From: Vadim Zhestikov Date: Thu, 2 Feb 2023 18:01:26 +0000 (-0800) Subject: Fixed RegExp.prototype[@@replace](). X-Git-Tag: 0.7.10~5 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=18ec98d63284a969a50048f62c7924b4a1d025a3;p=njs.git Fixed RegExp.prototype[@@replace](). Previously, when RegExpExec() returned a fast-array with gaps String.prototype.replace() might return erroneous exception TypeError: Cannot convert object to primitive value. --- diff --git a/src/njs_regexp.c b/src/njs_regexp.c index 4f7caad2..87e15139 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -1288,6 +1288,10 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, if (njs_fast_path(njs_is_fast_array(r) && njs_array_len(r) != 0)) { value = njs_array_start(r)[0]; + if (!njs_is_valid(&value)) { + njs_set_undefined(&value); + } + } else { ret = njs_value_property_i64(vm, r, 0, &value); if (njs_slow_path(ret == NJS_ERROR)) { diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 65b9928b..bff7ee3f 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -9063,8 +9063,19 @@ static njs_unit_test_t njs_test[] = "re.exec = function () {" " return a;" "};" - "var r = 'any_string'.replace(re);"), - njs_str("undefined") }, + "'any_string'.replace(re)"), + njs_str("undefinedg") }, + + { njs_str("var cnt = 0;" + "var a = [];" + "a[2] = '';" + "var re = /any_regexp/g;" + "re.exec = function () {" + " if (cnt++ > 1) return null;" + " return a;" + "};" + "'any_string'.replace(re)"), + njs_str("undefinedg") }, { njs_str("var a = [];" "a[2] = {toString() {a[2**20] = 1; return 'X';}}; " @@ -9077,14 +9088,37 @@ static njs_unit_test_t njs_test[] = "'abc'.replace(re, '@$1|$2|$3|$4|$99|$100|@')"), njs_str("@|X||Y|Z|0|@") }, + { njs_str("var cnt = 0;" + "var a = [];" + "a[2] = {toString() {a[2**20] = 1; return 'X';}}; " + "a[4] = 'Y';" + "a[99] = 'Z';" + "a[100] = '*';" + "a[200] = '!';" + "var re = /b/g;" + "re.exec = () => {if (cnt++ > 1) return null; return 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") }, + "'any_string'.replace(re)"), + njs_str("undefinedg") }, + + { njs_str("var cnt = 0;" + "var a = [];" + "Object.defineProperty(a, 32768, {});" + "var re = /any_regexp/g;" + "re.exec = function () {" + " if (cnt++ > 1) return null;" + " return a;" + "};" + "'any_string'.replace(re)"), + njs_str("undefinedg") }, { njs_str("/=/"), njs_str("/=/") },