[njs] Fixed querystring.stringify().

Dmitry Volyntsev xeioex at nginx.com
Mon Nov 2 19:10:20 UTC 2020


details:   https://hg.nginx.org/njs/rev/b523bbbd8e6d
branches:  
changeset: 1557:b523bbbd8e6d
user:      Artem S. Povalyukhin <artem.povaluhin at gmail.com>
date:      Sat Oct 31 23:00:03 2020 +0300
description:
Fixed querystring.stringify().

diffstat:

 src/njs_query_string.c   |  36 ++++++++++++++++++++++++------------
 src/test/njs_unit_test.c |  44 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 13 deletions(-)

diffs (140 lines):

diff -r 7ae9a0502fa1 -r b523bbbd8e6d src/njs_query_string.c
--- a/src/njs_query_string.c	Sat Oct 31 22:38:22 2020 +0100
+++ b/src/njs_query_string.c	Sat Oct 31 23:00:03 2020 +0300
@@ -549,8 +549,8 @@ njs_inline njs_int_t
 njs_query_string_push(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *key,
     njs_value_t *value, njs_string_prop_t *eq, njs_function_t *encoder)
 {
+    double     num;
     njs_int_t  ret, length;
-    njs_str_t  str;
 
     length = 0;
 
@@ -561,25 +561,37 @@ njs_query_string_push(njs_vm_t *vm, njs_
 
     length += ret;
 
-    if (!njs_is_string(value)) {
-        ret = njs_value_to_string(vm, value, value);
+    njs_chb_append(chain, eq->start, eq->size);
+    length += eq->length;
+
+    switch (value->type) {
+    case NJS_NUMBER:
+        num = njs_number(value);
+        if (njs_slow_path(isnan(num) || isinf(num))) {
+            break;
+        }
+
+        /* Fall through. */
+
+    case NJS_BOOLEAN:
+        ret = njs_primitive_value_to_string(vm, value, value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
-    }
-
-    njs_string_get(value, &str);
 
-    if (str.length > 0) {
-        njs_chb_append(chain, eq->start, eq->size);
-        length += eq->length;
+        /* Fall through. */
 
+    case NJS_STRING:
         ret = njs_query_string_encoder_call(vm, chain, encoder, value);
         if (njs_slow_path(ret < 0)) {
             return NJS_ERROR;
         }
 
         length += ret;
+        break;
+
+    default:
+        break;
     }
 
     return length;
@@ -673,7 +685,7 @@ njs_query_string_stringify(njs_vm_t *vm,
     njs_chb_init(&chain, vm->mem_pool);
 
     keys = njs_value_own_enumerate(vm, object, NJS_ENUM_KEYS, NJS_ENUM_STRING,
-                                   1);
+                                   0);
     if (njs_slow_path(keys == NULL)) {
         return NJS_ERROR;
     }
@@ -692,7 +704,7 @@ njs_query_string_stringify(njs_vm_t *vm,
                 array = njs_array(&value);
 
                 for (i = 0; i < array->length; i++) {
-                    if (i != 0) {
+                    if (chain.last != NULL) {
                         njs_chb_append(&chain, sep.start, sep.size);
                         length += sep.length;
                     }
@@ -721,7 +733,7 @@ njs_query_string_stringify(njs_vm_t *vm,
                     goto failed;
                 }
 
-                if (i != 0) {
+                if (chain.last != NULL) {
                     njs_chb_append(&chain, sep.start, sep.size);
                     length += sep.length;
                 }
diff -r 7ae9a0502fa1 -r b523bbbd8e6d src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Sat Oct 31 22:38:22 2020 +0100
+++ b/src/test/njs_unit_test.c	Sat Oct 31 23:00:03 2020 +0300
@@ -18233,7 +18233,49 @@ static njs_unit_test_t  njs_test[] =
 
     { njs_str("var qs = require('querystring');"
               "qs.stringify({X:{toString(){return 3}}})"),
-      njs_str("X=3") },
+      njs_str("X=") },
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify({ name: undefined, age: 12 })"),
+      njs_str("name=&age=12") },
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify(Object.create({ name: undefined, age: 12 }))"),
+      njs_str("") },
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify([])"),
+      njs_str("") },
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify(['','',''])"),
+      njs_str("0=&1=&2=") },
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify([undefined, null, Symbol(), Object(0), Object('test'), Object(false),,,])"),
+      njs_str("0=&1=&2=&3=&4=&5=") },
+
+#if 0
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify([NaN, Infinity, -Infinity, 2**69, 2**70])"),
+      njs_str("0=&1=&2=&3=590295810358705700000&4=1.1805916207174113e%2B21") },
+#else
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify([NaN, Infinity, -Infinity, 2**69, 2**70])"),
+      njs_str("0=&1=&2=&3=590295810358705700000&4=1.1805916207174114e%2B21") },
+#endif
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify([[1,2,3],[4,5,6]])"),
+      njs_str("0=1&0=2&0=3&1=4&1=5&1=6") },
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify([['a',,,],['b',,,]])"),
+      njs_str("0=a&0=&0=&1=b&1=&1=") },
+
+    { njs_str("var qs = require('querystring');"
+              "qs.stringify([[,'a','b',,]])"),
+      njs_str("0=&0=a&0=b&0=") },
 
     { njs_str("var qs = require('querystring');"
               "qs.escape('abcααααdef')"),


More information about the nginx-devel mailing list