diff --git a/lib/parse.js b/lib/parse.js index 3be8e1bc..67fb938f 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -85,7 +85,15 @@ var parseValues = function parseQueryStringValues(str, options) { val = options.strictNullHandling ? null : ''; } else { key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); - val = options.decoder(part.slice(pos + 1), defaults.decoder, charset, 'value'); + var encodedVal = part.slice(pos + 1); + if (options.comma && encodedVal.indexOf(',') !== -1) { + val = encodedVal.split(',') + .map(function (encodedFragment) { + return options.decoder(encodedFragment, defaults.decoder, charset, 'value'); + }); + } else { + val = options.decoder(encodedVal, defaults.decoder, charset, 'value'); + } } if (val && options.interpretNumericEntities && charset === 'iso-8859-1') { diff --git a/test/parse.js b/test/parse.js index 903b2af3..10b649a7 100644 --- a/test/parse.js +++ b/test/parse.js @@ -429,6 +429,14 @@ test('parse()', function (t) { st.end(); }); + t.test('parses comma delimited array while having percent-encoded comma treated as normal text', function (st) { + st.deepEqual(qs.parse('foo=a%2Cb', { comma: true }), { foo: ['a', 'b'] }); + st.deepEqual(qs.parse('foo=a%2C%20b,d', { comma: true }), { foo: ['a, b', 'd'] }); + st.deepEqual(qs.parse('foo=a%2C%20b,c%2C%20d', { comma: true }), { foo: ['a, b', 'c, d'] }); + + st.end(); + }); + t.test('parses an object in dot notation', function (st) { var input = { 'user.name': { 'pop[bob]': 3 },