details: https://hg.nginx.org/njs/rev/b80c24512157 branches: changeset: 1988:b80c24512157 user: Vadim Zhestikov <v.zhesti...@f5.com> date: Mon Nov 07 14:08:28 2022 -0800 description: Fixed String.prototype.replace(re) if re.exec() returns non-flat array.
This fixes #587 issue on Github. diffstat: src/njs_regexp.c | 58 +++++++++++++++-------------------------------- src/test/njs_unit_test.c | 29 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 39 deletions(-) diffs (116 lines): diff -r 4f66a66ef300 -r b80c24512157 src/njs_regexp.c --- a/src/njs_regexp.c Wed Oct 26 16:33:15 2022 -0700 +++ b/src/njs_regexp.c Mon Nov 07 14:08:28 2022 -0800 @@ -1362,54 +1362,34 @@ njs_regexp_prototype_symbol_replace(njs_ 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 -r 4f66a66ef300 -r b80c24512157 src/test/njs_unit_test.c --- a/src/test/njs_unit_test.c Wed Oct 26 16:33:15 2022 -0700 +++ b/src/test/njs_unit_test.c Mon Nov 07 14:08:28 2022 -0800 @@ -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("/=/") }, _______________________________________________ nginx-devel mailing list -- nginx-devel@nginx.org To unsubscribe send an email to nginx-devel-le...@nginx.org