[njs] Fixed String.prototype.repeat() according to the specification.
Dmitry Volyntsev
xeioex at nginx.com
Thu Jul 2 14:01:37 UTC 2020
details: https://hg.nginx.org/njs/rev/27b88bd86e61
branches:
changeset: 1445:27b88bd86e61
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Jul 02 12:59:48 2020 +0000
description:
Fixed String.prototype.repeat() according to the specification.
diffstat:
src/njs_string.c | 42 ++++++++++++++++++++++++++++--------------
src/test/njs_unit_test.c | 8 +++++---
2 files changed, 33 insertions(+), 17 deletions(-)
diffs (107 lines):
diff -r 6345c07f1c52 -r 27b88bd86e61 src/njs_string.c
--- a/src/njs_string.c Thu Jul 02 12:58:50 2020 +0000
+++ b/src/njs_string.c Thu Jul 02 12:59:48 2020 +0000
@@ -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 -r 6345c07f1c52 -r 27b88bd86e61 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Thu Jul 02 12:58:50 2020 +0000
+++ b/src/test/njs_unit_test.c Thu Jul 02 12:59:48 2020 +0000
@@ -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") },
More information about the nginx-devel
mailing list