Skip to content

Commit c56a890

Browse files
TimothyGuaddaleax
authored andcommitted
querystring: fix up lastPos usage
Use lastPos ONLY for tracking what has been .slice()'d, never as an indication of if key/value has been seen, since lastPos is updated on seeing + as well. PR-URL: #14151 Fixes: #13773 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Brian White <[email protected]>
1 parent bed1344 commit c56a890

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

lib/querystring.js

+10-12
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,7 @@ function parse(qs, sep, eq, options) {
308308
if (lastPos < end) {
309309
// Treat the substring as part of the key instead of the value
310310
key += qs.slice(lastPos, end);
311-
if (keyEncoded)
312-
key = decodeStr(key, decode);
313-
} else {
311+
} else if (key.length === 0) {
314312
// We saw an empty substring between separators
315313
if (--pairs === 0)
316314
return obj;
@@ -319,15 +317,15 @@ function parse(qs, sep, eq, options) {
319317
continue;
320318
}
321319
} else {
322-
if (lastPos < end) {
320+
if (lastPos < end)
323321
value += qs.slice(lastPos, end);
324-
if (valEncoded)
325-
value = decodeStr(value, decode);
326-
}
327-
if (keyEncoded)
328-
key = decodeStr(key, decode);
329322
}
330323

324+
if (key.length > 0 && keyEncoded)
325+
key = decodeStr(key, decode);
326+
if (value.length > 0 && valEncoded)
327+
value = decodeStr(value, decode);
328+
331329
// Use a key array lookup instead of using hasOwnProperty(), which is
332330
// slower
333331
if (keys.indexOf(key) === -1) {
@@ -422,13 +420,13 @@ function parse(qs, sep, eq, options) {
422420
key += qs.slice(lastPos);
423421
else if (sepIdx < sepLen)
424422
value += qs.slice(lastPos);
425-
} else if (eqIdx === 0) {
423+
} else if (eqIdx === 0 && key.length === 0) {
426424
// We ended on an empty substring
427425
return obj;
428426
}
429-
if (keyEncoded)
427+
if (key.length > 0 && keyEncoded)
430428
key = decodeStr(key, decode);
431-
if (valEncoded)
429+
if (value.length > 0 && valEncoded)
432430
value = decodeStr(value, decode);
433431
// Use a key array lookup instead of using hasOwnProperty(), which is slower
434432
if (keys.indexOf(key) === -1) {

test/fixtures/url-searchparams.js

+9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module.exports = [
4444
['=', '=', [['', '']]],
4545
['+', '+=', [[' ', '']]],
4646
['+=', '+=', [[' ', '']]],
47+
['+&', '+=', [[' ', '']]],
4748
['=+', '=+', [['', ' ']]],
4849
['+=&', '+=', [[' ', '']]],
4950
['a&&b', 'a=&b=', [['a', ''], ['b', '']]],
@@ -56,6 +57,14 @@ module.exports = [
5657
['a=&a=value&a=', 'a=&a=value&a=', [['a', ''], ['a', 'value'], ['a', '']]],
5758
['foo%20bar=baz%20quux', 'foo+bar=baz+quux', [['foo bar', 'baz quux']]],
5859
['+foo=+bar', '+foo=+bar', [[' foo', ' bar']]],
60+
['a+', 'a+=', [['a ', '']]],
61+
['=a+', '=a+', [['', 'a ']]],
62+
['a+&', 'a+=', [['a ', '']]],
63+
['=a+&', '=a+', [['', 'a ']]],
64+
['%20+', '++=', [[' ', '']]],
65+
['=%20+', '=++', [['', ' ']]],
66+
['%20+&', '++=', [[' ', '']]],
67+
['=%20+&', '=++', [['', ' ']]],
5968
[
6069
// fake percent encoding
6170
'foo=%©ar&baz=%A©uux&xyzzy=%©ud',

test/parallel/test-querystring.js

+15
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,16 @@ const qsTestCases = [
7878
['a=b&=c&d=e', 'a=b&=c&d=e', { a: 'b', '': 'c', d: 'e' }],
7979
['a=b&=&c=d', 'a=b&=&c=d', { a: 'b', '': '', c: 'd' }],
8080
['&&foo=bar&&', 'foo=bar', { foo: 'bar' }],
81+
['&', '', {}],
8182
['&&&&', '', {}],
8283
['&=&', '=', { '': '' }],
8384
['&=&=', '=&=', { '': [ '', '' ]}],
85+
['=', '=', { '': '' }],
86+
['+', '%20=', { ' ': '' }],
87+
['+=', '%20=', { ' ': '' }],
88+
['+&', '%20=', { ' ': '' }],
89+
['=+', '=%20', { '': ' ' }],
90+
['+=&', '%20=', { ' ': '' }],
8491
['a&&b', 'a=&b=', { 'a': '', 'b': '' }],
8592
['a=a&&b=b', 'a=a&b=b', { 'a': 'a', 'b': 'b' }],
8693
['&a', 'a=', { 'a': '' }],
@@ -91,6 +98,14 @@ const qsTestCases = [
9198
['a=&a=value&a=', 'a=&a=value&a=', { a: [ '', 'value', '' ] }],
9299
['foo+bar=baz+quux', 'foo%20bar=baz%20quux', { 'foo bar': 'baz quux' }],
93100
['+foo=+bar', '%20foo=%20bar', { ' foo': ' bar' }],
101+
['a+', 'a%20=', { 'a ': '' }],
102+
['=a+', '=a%20', { '': 'a ' }],
103+
['a+&', 'a%20=', { 'a ': '' }],
104+
['=a+&', '=a%20', { '': 'a ' }],
105+
['%20+', '%20%20=', { ' ': '' }],
106+
['=%20+', '=%20%20', { '': ' ' }],
107+
['%20+&', '%20%20=', { ' ': '' }],
108+
['=%20+&', '=%20%20', { '': ' ' }],
94109
[null, '', {}],
95110
[undefined, '', {}]
96111
];

0 commit comments

Comments
 (0)