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;
+ length = end - start;
- if (length < 0) {
- length = -length;
- start = end;
- }
+ if (length < 0) {
+ length = -length;
+ start = end;
}
}
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;
if (nargs > 1) {
start = args[1].data.u.number;
+ if (start < length) {
- if (start < 0) {
-
- 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;
}
}
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;
}
}
}
}
- end = length;
+ if (start >= length) {
+ start = 0;
+ length = 0;
- if (nargs > 2) {
- end = args[2].data.u.number;
+ } else {
+ end = length;
- if (end < 0) {
- end += length;
+ if (nargs > 2) {
+ end = args[2].data.u.number;
+
+ if (end < 0) {
+ end += length;
+ }
}
- }
- length = end - start;
+ if (length >= end) {
+ length = end - start;
- if (length < 0) {
- start = 0;
- length = 0;
+ if (length < 0) {
+ start = 0;
+ length = 0;
+ }
+
+ } else {
+ length -= start;
+ }
}
}
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;
+ start = string->start;
- if (length > 0 && slice->start < slice->string_length) {
+ if (string->size == slice->string_length) {
+ /* Byte or ASCII string. */
+ start += slice->start;
+ size = slice->length;
- start = string->start;
+ } else {
+ /* UTF-8 string. */
end = start + string->size;
+ start = njs_string_offset(start, end, slice->start);
- if (string->size == slice->string_length) {
- /* Byte or ASCII string. */
- start += slice->start;
-
- excess = (start + length) - end;
- if (excess > 0) {
- length -= excess;
- }
-
- size = length;
+ /* Evaluate size of the slice in bytes and ajdust length. */
+ p = start;
+ n = length;
- if (string->length == 0) {
- length = 0;
- }
-
- } else {
- /* UTF-8 string. */
- start = njs_string_offset(start, end, slice->start);
+ do {
+ p = nxt_utf8_next(p, end);
+ n--;
+ } while (n != 0 && p < end);
- /* 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;
- }
+ size = p - start;
+ length -= n;
+ }
- if (nxt_fast_path(size != 0)) {
- return njs_string_new(vm, &vm->retval, start, size, length);
- }
+ if (nxt_fast_path(size != 0)) {
+ return njs_string_new(vm, &vm->retval, start, size, length);
}
vm->retval = njs_string_empty;
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);
}
}
{ 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") },
{ 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") },