From 81835ff51d852c97e364eff78bbb8c58072aca71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klemen=20Tu=C5=A1ar?= Date: Sun, 19 May 2024 11:11:06 +0100 Subject: [PATCH] [Fix]: `parse`: parse encoded square brackets --- lib/parse.js | 1 + test/parse.js | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/lib/parse.js b/lib/parse.js index 54f24c12..8eedf63d 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -55,6 +55,7 @@ var parseValues = function parseQueryStringValues(str, options) { var obj = { __proto__: null }; var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; + cleanStr = cleanStr.replace(/%5B/gi, '[').replace(/%5D/gi, ']'); var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit; var parts = cleanStr.split(options.delimiter, limit); var skipIndex = -1; // Keep track of where the utf8 sentinel was found diff --git a/test/parse.js b/test/parse.js index f63c51cb..8724b2cc 100644 --- a/test/parse.js +++ b/test/parse.js @@ -571,6 +571,15 @@ test('parse()', function (t) { st.end(); }); + t.test('parses url-encoded brackets holds array of arrays when having two parts of strings with comma as array divider', function (st) { + st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=4,5,6', { comma: true }), { foo: [['1', '2', '3'], ['4', '5', '6']] }); + st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=', { comma: true }), { foo: [['1', '2', '3'], ''] }); + st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=,', { comma: true }), { foo: [['1', '2', '3'], ['', '']] }); + st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=a', { comma: true }), { foo: [['1', '2', '3'], 'a'] }); + + 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'] });