[njs] Improved working with arguments in String.prototype.lastIndexOf().
Dmitry Volyntsev
xeioex at nginx.com
Tue May 14 16:34:19 UTC 2019
details: https://hg.nginx.org/njs/rev/1cce73676665
branches:
changeset: 962:1cce73676665
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue May 14 19:00:03 2019 +0300
description:
Improved working with arguments in String.prototype.lastIndexOf().
diffstat:
njs/njs_string.c | 128 +++++++++++++++++++++++++---------------------
njs/test/njs_unit_test.c | 18 ++++++
2 files changed, 87 insertions(+), 59 deletions(-)
diffs (196 lines):
diff -r 6babef232e87 -r 1cce73676665 njs/njs_string.c
--- a/njs/njs_string.c Mon May 13 20:28:40 2019 +0300
+++ b/njs/njs_string.c Tue May 14 19:00:03 2019 +0300
@@ -1796,80 +1796,90 @@ static njs_ret_t
njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused)
{
+ double pos;
ssize_t index, start, length, search_length;
const u_char *p, *end;
+ const njs_value_t *search_string;
njs_string_prop_t string, search;
index = -1;
- if (nargs > 1) {
- length = njs_string_prop(&string, &args[0]);
- search_length = njs_string_prop(&search, &args[1]);
-
- if (length < search_length) {
- goto done;
- }
-
+ length = njs_string_prop(&string, njs_arg(args, nargs, 0));
+
+ search_string = njs_arg(args, nargs, 1);
+
+ if (njs_is_undefined(search_string)) {
+ search_string = &njs_string_undefined;
+ }
+
+ search_length = njs_string_prop(&search, search_string);
+
+ if (length < search_length) {
+ goto done;
+ }
+
+ pos = njs_arg(args, nargs, 2)->data.u.number;
+
+ if (isnan(pos)) {
index = NJS_STRING_MAX_LENGTH;
- if (nargs > 2) {
- index = args[2].data.u.number;
-
- if (index < 0) {
- index = 0;
- }
+ } else {
+ index = njs_number_to_integer(pos);
+
+ if (index < 0) {
+ index = 0;
}
-
- if (index > length) {
- index = length;
+ }
+
+ if (index > length) {
+ index = length;
+ }
+
+ if (string.size == (size_t) length) {
+ /* Byte or ASCII string. */
+
+ start = length - search.size;
+
+ if (index > start) {
+ index = start;
}
- if (string.size == (size_t) length) {
- /* Byte or ASCII string. */
-
- start = length - search.size;
-
- if (index > start) {
- index = start;
+ p = string.start + index;
+
+ do {
+ if (memcmp(p, search.start, search.size) == 0) {
+ goto done;
}
- p = string.start + index;
-
- do {
- if (memcmp(p, search.start, search.size) == 0) {
- goto done;
- }
-
- index--;
- p--;
-
- } while (p >= string.start);
-
- } else {
- /* UTF-8 string. */
-
- end = string.start + string.size;
- p = njs_string_offset(string.start, end, index);
- end -= search.size;
-
- while (p > end) {
- index--;
- p = nxt_utf8_prev(p);
+ index--;
+ p--;
+
+ } while (p >= string.start);
+
+ } else {
+ /* UTF-8 string. */
+
+ end = string.start + string.size;
+ p = njs_string_offset(string.start, end, index);
+ end -= search.size;
+
+ while (p > end) {
+ index--;
+ p = nxt_utf8_prev(p);
+ }
+
+ for ( ;; ) {
+ if (memcmp(p, search.start, search.size) == 0) {
+ goto done;
}
- for ( ;; ) {
- if (memcmp(p, search.start, search.size) == 0) {
- goto done;
- }
-
- index--;
-
- if (p <= string.start) {
- break;
- }
-
- p = nxt_utf8_prev(p);
+ index--;
+
+ if (p <= string.start) {
+ break;
}
+
+ p = nxt_utf8_prev(p);
}
}
@@ -3912,7 +3922,7 @@ static const njs_object_prop_t njs_stri
.type = NJS_METHOD,
.name = njs_string("lastIndexOf"),
.value = njs_native_function(njs_string_prototype_last_index_of, 0,
- NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+ NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_NUMBER_ARG),
.configurable = 1,
},
diff -r 6babef232e87 -r 1cce73676665 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Mon May 13 20:28:40 2019 +0300
+++ b/njs/test/njs_unit_test.c Tue May 14 19:00:03 2019 +0300
@@ -5127,6 +5127,18 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("'abc abc абвгд abc'.lastIndexOf('абвгд')"),
nxt_string("8") },
+ { nxt_string("'abc abc абвгд abc'.lastIndexOf('абвгд', undefined)"),
+ nxt_string("8") },
+
+ { nxt_string("'abc abc абвгд abc'.lastIndexOf('абвгд', NaN)"),
+ nxt_string("8") },
+
+ { nxt_string("'abc abc абвгд abc'.lastIndexOf('абвгд', {})"),
+ nxt_string("8") },
+
+ { nxt_string("String.prototype.lastIndexOf.call({toString:()=>'abc abc абвгд abc'}, 'абвгд')"),
+ nxt_string("8") },
+
{ nxt_string("'abc abc абвгдежз'.lastIndexOf('абвгд')"),
nxt_string("8") },
@@ -5154,6 +5166,12 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("''.lastIndexOf('')"),
nxt_string("0") },
+ { nxt_string("''.lastIndexOf()"),
+ nxt_string("-1") },
+
+ { nxt_string("''.lastIndexOf(undefined)"),
+ nxt_string("-1") },
+
{ nxt_string("''.includes('')"),
nxt_string("true") },
More information about the nginx-devel
mailing list