[njs] Fixed handling of space argument in JSON.stringify().

Alexander Borisov alexander.borisov at nginx.com
Wed Feb 26 09:42:52 UTC 2020


details:   https://hg.nginx.org/njs/rev/079d4d4556f0
branches:  
changeset: 1335:079d4d4556f0
user:      Alexander Borisov <alexander.borisov at nginx.com>
date:      Wed Feb 26 12:41:51 2020 +0300
description:
Fixed handling of space argument in JSON.stringify().

This closes #294 issue on GitHub.

diffstat:

 src/njs_json.c           |  22 ++++++++++++++++++++--
 src/test/njs_unit_test.c |  12 ++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diffs (65 lines):

diff -r 0173143d7b15 -r 079d4d4556f0 src/njs_json.c
--- a/src/njs_json.c	Wed Feb 19 17:21:32 2020 +0300
+++ b/src/njs_json.c	Wed Feb 26 12:41:51 2020 +0300
@@ -187,10 +187,13 @@ static njs_int_t
 njs_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    size_t                length;
     double                num;
     njs_int_t             i;
     njs_int_t             ret;
     njs_value_t           *replacer, *space;
+    const u_char          *p;
+    njs_string_prop_t     prop;
     njs_json_stringify_t  *stringify, json_stringify;
 
     stringify = &json_stringify;
@@ -220,8 +223,23 @@ njs_json_stringify(njs_vm_t *vm, njs_val
 
     if (njs_is_string(space) || njs_is_number(space)) {
         if (njs_is_string(space)) {
-            njs_string_get(space, &stringify->space);
-            stringify->space.length = njs_min(stringify->space.length, 10);
+            length = njs_string_prop(&prop, space);
+
+            if (njs_is_byte_string(&prop)) {
+                njs_internal_error(vm, "space argument cannot be"
+                                   " a byte string");
+                return NJS_ERROR;
+            }
+
+            if (length > 10) {
+                p = njs_string_offset(prop.start, prop.start + prop.size, 10);
+
+            } else {
+                p = prop.start + prop.size;
+            }
+
+            stringify->space.start = prop.start;
+            stringify->space.length = p - prop.start;
 
         } else {
             num = njs_number(space);
diff -r 0173143d7b15 -r 079d4d4556f0 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Feb 19 17:21:32 2020 +0300
+++ b/src/test/njs_unit_test.c	Wed Feb 26 12:41:51 2020 +0300
@@ -15674,6 +15674,18 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("JSON.stringify([{a:1,b:{c:2}},1], undefined, new Date())"),
       njs_str("[{\"a\":1,\"b\":{\"c\":2}},1]") },
 
+    { njs_str("JSON.stringify([], null, '!βββββ').length"),
+      njs_str("10") },
+
+    { njs_str("JSON.stringify([], null, '!!βββββββββββββββββ').length"),
+      njs_str("14") },
+
+    { njs_str("JSON.stringify([], null, '!βββββββββββββββββ').length"),
+      njs_str("14") },
+
+    { njs_str("JSON.stringify([], null, String.bytesFrom([0x9d])).length"),
+      njs_str("InternalError: space argument cannot be a byte string") },
+
     { njs_str("var o = Object.defineProperty({}, 'a', { get() { return ()=> 1}, enumerable: true });"
               "JSON.stringify(o)"),
       njs_str("{}") },


More information about the nginx-devel mailing list