details: http://hg.nginx.org/njs/rev/938d49b0f420 branches: changeset: 202:938d49b0f420 user: Igor Sysoev <i...@sysoev.ru> date: Mon Oct 17 16:42:31 2016 +0300 description: Fixes in various String methods which return part of string.
diffstat: njs/njs_array.c | 3 + njs/njs_string.c | 164 ++++++++++++++++++++++++++-------------------- njs/njs_vm.c | 16 ++-- njs/test/njs_unit_test.c | 15 ++++ 4 files changed, 118 insertions(+), 80 deletions(-) diffs (296 lines): diff -r c583e4985a7b -r 938d49b0f420 njs/njs_array.c --- a/njs/njs_array.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/njs_array.c Mon Oct 17 16:42:31 2016 +0300 @@ -409,6 +409,9 @@ njs_array_prototype_slice(njs_vm_t *vm, start = 0; length = 0; } + + } else { + length -= start; } } } diff -r c583e4985a7b -r 938d49b0f420 njs/njs_string.c --- a/njs/njs_string.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/njs_string.c Mon Oct 17 16:42:31 2016 +0300 @@ -886,21 +886,29 @@ njs_string_prototype_substring(njs_vm_t if (start < 0) { start = 0; + + } else if (start > length) { + start = length; } + end = length; + if (nargs > 2) { end = args[2].data.u.number; if (end < 0) { end = 0; + + } else if (end >= length) { + end = length; } - - length = end - start; - - if (length < 0) { - length = -length; - start = end; - } + } + + length = end - start; + + if (length < 0) { + length = -length; + start = end; } } @@ -920,7 +928,7 @@ static njs_ret_t njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - ssize_t start, length; + ssize_t start, length, n; njs_slice_prop_t slice; njs_string_prop_t string; @@ -931,17 +939,32 @@ njs_string_prototype_substr(njs_vm_t *vm if (nargs > 1) { start = args[1].data.u.number; - - if (start < 0) { - - start += length; + if (start < length) { + if (start < 0) { - start = 0; + start += length; + + if (start < 0) { + start = 0; + } } - } - - if (nargs > 2) { - length = args[2].data.u.number; + + length -= start; + + if (nargs > 2) { + n = args[2].data.u.number; + + if (n < 0) { + length = 0; + + } else if (n < length) { + length = n; + } + } + + } else { + start = 0; + length = 0; } } @@ -968,7 +991,8 @@ njs_string_prototype_char_at(njs_vm_t *v if (nargs > 1) { start = args[1].data.u.number; - if (start < 0) { + if (start < 0 || start >= (ssize_t) slice.string_length) { + start = 0; length = 0; } } @@ -1010,21 +1034,32 @@ njs_string_slice_args(njs_slice_prop_t * } } - end = length; - - if (nargs > 2) { - end = args[2].data.u.number; - - if (end < 0) { - end += length; - } - } - - length = end - start; - - if (length < 0) { + if (start >= length) { start = 0; length = 0; + + } else { + end = length; + + if (nargs > 2) { + end = args[2].data.u.number; + + if (end < 0) { + end += length; + } + } + + if (length >= end) { + length = end - start; + + if (length < 0) { + start = 0; + length = 0; + } + + } else { + length -= start; + } } } @@ -1038,51 +1073,36 @@ njs_string_slice(njs_vm_t *vm, njs_value const njs_string_prop_t *string, njs_slice_prop_t *slice) { size_t size, n, length; - ssize_t excess; const u_char *p, *start, *end; length = slice->length; - - if (length > 0 && slice->start < slice->string_length) { - - start = string->start; + start = string->start; + + if (string->size == slice->string_length) { + /* Byte or ASCII string. */ + start += slice->start; + size = slice->length; + + } else { + /* UTF-8 string. */ end = start + string->size; - - if (string->size == slice->string_length) { - /* Byte or ASCII string. */ - start += slice->start; - - excess = (start + length) - end; - if (excess > 0) { - length -= excess; - } - - size = length; - - if (string->length == 0) { - length = 0; - } - - } else { - /* UTF-8 string. */ - start = njs_string_offset(start, end, slice->start); - - /* Evaluate size of the slice in bytes and ajdust length. */ - p = start; - n = length; - - do { - p = nxt_utf8_next(p, end); - n--; - } while (n != 0 && p < end); - - size = p - start; - length -= n; - } - - if (nxt_fast_path(size != 0)) { - return njs_string_new(vm, &vm->retval, start, size, length); - } + start = njs_string_offset(start, end, slice->start); + + /* Evaluate size of the slice in bytes and ajdust length. */ + p = start; + n = length; + + do { + p = nxt_utf8_next(p, end); + n--; + } while (n != 0 && p < end); + + size = p - start; + length -= n; + } + + if (nxt_fast_path(size != 0)) { + return njs_string_new(vm, &vm->retval, start, size, length); } vm->retval = njs_string_empty; diff -r c583e4985a7b -r 938d49b0f420 njs/njs_vm.c --- a/njs/njs_vm.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/njs_vm.c Mon Oct 17 16:42:31 2016 +0300 @@ -559,14 +559,14 @@ njs_vmcode_property_get(njs_vm_t *vm, nj slice.start = index; slice.length = 1; slice.string_length = njs_string_prop(&string, object); - /* - * A single codepoint string fits in vm->retval - * so the function cannot fail. - */ - (void) njs_string_slice(vm, &vm->retval, &string, &slice); - - if (nxt_fast_path(vm->retval.data.truth != 0)) { - /* Non-empty string. */ + + if (slice.start < slice.string_length) { + /* + * A single codepoint string fits in vm->retval + * so the function cannot fail. + */ + (void) njs_string_slice(vm, &vm->retval, &string, &slice); + return sizeof(njs_vmcode_prop_get_t); } } diff -r c583e4985a7b -r 938d49b0f420 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 17 16:42:31 2016 +0300 @@ -2857,6 +2857,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abcdefgh'.slice(3)"), nxt_string("defgh") }, + { nxt_string("'abcde'.slice(50)"), + nxt_string("") }, + + { nxt_string("'abcde'.slice(1, 50)"), + nxt_string("bcde") }, + { nxt_string("'abcdefgh'.slice(3, -2)"), nxt_string("def") }, @@ -2866,6 +2872,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abcdefgh'.slice(100, 120)"), nxt_string("") }, + { nxt_string("String.prototype.substring(1, 5)"), + nxt_string("") }, + + { nxt_string("String.prototype.slice(1, 5)"), + nxt_string("") }, + + { nxt_string("String.prototype.toBytes(1, 5)"), + nxt_string("") }, + { nxt_string("'abc'.charAt(1 + 1)"), nxt_string("c") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel