From 9ab425eac2b6c7eb3a932c8e6934e9992435e328 Mon Sep 17 00:00:00 2001 From: Alexander Borisov Date: Tue, 6 Oct 2020 19:53:26 +0300 Subject: [PATCH] Fixed heap-use-after-free in JSON.parse(). MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This correctly fixes the issues addressed in 1405:9beb9ea093b5. The initial fix wrongly assumed that the "value" pointer is still valid when njs_is_fast_array(&state->value) is true and the pointer can be used for the fast path.  This is not the case when the array object is resized. Moreover, the fast path branch may be completely eliminated because JSON.parse() with the replacer function is relatively slow by itself. This closes #323, #324, #325 issues on GitHub. --- src/njs_json.c | 18 ------------------ src/test/njs_unit_test.c | 4 ++++ 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/njs_json.c b/src/njs_json.c index 80e10cf8..6bbf13b1 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -1018,24 +1018,6 @@ 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)) { ret = njs_value_property_i64_delete(vm, &state->value, state->index - 1, NULL); diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 661bf6a6..64c993cf 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -16437,6 +16437,10 @@ static njs_unit_test_t njs_test[] = " function(k, v) {return v.a.a;}); o"), njs_str("TypeError: cannot get property \"a\" of undefined") }, + { njs_str("function func() {this[8] = 1; return new Int8Array(func)}" + "JSON.parse('[1]', func);"), + njs_str("") }, + /* JSON.stringify() */ { njs_str("JSON.stringify()"), -- 2.47.3