From: Dmitry Volyntsev Date: Thu, 2 Jul 2020 12:59:48 +0000 (+0000) Subject: Fixed String.prototype.repeat() according to the specification. X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=62b813cba513228a5ddd14432c5195e000c65403;p=njs.git Fixed String.prototype.repeat() according to the specification. --- diff --git a/src/njs_string.c b/src/njs_string.c index 5c2997be..371605c7 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -2772,47 +2772,61 @@ static njs_int_t njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { - u_char *p, *start; + u_char *p; + double count; int64_t n, max; uint64_t size, length; njs_int_t ret; + njs_value_t *this; njs_string_prop_t string; - ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0)); + this = njs_argument(args, 0); + + if (njs_slow_path(njs_is_null_or_undefined(this))) { + njs_type_error(vm, "cannot convert \"%s\"to object", + njs_type_string(this->type)); + return NJS_ERROR; + } + + ret = njs_value_to_string(vm, this, this); if (njs_slow_path(ret != NJS_OK)) { return ret; } - ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &n); + ret = njs_value_to_number(vm, njs_arg(args, nargs, 1), &count); if (njs_slow_path(ret != NJS_OK)) { return ret; } - (void) njs_string_prop(&string, njs_argument(args, 0)); - - max = (string.size > 1) ? NJS_STRING_MAX_LENGTH / string.size - : NJS_STRING_MAX_LENGTH; - - if (njs_slow_path(n < 0 || n >= max)) { + if (njs_slow_path(!isnan(count) && (count < 0 || isinf(count)))) { njs_range_error(vm, NULL); return NJS_ERROR; } - if (string.size == 0) { + n = njs_number_to_integer(count); + + (void) njs_string_prop(&string, this); + + if (njs_slow_path(n == 0 || string.size == 0)) { vm->retval = njs_string_empty; return NJS_OK; } + max = NJS_STRING_MAX_LENGTH / string.size; + + if (njs_slow_path(n >= max)) { + njs_range_error(vm, NULL); + return NJS_ERROR; + } + size = string.size * n; length = string.length * n; - start = njs_string_alloc(vm, &vm->retval, size, length); - if (njs_slow_path(start == NULL)) { + p = njs_string_alloc(vm, &vm->retval, size, length); + if (njs_slow_path(p == NULL)) { return NJS_ERROR; } - p = start; - while (n != 0) { p = memcpy(p, string.start, string.size); p += string.size; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 56c7c5f3..2f087b8d 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -7892,12 +7892,11 @@ static njs_unit_test_t njs_test[] = { njs_str("''.repeat(2147483646)"), njs_str("") }, - /* ES6: "". */ { njs_str("''.repeat(2147483647)"), - njs_str("RangeError") }, + njs_str("") }, { njs_str("''.repeat(2147483648)"), - njs_str("RangeError") }, + njs_str("") }, { njs_str("''.repeat(Infinity)"), njs_str("RangeError") }, @@ -7905,6 +7904,9 @@ static njs_unit_test_t njs_test[] = { njs_str("''.repeat(NaN)"), njs_str("") }, + { njs_str("String.prototype.repeat.call({},2)"), + njs_str("[object Object][object Object]") }, + { njs_str("'abc'.padStart(7)"), njs_str(" abc") },