From: Alexander Borisov Date: Tue, 14 May 2019 10:00:44 +0000 (+0300) Subject: Improved String.prototype.replace(). X-Git-Tag: 0.3.2~6 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=c34496c181469560390a2f5d2d96e07369e47117;p=njs.git Improved String.prototype.replace(). 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. --- diff --git a/njs/njs_string.c b/njs/njs_string.c index 2fa93f30..ae3f9718 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -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); } diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index b5743e02..8f1411a5 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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,,,") },