]> git.kaiwu.me - njs.git/commitdiff
Improved String.prototype.replace().
authorAlexander Borisov <alexander.borisov@nginx.com>
Tue, 14 May 2019 10:00:44 +0000 (13:00 +0300)
committerAlexander Borisov <alexander.borisov@nginx.com>
Tue, 14 May 2019 10:00:44 +0000 (13:00 +0300)
If replace value is a function and the function return non string
value, then convert returned value to string.

This closes #61 issue on GitHub.

njs/njs_string.c
njs/test/njs_unit_test.c

index 2fa93f3005ca655676ba2ab2f7ef53448f699174..ae3f97187612bdc0504099376d5990a4c0f54431 100644 (file)
@@ -3355,20 +3355,28 @@ static njs_ret_t
 njs_string_replace_search_continuation(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused)
 {
+    njs_ret_t             ret;
+    njs_value_t           string;
     njs_string_replace_t  *r;
 
     r = njs_vm_continuation(vm);
 
-    if (njs_is_string(&r->retval)) {
-        njs_string_replacement_copy(&r->part[1], &r->retval);
-
-        return njs_string_replace_join(vm, r);
+    if (!njs_is_primitive(&r->retval)) {
+        njs_vm_trap_value(vm, &r->retval);
+        return njs_trap(vm, NJS_TRAP_STRING_ARG);
     }
 
-    njs_internal_error(vm, "unexpected continuation retval type:%s",
+    ret = njs_primitive_value_to_string(vm, &string, &r->retval);
+    if (nxt_slow_path(ret != NJS_OK)) {
+        njs_type_error(vm, "cannot convert primitive value to string: %s",
                        njs_type_string(r->retval.type));
 
-    return NXT_ERROR;
+        return NXT_ERROR;
+    }
+
+    njs_string_replacement_copy(&r->part[1], &string);
+
+    return njs_string_replace_join(vm, r);
 }
 
 
index b5743e02fa0fcb27ce1b633fa5bbd02cc5dee6cb..8f1411a5a59acc5d93f1f7c024501816a0509a62 100644 (file)
@@ -5484,6 +5484,15 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("''.replace(/a*/g, '')"),
       nxt_string("") },
 
+    { nxt_string("'12345'.replace(3, () => 0)"),
+      nxt_string("12045") },
+
+    { nxt_string("'123'.replace(3, function() { return {toString: ()=>({})}; })"),
+      nxt_string("TypeError: Cannot convert object to primitive value") },
+
+    { nxt_string("'12345'.replace(3, () => ({toString: () => 'aaaa'}))"),
+      nxt_string("12aaaa45") },
+
     { nxt_string("'abc'.match(/a*/g)"),
       nxt_string("a,,,") },