From 10d9f2d77140d48c3ab2781137bea0013d7b3291 Mon Sep 17 00:00:00 2001 From: "Artem S. Povalyukhin" Date: Sat, 31 Oct 2020 23:00:03 +0300 Subject: [PATCH] Fixed querystring.stringify(). --- src/njs_query_string.c | 36 +++++++++++++++++++++----------- src/test/njs_unit_test.c | 44 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/njs_query_string.c b/src/njs_query_string.c index b961ddc5..b7743e9a 100644 --- a/src/njs_query_string.c +++ b/src/njs_query_string.c @@ -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_chb_t *chain, njs_value_t *key, 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_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, goto failed; } - if (i != 0) { + if (chain.last != NULL) { njs_chb_append(&chain, sep.start, sep.size); length += sep.length; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 76a4fa85..c48965c1 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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')"), -- 2.47.3