From: Vadim Zhestikov Date: Mon, 7 Nov 2022 22:08:28 +0000 (-0800) Subject: Fixed String.prototype.replace(re) if re.exec() returns non-flat array. X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=ba0f3c4d1270d27abb17a3d885a9c10373528e98;p=njs.git Fixed String.prototype.replace(re) if re.exec() returns non-flat array. This fixes #587 issue on Github. --- diff --git a/src/njs_regexp.c b/src/njs_regexp.c index 3f82b4c3..eaff427a 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -1362,54 +1362,34 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, pos = njs_max(njs_min(pos, (int64_t) s.size), 0); - if (njs_fast_path(njs_is_fast_array(r) && njs_array_len(r) != 0)) { - array = njs_array(r); + ret = njs_object_length(vm, r, &ncaptures); + if (njs_slow_path(ret != NJS_OK)) { + goto exception; + } - arguments = array->start; - arguments[0] = matched; - ncaptures = njs_max((int64_t) array->length - 1, 0); + ncaptures = njs_min(njs_max(ncaptures - 1, 0), 99); - for (n = 1; n <= ncaptures; n++) { - if (njs_is_undefined(&arguments[n])) { - continue; - } + array = njs_array_alloc(vm, 1, ncaptures + 1, 0); + if (njs_slow_path(array == NULL)) { + goto exception; + } - ret = njs_value_to_string(vm, &arguments[n], &arguments[n]); - if (njs_slow_path(ret == NJS_ERROR)) { - goto exception; - } - } + arguments = array->start; + arguments[0] = matched; - } else { - ret = njs_object_length(vm, r, &ncaptures); - if (njs_slow_path(ret != NJS_OK)) { + for (n = 1; n <= ncaptures; n++) { + ret = njs_value_property_i64(vm, r, n, &arguments[n]); + if (njs_slow_path(ret == NJS_ERROR)) { goto exception; } - ncaptures = njs_max(ncaptures - 1, 0); - - array = njs_array_alloc(vm, 0, ncaptures + 1, 0); - if (njs_slow_path(array == NULL)) { - goto exception; + if (njs_is_undefined(&arguments[n])) { + continue; } - arguments = array->start; - arguments[0] = matched; - - for (n = 1; n <= ncaptures; n++) { - ret = njs_value_property_i64(vm, r, n, &arguments[n]); - if (njs_slow_path(ret == NJS_ERROR)) { - goto exception; - } - - if (njs_is_undefined(&arguments[n])) { - continue; - } - - ret = njs_value_to_string(vm, &arguments[n], &arguments[n]); - if (njs_slow_path(ret == NJS_ERROR)) { - goto exception; - } + ret = njs_value_to_string(vm, &arguments[n], &arguments[n]); + if (njs_slow_path(ret == NJS_ERROR)) { + goto exception; } } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index b5fc0616..43c2676b 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -8937,6 +8937,35 @@ static njs_unit_test_t njs_test[] = { njs_str("String.bytesFrom([255,149,15,97,95]).replace(/_/g, 'X')[4]"), njs_str("X") }, + { njs_str("var a = [];" + "a[2] = '';" + "var re = /any_regexp/;" + "re.exec = function () {" + " return a;" + "};" + "var r = 'any_string'.replace(re);"), + njs_str("undefined") }, + + { njs_str("var a = [];" + "a[2] = {toString() {a[2**20] = 1; return 'X';}}; " + "a[4] = 'Y';" + "a[99] = 'Z';" + "a[100] = '*';" + "a[200] = '!';" + "var re = /b/;" + "re.exec = () => a;" + "'abc'.replace(re, '@$1|$2|$3|$4|$99|$100|@')"), + njs_str("@|X||Y|Z|0|@") }, + + { njs_str("var a = [];" + "Object.defineProperty(a, 32768, {});" + "var re = /any_regexp/;" + "re.exec = function () {" + " return a;" + "};" + "var r = 'any_string'.replace(re);"), + njs_str("undefined") }, + { njs_str("/=/"), njs_str("/=/") },