[njs] Byte string processing was fixed in String.split(),

Igor Sysoev igor at sysoev.ru
Mon Jul 11 12:10:01 UTC 2016


details:   http://hg.nginx.org/njs/rev/73dc069a08c0
branches:  
changeset: 116:73dc069a08c0
user:      Igor Sysoev <igor at 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") },
 



More information about the nginx-devel mailing list