From 4a17709e71ae510a7195ff57b969a2bf9cde139f Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 19 Apr 2021 08:35:28 -0700 Subject: [PATCH] [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424) Fixes #410 --- lib/stringify.js | 13 +++++++++++-- test/stringify.js | 25 ++++++++++--------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/stringify.js b/lib/stringify.js index f46bb0e1..f70820f9 100644 --- a/lib/stringify.js +++ b/lib/stringify.js @@ -18,6 +18,7 @@ var arrayPrefixGenerators = { }; var isArray = Array.isArray; +var split = String.prototype.split; var push = Array.prototype.push; var pushToArray = function (arr, valueOrArray) { push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]); @@ -95,6 +96,14 @@ var stringify = function stringify( if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { if (encoder) { var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format); + if (generateArrayPrefix === 'comma' && encodeValuesOnly) { + var valuesArray = split.call(String(obj), ','); + var valuesJoined = ''; + for (var i = 0; i < valuesArray.length; ++i) { + valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format)); + } + return [formatter(keyValue) + '=' + valuesJoined]; + } return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; } return [formatter(prefix) + '=' + formatter(String(obj))]; @@ -117,8 +126,8 @@ var stringify = function stringify( objKeys = sort ? keys.sort(sort) : keys; } - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; + for (var j = 0; j < objKeys.length; ++j) { + var key = objKeys[j]; var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key]; if (skipNulls && value === null) { diff --git a/test/stringify.js b/test/stringify.js index 8c113bab..f761fb35 100644 --- a/test/stringify.js +++ b/test/stringify.js @@ -134,8 +134,7 @@ test('stringify()', function (t) { t.test('stringifies a nested array value', function (st) { st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[b][0]=c&a[b][1]=d'); st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[b][]=c&a[b][]=d'); - st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[b]=c%2Cd'); - st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[b]=c,d', '(pending issue #378)', { skip: true }); + st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[b]=c,d'); st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true }), 'a[b][0]=c&a[b][1]=d'); st.end(); }); @@ -157,22 +156,13 @@ test('stringify()', function (t) { 'a.b[]=c&a.b[]=d', 'brackets: stringifies with dots + brackets' ); - st.equal( - qs.stringify( - { a: { b: ['c', 'd'] } }, - { allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' } - ), - 'a.b=c%2Cd', - 'comma: stringifies with dots + comma' - ); st.equal( qs.stringify( { a: { b: ['c', 'd'] } }, { allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' } ), 'a.b=c,d', - 'comma: stringifies with dots + comma (pending issue #378)', - { skip: true } + 'comma: stringifies with dots + comma' ); st.equal( qs.stringify( @@ -237,8 +227,8 @@ test('stringify()', function (t) { st.equal( qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), '???', - 'brackets => brackets (pending issue #378)', - { skip: true } + 'brackets => brackets', + { skip: 'TODO: figure out what this should do' } ); st.equal( qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true }), @@ -800,7 +790,12 @@ test('stringify()', function (t) { st.equal(qs.stringify(withArray, { encode: false }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, no arrayFormat'); st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'bracket' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, bracket'); st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'indices' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, indices'); - st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }), '???', 'array, comma (pending issue #378)', { skip: true }); + st.equal( + qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }), + '???', + 'array, comma', + { skip: 'TODO: figure out what this should do' } + ); st.end(); });