[njs] Fixed integer-overflow in String.prototype.concat().

Alexander Borisov alexander.borisov at nginx.com
Tue May 21 17:46:06 UTC 2019


details:   https://hg.nginx.org/njs/rev/96dc80e2ea1b
branches:  
changeset: 976:96dc80e2ea1b
user:      Alexander Borisov <alexander.borisov at nginx.com>
date:      Tue May 21 20:45:42 2019 +0300
description:
Fixed integer-overflow in String.prototype.concat().

This closes #159 issue on GitHub.

diffstat:

 njs/njs_string.c         |  11 ++++++++---
 njs/njs_string.h         |   4 ++--
 njs/test/njs_unit_test.c |   5 +++++
 3 files changed, 15 insertions(+), 5 deletions(-)

diffs (61 lines):

diff -r 8d8fd9c98174 -r 96dc80e2ea1b njs/njs_string.c
--- a/njs/njs_string.c	Tue May 21 19:39:25 2019 +0300
+++ b/njs/njs_string.c	Tue May 21 20:45:42 2019 +0300
@@ -181,12 +181,17 @@ njs_string_new(njs_vm_t *vm, njs_value_t
 
 
 nxt_noinline u_char *
-njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size,
-    uint32_t length)
+njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size,
+    uint64_t length)
 {
     uint32_t      total, map_offset, *map;
     njs_string_t  *string;
 
+    if (nxt_slow_path(size > NJS_STRING_MAX_LENGTH)) {
+        njs_range_error(vm, "invalid string length");
+        return NULL;
+    }
+
     value->type = NJS_STRING;
     njs_string_truth(value, size);
 
@@ -844,7 +849,7 @@ njs_string_prototype_concat(njs_vm_t *vm
     njs_index_t unused)
 {
     u_char             *p, *start;
-    size_t             size, length, mask;
+    uint64_t           size, length, mask;
     nxt_uint_t         i;
     njs_string_prop_t  string;
 
diff -r 8d8fd9c98174 -r 96dc80e2ea1b njs/njs_string.h
--- a/njs/njs_string.h	Tue May 21 19:39:25 2019 +0300
+++ b/njs/njs_string.h	Tue May 21 20:45:42 2019 +0300
@@ -145,8 +145,8 @@ njs_string_length(njs_value_t *string)
 
 njs_ret_t njs_string_set(njs_vm_t *vm, njs_value_t *value, const u_char *start,
     uint32_t size);
-u_char *njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size,
-    uint32_t length);
+u_char *njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size,
+    uint64_t length);
 njs_ret_t njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
     uint32_t size, uint32_t length);
 njs_ret_t njs_string_hex(njs_vm_t *vm, njs_value_t *value,
diff -r 8d8fd9c98174 -r 96dc80e2ea1b njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Tue May 21 19:39:25 2019 +0300
+++ b/njs/test/njs_unit_test.c	Tue May 21 20:45:42 2019 +0300
@@ -4620,6 +4620,11 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("'A'.repeat(16).toBytes() === 'A'.repeat(16)"),
       nxt_string("true") },
 
+    { nxt_string("var s = 'x'.repeat(2**10).repeat(2**14);"
+                 "var a = Array(200).fill(s);"
+                 "String.prototype.concat.apply(s, a.slice(1))"),
+      nxt_string("RangeError: invalid string length") },
+
     { nxt_string("var a = 'abcdefgh'; a.substr(3, 15)"),
       nxt_string("defgh") },
 


More information about the nginx-devel mailing list