querystring, url: handle repeated sep in search
* update state machine in parse * repeated sep should be adjusted * `&=&=` should be `{ '': [ '', '' ] }` * add test cases for querystring and URLSearchParams Fixes: https://github.com/nodejs/node/issues/10454 PR-URL: https://github.com/nodejs/node/pull/10967 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com>
This commit is contained in:
parent
0d9ea4fdcd
commit
4e259b21a3
@ -292,6 +292,7 @@ function parse(qs, sep, eq, options) {
|
|||||||
const customDecode = (decode !== qsUnescape);
|
const customDecode = (decode !== qsUnescape);
|
||||||
|
|
||||||
const keys = [];
|
const keys = [];
|
||||||
|
var posIdx = 0;
|
||||||
var lastPos = 0;
|
var lastPos = 0;
|
||||||
var sepIdx = 0;
|
var sepIdx = 0;
|
||||||
var eqIdx = 0;
|
var eqIdx = 0;
|
||||||
@ -319,26 +320,34 @@ function parse(qs, sep, eq, options) {
|
|||||||
key = decodeStr(key, decode);
|
key = decodeStr(key, decode);
|
||||||
if (valEncoded)
|
if (valEncoded)
|
||||||
value = decodeStr(value, decode);
|
value = decodeStr(value, decode);
|
||||||
// Use a key array lookup instead of using hasOwnProperty(), which is
|
|
||||||
// slower
|
if (key || value || lastPos - posIdx > sepLen || i === 0) {
|
||||||
if (keys.indexOf(key) === -1) {
|
// Use a key array lookup instead of using hasOwnProperty(), which is
|
||||||
obj[key] = value;
|
// slower
|
||||||
keys[keys.length] = key;
|
if (keys.indexOf(key) === -1) {
|
||||||
} else {
|
obj[key] = value;
|
||||||
const curValue = obj[key];
|
keys[keys.length] = key;
|
||||||
// A simple Array-specific property check is enough here to
|
} else {
|
||||||
// distinguish from a string value and is faster and still safe since
|
const curValue = obj[key] || '';
|
||||||
// we are generating all of the values being assigned.
|
// A simple Array-specific property check is enough here to
|
||||||
if (curValue.pop)
|
// distinguish from a string value and is faster and still safe
|
||||||
curValue[curValue.length] = value;
|
// since we are generating all of the values being assigned.
|
||||||
else
|
if (curValue.pop)
|
||||||
obj[key] = [curValue, value];
|
curValue[curValue.length] = value;
|
||||||
|
else if (curValue)
|
||||||
|
obj[key] = [curValue, value];
|
||||||
|
}
|
||||||
|
} else if (i === 1) {
|
||||||
|
// A pair with repeated sep could be added into obj in the first loop
|
||||||
|
// and it should be deleted
|
||||||
|
delete obj[key];
|
||||||
}
|
}
|
||||||
if (--pairs === 0)
|
if (--pairs === 0)
|
||||||
break;
|
break;
|
||||||
keyEncoded = valEncoded = customDecode;
|
keyEncoded = valEncoded = customDecode;
|
||||||
encodeCheck = 0;
|
encodeCheck = 0;
|
||||||
key = value = '';
|
key = value = '';
|
||||||
|
posIdx = lastPos;
|
||||||
lastPos = i + 1;
|
lastPos = i + 1;
|
||||||
sepIdx = eqIdx = 0;
|
sepIdx = eqIdx = 0;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,14 @@ const qsTestCases = [
|
|||||||
__defineGetter__: 'baz' }],
|
__defineGetter__: 'baz' }],
|
||||||
// See: https://github.com/joyent/node/issues/3058
|
// See: https://github.com/joyent/node/issues/3058
|
||||||
['foo&bar=baz', 'foo=&bar=baz', { foo: '', bar: 'baz' }],
|
['foo&bar=baz', 'foo=&bar=baz', { foo: '', bar: 'baz' }],
|
||||||
|
['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=e', 'a=b&=c&d=e', { a: 'b', '': 'c', d: 'e' }],
|
||||||
|
['a=b&=&c=d', 'a=b&=&c=d', { a: 'b', '': '', c: 'd' }],
|
||||||
|
['&&foo=bar&&', 'foo=bar', { foo: 'bar' }],
|
||||||
|
['&&&&', '', {}],
|
||||||
|
['&=&', '=', { '': '' }],
|
||||||
|
['&=&=', '=&=', { '': [ '', '' ]}],
|
||||||
[null, '', {}],
|
[null, '', {}],
|
||||||
[undefined, '', {}]
|
[undefined, '', {}]
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user