apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minf...@apache.org
Subject svn commit: r1835361 - in /apr/apr-util/branches/1.7.x: json/apr_json_decode.c test/testjson.c
Date Sun, 08 Jul 2018 15:15:40 GMT
Author: minfrin
Date: Sun Jul  8 15:15:40 2018
New Revision: 1835361

URL: http://svn.apache.org/viewvc?rev=1835361&view=rev
Log:
Backport 1835360.

Fix the string unescape logic for multiple escaped characters. Add
a unit test.

Modified:
    apr/apr-util/branches/1.7.x/json/apr_json_decode.c
    apr/apr-util/branches/1.7.x/test/testjson.c

Modified: apr/apr-util/branches/1.7.x/json/apr_json_decode.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/json/apr_json_decode.c?rev=1835361&r1=1835360&r2=1835361&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/json/apr_json_decode.c (original)
+++ apr/apr-util/branches/1.7.x/json/apr_json_decode.c Sun Jul  8 15:15:40 2018
@@ -83,6 +83,7 @@ static apr_status_t apr_json_decode_stri
     const char *p = self->p;
     const char *e;
     char *q;
+    apr_size_t len;
 
     if (self->p >= self->e) {
         status = APR_EOF;
@@ -92,7 +93,7 @@ static apr_status_t apr_json_decode_stri
     self->p++; /* eat the leading '"' */
 
     /* advance past the \ " */
-    string.len = 0;
+    len = 0;
     for (p = self->p, e = self->e; p < e;) {
         if (*p == '"')
             break;
@@ -108,21 +109,20 @@ static apr_status_t apr_json_decode_stri
                     goto out;
                 }
                 p += 5;
-                string.len += 4;/* an UTF-8 character spans at most 4 bytes */
-                break;
+                len += 4;/* an UTF-8 character spans at most 4 bytes */
             }
             else {
-                string.len++;
+                len++;
                 p++;
             }
         }
         else {
-            string.len++;
+            len++;
             p++;
         }
     }
 
-    string.p = q = apr_pcalloc(self->pool, string.len + 1);
+    string.p = q = apr_pcalloc(self->pool, len + 1);
     e = p;
 
 #define VALIDATE_UTF8_SUCCEEDING_BYTE(p) \
@@ -139,15 +139,14 @@ static apr_status_t apr_json_decode_stri
             case 'u':
                 /* THIS IS REQUIRED TO BE A 4 DIGIT HEX NUMBER */
                 {
-                    int cp = 0;
-                    while (p < e) {
-                        int d = hex_to_int(*p);
+                    int i, d, cp = 0;
+                    for (i = 0, p++; i < 4 && p < e; i++, p++) {
+                        d = hex_to_int(*p);
                         if (d < 0) {
                             status = APR_BADCH;
                             goto out;
                         }
                         cp = (cp << 4) | d;
-                        p++;
                     }
                     if (cp >= 0xd800 && cp < 0xdc00) {
                         /* surrogate pair */
@@ -160,14 +159,13 @@ static apr_status_t apr_json_decode_stri
                             status = APR_BADCH;
                             goto out;
                         }
-                        while (p < e) {
-                            int d = hex_to_int(*p);
+                        for (i = 0, p += 2; i < 4 && p < e; i++, p++) {
+                            d = hex_to_int(*p);
                             if (d < 0) {
                                 status = APR_BADCH;
                                 goto out;
                             }
                             sc = (sc << 4) | d;
-                            p++;
                         }
                         cp = ((cp & 0x3ff) << 10) | (sc & 0x3ff);
                         if ((cp >= 0xd800 && cp < 0xe000) || (cp >= 0x110000))
{
@@ -340,6 +338,8 @@ static apr_status_t apr_json_decode_stri
     }
 #undef VALIDATE_UTF8_SUCCEEDING_BYTE
     p++; /* eat the trailing '"' */
+    *q = 0;
+    string.len = q - string.p;
     *retval = string;
 out:
     self->p = p;

Modified: apr/apr-util/branches/1.7.x/test/testjson.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/test/testjson.c?rev=1835361&r1=1835360&r2=1835361&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/test/testjson.c (original)
+++ apr/apr-util/branches/1.7.x/test/testjson.c Sun Jul  8 15:15:40 2018
@@ -127,6 +127,28 @@ static void test_json_eof(abts_case * tc
 
 }
 
+static void test_json_string(abts_case * tc, void *data)
+{
+    apr_json_value_t *json = NULL;
+    apr_status_t status;
+    const char *src;
+    apr_off_t offset = 0;
+
+    /* "턞\"\t/\b\f\n\r\t"; */
+	const unsigned char expected[] = {237, 132, 158, 34, 9, 47, 8, 12, 10, 13, 9, 0};
+
+    src = "\"\\uD834\\uDD1E\\\"\\t\\/\\b\\f\\n\\r\\t\"";
+
+    status = apr_json_decode(&json, src, APR_JSON_VALUE_STRING, &offset,
+            APR_JSON_FLAGS_WHITESPACE, 10, p);
+
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, status);
+    ABTS_INT_EQUAL(tc, APR_JSON_STRING, json->type);
+
+	ABTS_ASSERT(tc, "check for string unescape match",
+			(memcmp(expected, json->value.string.p, json->value.string.len) == 0));
+}
+
 abts_suite *testjson(abts_suite * suite)
 {
     suite = ADD_SUITE(suite);
@@ -134,6 +156,7 @@ abts_suite *testjson(abts_suite * suite)
     abts_run_test(suite, test_json_identity, NULL);
     abts_run_test(suite, test_json_level, NULL);
     abts_run_test(suite, test_json_eof, NULL);
+    abts_run_test(suite, test_json_string, NULL);
 
     return suite;
 }



Mime
View raw message