]> git.kaiwu.me - njs.git/commitdiff
Fixed String.prototype.replace() when function returns non-string.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 14 Apr 2020 12:43:09 +0000 (12:43 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 14 Apr 2020 12:43:09 +0000 (12:43 +0000)
This closes #303 issue on Github.

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

index 9bc2990e2a3239c71de5360c0a2453805412b258..7e431a2d648590f62d23e9ac0d97fd199d295981 100644 (file)
@@ -3718,33 +3718,34 @@ njs_string_replace_regexp_function(njs_vm_t *vm, njs_value_t *this,
     r->part[0].size = captures[0];
 
     ret = njs_function_apply(vm, r->function, arguments, n + 3, &r->retval);
-
     if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+        goto exception;
     }
 
-    (void) njs_string_prop(&string, this);
-
-    if (njs_is_string(&r->retval)) {
-        njs_string_replacement_copy(&r->part[r->empty ? 0 : 1], &r->retval);
+    if (njs_slow_path(!njs_is_string(&r->retval))) {
+        ret = njs_value_to_string(vm, &r->retval, &r->retval);
+        if (njs_slow_path(ret != NJS_OK)) {
+            goto exception;
+        }
+    }
 
-        if (njs_regexp_pattern(regex)->global) {
-            r->part += 2;
+    njs_string_replacement_copy(&r->part[r->empty ? 0 : 1], &r->retval);
 
-            if (r->part[0].start > (string.start + string.size)) {
-                return njs_string_replace_regexp_join(vm, r);
-            }
+    if (njs_regexp_pattern(regex)->global) {
+        r->part += 2;
 
-            return njs_string_replace_regexp(vm, this, regex, r);
+        if (r->part[0].start > (string.start + string.size)) {
+            return njs_string_replace_regexp_join(vm, r);
         }
 
-        return njs_string_replace_regexp_join(vm, r);
+        return njs_string_replace_regexp(vm, this, regex, r);
     }
 
-    njs_regex_match_data_free(r->match_data, vm->regex_context);
+    return njs_string_replace_regexp_join(vm, r);
 
-    njs_internal_error(vm, "unexpected retval type:%s",
-                       njs_type_string(r->retval.type));
+exception:
+
+    njs_regex_match_data_free(r->match_data, vm->regex_context);
 
     return NJS_ERROR;
 }
index 48d7ed6081b13ef2315175398d22b68d00161ee4..3642c6fc83e622e371ebd8f3403f0d077780caed 100644 (file)
@@ -7231,6 +7231,12 @@ static njs_unit_test_t  njs_test[] =
                        "{ return '|'+s+'|'+o+'|'+m+'|'+p+'|' })"),
       njs_str("abc|abcdefghdijklm|3|d|d|efghdijklm") },
 
+    { njs_str("'abc'.replace(/b/, ()=>1)"),
+      njs_str("a1c") },
+
+    { njs_str("var n = 0; 'abbbc'.replace(/b/g, function() {return ++n;})"),
+      njs_str("a123c") },
+
     { njs_str("'abcdefghdijklm'.replace(/x/, 'X')"),
       njs_str("abcdefghdijklm") },