]> git.kaiwu.me - njs.git/commitdiff
Fixed heap-use-after-free in JSON.parse() function.
authorAlexander Borisov <alexander.borisov@nginx.com>
Wed, 27 May 2020 15:18:40 +0000 (18:18 +0300)
committerAlexander Borisov <alexander.borisov@nginx.com>
Wed, 27 May 2020 15:18:40 +0000 (18:18 +0300)
src/njs_json.c
src/test/njs_unit_test.c

index 9a00ede35298be587c9b74d346424cdac15c4be5..26d4aa077d0f3fc5f5b111b102bf7b1bf346e547 100644 (file)
@@ -1018,11 +1018,31 @@ njs_json_parse_iterator_call(njs_vm_t *vm, njs_json_parse_t *parse,
             return ret;
         }
 
+        /*
+         * The njs_function_apply() function can convert fast array to object.
+         * After this conversion, there will be garbage in the value.
+         */
+
+        if (njs_fast_path(njs_is_fast_array(&state->value)
+            && (state->index - 1) < njs_array(&state->value)->length))
+        {
+            if (njs_is_undefined(&parse->retval)) {
+                njs_set_invalid(value);
+
+            } else {
+                *value = parse->retval;
+            }
+
+            break;
+        }
+
         if (njs_is_undefined(&parse->retval)) {
-            njs_set_invalid(value);
+            njs_value_property_i64_delete(vm, &state->value, state->index - 1,
+                                          NULL);
 
         } else {
-            *value = parse->retval;
+            njs_value_property_i64_set(vm, &state->value, state->index - 1,
+                                       &parse->retval);
         }
 
         break;
index ae97bb4fff146aa1738035ea9100712ccbaa6d7a..1e6be077851d69ebb65feb6f55a60be808f12589 100644 (file)
@@ -15309,6 +15309,23 @@ static njs_unit_test_t  njs_test[] =
                  "args.join('|')"),
       njs_str("0:2|a:3|1:[object Object]|:2,[object Object]") },
 
+    { njs_str("JSON.parse('[0,1,2]', function(k, v) {"
+              "    if (v == 2) {"
+              "        return undefined;"
+              "    }"
+              "    return v;"
+              "});"),
+      njs_str("0,1,") },
+
+    { njs_str("JSON.parse('[0,1,2]', function(k, v) {"
+              "    if (v == 0) {"
+              "        Object.defineProperty(this, '0', {value: undefined, enumerable: false});"
+              "        return undefined;"
+              "    }"
+              "    return v;"
+              "});"),
+      njs_str(",1,2") },
+
     { njs_str("JSON.parse()"),
       njs_str("SyntaxError: Unexpected token at position 0") },