Skip to content

Commit 97d2da1

Browse files
kukawskikvz
authored andcommitted
Fix issue locutusjs#366: wrong parsing of nested arrays (locutusjs#369)
* Fix issue locutusjs#366: wrong parsing of nested arrays * Updated tests for modified parse_str after fixing issue locutusjs#366
1 parent 0326e7c commit 97d2da1

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

src/php/strings/parse_str.js

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = function parse_str (str, array) { // eslint-disable-line camelc
1414
// input by: Zaide (http://zaidesthings.com/)
1515
// input by: David Pesta (http://davidpesta.com/)
1616
// input by: jeicquest
17+
// bugfixed by: Rafał Kukawski
1718
// note 1: When no argument is specified, will put variables in global scope.
1819
// note 1: When a particular argument has been passed, and the
1920
// note 1: returned value is different parse_str of PHP.
@@ -30,6 +31,14 @@ module.exports = function parse_str (str, array) { // eslint-disable-line camelc
3031
// example 3: parse_str('a[b]["c"]=def&a[q]=t+5', $abc)
3132
// example 3: var $result = $abc
3233
// returns 3: {"3":"a","a":{"b":{"c":"def"},"q":"t 5"}}
34+
// example 4: var $arr = {}
35+
// example 4: parse_str('a[][]=value', $arr)
36+
// example 4: var $result = $arr
37+
// returns 4: {"a":{"0":{"0":"value"}}}
38+
// example 5: var $arr = {}
39+
// example 5: parse_str('a=1&a[]=2', $arr)
40+
// example 5: var $result = $arr
41+
// returns 5: {"a":{"0":"2"}}
3342

3443
var strArr = String(str).replace(/^&/, '').replace(/&$/, '').split('&')
3544
var sal = strArr.length
@@ -39,7 +48,6 @@ module.exports = function parse_str (str, array) { // eslint-disable-line camelc
3948
var p
4049
var lastObj
4150
var obj
42-
var undef
4351
var chr
4452
var tmp
4553
var key
@@ -69,12 +77,15 @@ module.exports = function parse_str (str, array) { // eslint-disable-line camelc
6977
while (key.charAt(0) === ' ') {
7078
key = key.slice(1)
7179
}
80+
7281
if (key.indexOf('\x00') > -1) {
7382
key = key.slice(0, key.indexOf('\x00'))
7483
}
84+
7585
if (key && key.charAt(0) !== '[') {
7686
keys = []
7787
postLeftBracketPos = 0
88+
7889
for (j = 0; j < key.length; j++) {
7990
if (key.charAt(j) === '[' && !postLeftBracketPos) {
8091
postLeftBracketPos = j + 1
@@ -83,49 +94,62 @@ module.exports = function parse_str (str, array) { // eslint-disable-line camelc
8394
if (!keys.length) {
8495
keys.push(key.slice(0, postLeftBracketPos - 1))
8596
}
97+
8698
keys.push(key.substr(postLeftBracketPos, j - postLeftBracketPos))
8799
postLeftBracketPos = 0
100+
88101
if (key.charAt(j + 1) !== '[') {
89102
break
90103
}
91104
}
92105
}
93106
}
107+
94108
if (!keys.length) {
95109
keys = [key]
96110
}
111+
97112
for (j = 0; j < keys[0].length; j++) {
98113
chr = keys[0].charAt(j)
114+
99115
if (chr === ' ' || chr === '.' || chr === '[') {
100116
keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1)
101117
}
118+
102119
if (chr === '[') {
103120
break
104121
}
105122
}
106123

107124
obj = array
125+
108126
for (j = 0, keysLen = keys.length; j < keysLen; j++) {
109127
key = keys[j].replace(/^['"]/, '').replace(/['"]$/, '')
110128
lastObj = obj
111-
if ((key !== '' && key !== ' ') || j === 0) {
112-
if (obj[key] === undef) {
113-
obj[key] = {}
114-
}
115-
obj = obj[key]
116-
} else {
117-
// To insert new dimension
129+
130+
if ((key === '' || key === ' ') && j !== 0) {
131+
// Insert new dimension
118132
ct = -1
133+
119134
for (p in obj) {
120135
if (obj.hasOwnProperty(p)) {
121136
if (+p > ct && p.match(/^\d+$/g)) {
122137
ct = +p
123138
}
124139
}
125140
}
141+
126142
key = ct + 1
127143
}
144+
145+
// if primitive value, replace with object
146+
if (Object(obj[key]) !== obj[key]) {
147+
obj[key] = {}
148+
}
149+
150+
obj = obj[key]
128151
}
152+
129153
lastObj[key] = value
130154
}
131155
}

test/languages/php/strings/test-parse_str.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,20 @@ describe('src/php/strings/parse_str.js (tested in test/languages/php/strings/tes
3131
expect(result).to.deep.equal(expected)
3232
done()
3333
})
34+
it('should pass example 4', function (done) {
35+
var expected = {"a":{"0":{"0":"value"}}}
36+
var $arr = {}
37+
parse_str('a[][]=value', $arr)
38+
var result = $arr
39+
expect(result).to.deep.equal(expected)
40+
done()
41+
})
42+
it('should pass example 5', function (done) {
43+
var expected = {"a":{"0":"2"}}
44+
var $arr = {}
45+
parse_str('a=1&a[]=2', $arr)
46+
var result = $arr
47+
expect(result).to.deep.equal(expected)
48+
done()
49+
})
3450
})

0 commit comments

Comments
 (0)