details: http://hg.nginx.org/njs/rev/73dc069a08c0 branches: changeset: 116:73dc069a08c0 user: Igor Sysoev <i...@sysoev.ru> date: Thu Jul 07 20:49:57 2016 +0300 description: Byte string processing was fixed in String.split(), the issue has been found by Coverity Scan.
diffstat: njs/njs_string.c | 69 ++++++++++++++++++++++++++++++++++++++--------- njs/test/njs_unit_test.c | 3 ++ 2 files changed, 59 insertions(+), 13 deletions(-) diffs (139 lines): diff -r ef2b708510b1 -r 73dc069a08c0 njs/njs_string.c --- a/njs/njs_string.c Wed Jun 29 13:38:20 2016 +0300 +++ b/njs/njs_string.c Thu Jul 07 20:49:57 2016 +0300 @@ -40,6 +40,8 @@ static njs_ret_t njs_string_prototype_fr njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static nxt_noinline ssize_t njs_string_index_of(njs_vm_t *vm, njs_value_t *src, njs_value_t *search_string, size_t index); +static njs_ret_t njs_string_split_part_add(njs_vm_t *vm, njs_array_t *array, + u_char *start, size_t size, nxt_uint_t utf8); njs_ret_t @@ -1657,7 +1659,7 @@ njs_string_prototype_split(njs_vm_t *vm, u_char *p, *start, *next; size_t size, length; uint32_t limit; - nxt_uint_t n; + nxt_uint_t n, utf8; njs_array_t *array; const u_char *end; njs_string_prop_t string, split; @@ -1681,13 +1683,32 @@ njs_string_prototype_split(njs_vm_t *vm, limit = (uint32_t) -1; } + length = njs_string_prop(&string, &args[0]); + + if (string.size == 0) { + goto single; + } + + /* Byte string. */ + utf8 = 0; + n = 0; + + if (string.length != 0) { + /* ASCII string. */ + utf8 = 1; + n = 1; + + if (string.length != string.size) { + /* UTF-8 string. */ + utf8 = 2; + } + } + switch (args[1].type) { case NJS_STRING: (void) njs_string_prop(&split, &args[1]); - length = njs_string_prop(&string, &args[0]); - if (string.size < split.size) { goto single; } @@ -1711,9 +1732,8 @@ njs_string_prototype_split(njs_vm_t *vm, } size = p - start; - length = nxt_utf8_length(start, size); - - ret = njs_array_string_add(vm, array, start, size, length); + + ret = njs_string_split_part_add(vm, array, start, size, utf8); if (nxt_slow_path(ret != NXT_OK)) { return ret; } @@ -1728,10 +1748,6 @@ njs_string_prototype_split(njs_vm_t *vm, case NJS_REGEXP: pattern = args[1].data.u.regexp->pattern; - (void) njs_string_prop(&string, &args[0]); - - n = (string.length != 0 && string.length != string.size); - if (!nxt_regex_is_valid(&pattern->regex[n])) { goto single; } @@ -1764,9 +1780,8 @@ njs_string_prototype_split(njs_vm_t *vm, } size = p - start; - length = nxt_utf8_length(start, size); - - ret = njs_array_string_add(vm, array, start, size, length); + + ret = njs_string_split_part_add(vm, array, start, size, utf8); if (nxt_slow_path(ret != NXT_OK)) { return ret; } @@ -1799,6 +1814,34 @@ done: } +static njs_ret_t +njs_string_split_part_add(njs_vm_t *vm, njs_array_t *array, u_char *start, + size_t size, nxt_uint_t utf8) +{ + uint32_t length; + + switch (utf8) { + case 0: + length = 0; + break; + + case 1: + length = size; + break; + + default: + length = nxt_utf8_length(start, size); + + if (nxt_slow_path(length < 0)) { + vm->exception = &njs_exception_internal_error; + return NXT_ERROR; + } + } + + return njs_array_string_add(vm, array, start, size, length); +} + + njs_ret_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src) diff -r ef2b708510b1 -r 73dc069a08c0 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Jun 29 13:38:20 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Jul 07 20:49:57 2016 +0300 @@ -2951,6 +2951,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abc'.split('')"), nxt_string("a,b,c") }, + { nxt_string("'abc'.split('abc')"), + nxt_string(",") }, + { nxt_string("'a bc def'.split(' ')"), nxt_string("a,bc,def") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel