From: Dmitry Volyntsev Date: Tue, 7 Jul 2020 12:23:45 +0000 (+0000) Subject: Fixed GetSubstitution() with absent namedCaptures. X-Git-Tag: 0.4.2~3 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=23cef9ab7bc9badef6e5d8444dd456534eb396ee;p=njs.git Fixed GetSubstitution() with absent namedCaptures. This issue was introduced in 1c729f765cfb. Found by Clang static analyzer. --- diff --git a/src/njs_string.c b/src/njs_string.c index 482bfb4e..260c9b02 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -3414,7 +3414,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, case '<': r = njs_strlchr(p, end, '>'); - if (r == NULL) { + if (groups == NULL || njs_is_undefined(groups) || r == NULL) { njs_chb_append(&chain, p, 2); p += 2; break; @@ -3422,10 +3422,6 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, p += 2; - if (groups == NULL) { - break; - } - ret = njs_vm_value_string_set(vm, &name, p, r - p); if (njs_slow_path(ret != NJS_OK)) { goto exception; @@ -3512,7 +3508,7 @@ exception: njs_chb_destroy(&chain); - return NJS_OK; + return ret; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 54518871..fe8ebd6b 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -7502,6 +7502,12 @@ static njs_unit_test_t njs_test[] = { njs_str("'abcdbe'.replace('b', '|$`X$\\'|')"), njs_str("a|aXcdbe|cdbe") }, + { njs_str("'ABC'.replace('B', '$')"), + njs_str("A$C") }, + + { njs_str("'ABC'.replace('B', '$23')"), + njs_str("A$23C") }, + { njs_str("'undefined'.replace(void 0, 'x')"), njs_str("x") }, @@ -7669,6 +7675,9 @@ static njs_unit_test_t njs_test[] = "uri.replace(/^\\/u\\/v1\\/[^/]*\\/([^\?]*)\\?.*(mt=[^&]*).*$/, '$1|$2')"), njs_str("bB|mt=42") }, + { njs_str("'ABC'.replace(/B/, '$')"), + njs_str("A$C") }, + { njs_str("'ABC'.replace(/(?B)/, '|$|@$@')"), njs_str("A|B|@@C") }, @@ -7693,12 +7702,29 @@ static njs_unit_test_t njs_test[] = njs_str("A|+|C") }, { njs_str("var O = RegExp.prototype.exec;" - "function mangled(s) { var r = O.call(this, s); Object.defineProperty(r, '0', {enumerable:false}); " + "function mangled(s) { var r = O.call(this, s);" + " Object.defineProperty(r, '0', {enumerable:false}); " " return r; };" "RegExp.prototype.exec = mangled;" "'ABC'.replace(/(B)/, (m, p1, off, s) => `@${m}|${p1}|${off}|${s}@`)"), njs_str("A@B|B|1|ABC@C") }, + { njs_str("var O = RegExp.prototype.exec;" + "function mangled(s) { var r = O.call(this, s);" + " Object.defineProperty(r, 'groups', {value: {g:1}}); " + " return r; };" + "RegExp.prototype.exec = mangled;" + "'ABC'.replace(/(B)/, '$')"), + njs_str("A1C") }, + + { njs_str("var O = RegExp.prototype.exec;" + "function mangled(s) { var r = O.call(this, s);" + " Object.defineProperty(r, 'groups', {value: {get g() {throw 'OOps'}}}); " + " return r; };" + "RegExp.prototype.exec = mangled;" + "'ABC'.replace(/(B)/, '$')"), + njs_str("OOps") }, + { njs_str("RegExp.prototype[Symbol.replace].call()"), njs_str("TypeError: \"this\" is not object") },