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: https://github.com/nodejs/node/pull/14151 Fixes: https://github.com/nodejs/node/issues/13773 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
This commit is contained in:
parent
e6e6b07e51
commit
afab5aba32
@ -308,9 +308,7 @@ function parse(qs, sep, eq, options) {
|
|||||||
if (lastPos < end) {
|
if (lastPos < end) {
|
||||||
// Treat the substring as part of the key instead of the value
|
// Treat the substring as part of the key instead of the value
|
||||||
key += qs.slice(lastPos, end);
|
key += qs.slice(lastPos, end);
|
||||||
if (keyEncoded)
|
} else if (key.length === 0) {
|
||||||
key = decodeStr(key, decode);
|
|
||||||
} else {
|
|
||||||
// We saw an empty substring between separators
|
// We saw an empty substring between separators
|
||||||
if (--pairs === 0)
|
if (--pairs === 0)
|
||||||
return obj;
|
return obj;
|
||||||
@ -319,15 +317,15 @@ function parse(qs, sep, eq, options) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (lastPos < end) {
|
if (lastPos < end)
|
||||||
value += qs.slice(lastPos, end);
|
value += qs.slice(lastPos, end);
|
||||||
if (valEncoded)
|
|
||||||
value = decodeStr(value, decode);
|
|
||||||
}
|
|
||||||
if (keyEncoded)
|
|
||||||
key = decodeStr(key, decode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key.length > 0 && keyEncoded)
|
||||||
|
key = decodeStr(key, decode);
|
||||||
|
if (value.length > 0 && valEncoded)
|
||||||
|
value = decodeStr(value, decode);
|
||||||
|
|
||||||
// Use a key array lookup instead of using hasOwnProperty(), which is
|
// Use a key array lookup instead of using hasOwnProperty(), which is
|
||||||
// slower
|
// slower
|
||||||
if (keys.indexOf(key) === -1) {
|
if (keys.indexOf(key) === -1) {
|
||||||
@ -422,13 +420,13 @@ function parse(qs, sep, eq, options) {
|
|||||||
key += qs.slice(lastPos);
|
key += qs.slice(lastPos);
|
||||||
else if (sepIdx < sepLen)
|
else if (sepIdx < sepLen)
|
||||||
value += qs.slice(lastPos);
|
value += qs.slice(lastPos);
|
||||||
} else if (eqIdx === 0) {
|
} else if (eqIdx === 0 && key.length === 0) {
|
||||||
// We ended on an empty substring
|
// We ended on an empty substring
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
if (keyEncoded)
|
if (key.length > 0 && keyEncoded)
|
||||||
key = decodeStr(key, decode);
|
key = decodeStr(key, decode);
|
||||||
if (valEncoded)
|
if (value.length > 0 && valEncoded)
|
||||||
value = decodeStr(value, decode);
|
value = decodeStr(value, decode);
|
||||||
// Use a key array lookup instead of using hasOwnProperty(), which is slower
|
// Use a key array lookup instead of using hasOwnProperty(), which is slower
|
||||||
if (keys.indexOf(key) === -1) {
|
if (keys.indexOf(key) === -1) {
|
||||||
|
9
test/fixtures/url-searchparams.js
vendored
9
test/fixtures/url-searchparams.js
vendored
@ -44,6 +44,7 @@ module.exports = [
|
|||||||
['=', '=', [['', '']]],
|
['=', '=', [['', '']]],
|
||||||
['+', '+=', [[' ', '']]],
|
['+', '+=', [[' ', '']]],
|
||||||
['+=', '+=', [[' ', '']]],
|
['+=', '+=', [[' ', '']]],
|
||||||
|
['+&', '+=', [[' ', '']]],
|
||||||
['=+', '=+', [['', ' ']]],
|
['=+', '=+', [['', ' ']]],
|
||||||
['+=&', '+=', [[' ', '']]],
|
['+=&', '+=', [[' ', '']]],
|
||||||
['a&&b', 'a=&b=', [['a', ''], ['b', '']]],
|
['a&&b', 'a=&b=', [['a', ''], ['b', '']]],
|
||||||
@ -56,6 +57,14 @@ module.exports = [
|
|||||||
['a=&a=value&a=', 'a=&a=value&a=', [['a', ''], ['a', 'value'], ['a', '']]],
|
['a=&a=value&a=', 'a=&a=value&a=', [['a', ''], ['a', 'value'], ['a', '']]],
|
||||||
['foo%20bar=baz%20quux', 'foo+bar=baz+quux', [['foo bar', 'baz quux']]],
|
['foo%20bar=baz%20quux', 'foo+bar=baz+quux', [['foo bar', 'baz quux']]],
|
||||||
['+foo=+bar', '+foo=+bar', [[' foo', ' bar']]],
|
['+foo=+bar', '+foo=+bar', [[' foo', ' bar']]],
|
||||||
|
['a+', 'a+=', [['a ', '']]],
|
||||||
|
['=a+', '=a+', [['', 'a ']]],
|
||||||
|
['a+&', 'a+=', [['a ', '']]],
|
||||||
|
['=a+&', '=a+', [['', 'a ']]],
|
||||||
|
['%20+', '++=', [[' ', '']]],
|
||||||
|
['=%20+', '=++', [['', ' ']]],
|
||||||
|
['%20+&', '++=', [[' ', '']]],
|
||||||
|
['=%20+&', '=++', [['', ' ']]],
|
||||||
[
|
[
|
||||||
// fake percent encoding
|
// fake percent encoding
|
||||||
'foo=%©ar&baz=%A©uux&xyzzy=%©ud',
|
'foo=%©ar&baz=%A©uux&xyzzy=%©ud',
|
||||||
|
@ -78,9 +78,16 @@ const qsTestCases = [
|
|||||||
['a=b&=c&d=e', 'a=b&=c&d=e', { a: 'b', '': 'c', d: 'e' }],
|
['a=b&=c&d=e', 'a=b&=c&d=e', { a: 'b', '': 'c', d: 'e' }],
|
||||||
['a=b&=&c=d', 'a=b&=&c=d', { a: 'b', '': '', c: 'd' }],
|
['a=b&=&c=d', 'a=b&=&c=d', { a: 'b', '': '', c: 'd' }],
|
||||||
['&&foo=bar&&', 'foo=bar', { foo: 'bar' }],
|
['&&foo=bar&&', 'foo=bar', { foo: 'bar' }],
|
||||||
|
['&', '', {}],
|
||||||
['&&&&', '', {}],
|
['&&&&', '', {}],
|
||||||
['&=&', '=', { '': '' }],
|
['&=&', '=', { '': '' }],
|
||||||
['&=&=', '=&=', { '': [ '', '' ]}],
|
['&=&=', '=&=', { '': [ '', '' ]}],
|
||||||
|
['=', '=', { '': '' }],
|
||||||
|
['+', '%20=', { ' ': '' }],
|
||||||
|
['+=', '%20=', { ' ': '' }],
|
||||||
|
['+&', '%20=', { ' ': '' }],
|
||||||
|
['=+', '=%20', { '': ' ' }],
|
||||||
|
['+=&', '%20=', { ' ': '' }],
|
||||||
['a&&b', 'a=&b=', { 'a': '', 'b': '' }],
|
['a&&b', 'a=&b=', { 'a': '', 'b': '' }],
|
||||||
['a=a&&b=b', 'a=a&b=b', { 'a': 'a', 'b': 'b' }],
|
['a=a&&b=b', 'a=a&b=b', { 'a': 'a', 'b': 'b' }],
|
||||||
['&a', 'a=', { 'a': '' }],
|
['&a', 'a=', { 'a': '' }],
|
||||||
@ -91,6 +98,14 @@ const qsTestCases = [
|
|||||||
['a=&a=value&a=', 'a=&a=value&a=', { a: [ '', 'value', '' ] }],
|
['a=&a=value&a=', 'a=&a=value&a=', { a: [ '', 'value', '' ] }],
|
||||||
['foo+bar=baz+quux', 'foo%20bar=baz%20quux', { 'foo bar': 'baz quux' }],
|
['foo+bar=baz+quux', 'foo%20bar=baz%20quux', { 'foo bar': 'baz quux' }],
|
||||||
['+foo=+bar', '%20foo=%20bar', { ' foo': ' bar' }],
|
['+foo=+bar', '%20foo=%20bar', { ' foo': ' bar' }],
|
||||||
|
['a+', 'a%20=', { 'a ': '' }],
|
||||||
|
['=a+', '=a%20', { '': 'a ' }],
|
||||||
|
['a+&', 'a%20=', { 'a ': '' }],
|
||||||
|
['=a+&', '=a%20', { '': 'a ' }],
|
||||||
|
['%20+', '%20%20=', { ' ': '' }],
|
||||||
|
['=%20+', '=%20%20', { '': ' ' }],
|
||||||
|
['%20+&', '%20%20=', { ' ': '' }],
|
||||||
|
['=%20+&', '=%20%20', { '': ' ' }],
|
||||||
[null, '', {}],
|
[null, '', {}],
|
||||||
[undefined, '', {}]
|
[undefined, '', {}]
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user