]> git.kaiwu.me - njs.git/commitdiff
Fixed GetSubstitution() with absent namedCaptures.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 7 Jul 2020 12:23:45 +0000 (12:23 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 7 Jul 2020 12:23:45 +0000 (12:23 +0000)
This issue was introduced in 1c729f765cfb.
Found by Clang static analyzer.

src/njs_string.c
src/test/njs_unit_test.c

index 482bfb4e12336bbb85f819d37641adf64d8f3df3..260c9b02a66fa20052d242993cc2a45769b5110b 100644 (file)
@@ -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;
 }
 
 
index 545188712daf4de9603e533bee2d9a3570a023de..fe8ebd6b14119c0a84e0e12ebf519169c4294804 100644 (file)
@@ -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', '$<g>')"),
+      njs_str("A$<g>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/, '$<g>')"),
+      njs_str("A$<g>C") },
+
     { njs_str("'ABC'.replace(/(?<b>B)/, '|$<b>|@$<a>@')"),
       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)/, '$<g>')"),
+      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)/, '$<g>')"),
+      njs_str("OOps") },
+
     { njs_str("RegExp.prototype[Symbol.replace].call()"),
       njs_str("TypeError: \"this\" is not object") },