From: Alexander Borisov Date: Wed, 27 May 2020 15:18:40 +0000 (+0300) Subject: Fixed heap-use-after-free in JSON.parse() function. X-Git-Tag: 0.4.2~53 X-Git-Url: http://git.kaiwu.me/sitemap.xml?a=commitdiff_plain;h=d41e2fbbc29cf2b962cc80dd7215f153356eb6ed;p=njs.git Fixed heap-use-after-free in JSON.parse() function. --- diff --git a/src/njs_json.c b/src/njs_json.c index 9a00ede3..26d4aa07 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -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; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index ae97bb4f..1e6be077 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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") },