Skip to content

Commit 8496516

Browse files
committed
Fix parsing deeply nested POST structures
1 parent d205a8e commit 8496516

2 files changed

Lines changed: 70 additions & 16 deletions

File tree

src/Io/MultipartParser.php

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -250,29 +250,27 @@ private function extractPost($postFields, $key, $value)
250250
return $postFields;
251251
}
252252

253-
$chunkKey = $chunks[0];
254-
if (!isset($postFields[$chunkKey])) {
255-
$postFields[$chunkKey] = array();
256-
}
257-
253+
$chunkKey = rtrim($chunks[0], ']');
258254
$parent = &$postFields;
259255
for ($i = 1; $i < count($chunks); $i++) {
260256
$previousChunkKey = $chunkKey;
261-
if (!isset($parent[$previousChunkKey])) {
257+
if ($previousChunkKey !== '' && !isset($parent[$previousChunkKey])) {
262258
$parent[$previousChunkKey] = array();
263259
}
264-
$parent = &$parent[$previousChunkKey];
265-
$chunkKey = $chunks[$i];
266260

267-
if ($chunkKey == ']') {
268-
$parent[] = $value;
269-
return $postFields;
261+
if ($previousChunkKey === '') {
262+
$parent = &$parent[0];
263+
} else {
264+
$parent = &$parent[$previousChunkKey];
270265
}
271266

272-
$chunkKey = rtrim($chunkKey, ']');
267+
$chunkKey = rtrim($chunks[$i], ']');
273268
if ($i == count($chunks) - 1) {
274-
$parent[$chunkKey] = $value;
275-
return $postFields;
269+
if ($chunkKey === '') {
270+
$parent[] = $value;
271+
} else {
272+
$parent[$chunkKey] = $value;
273+
}
276274
}
277275
}
278276

tests/Io/MultipartParserTest.php

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public function testEmptyPostValue()
5151
$data .= "\r\n";
5252
$data .= "--$boundary--\r\n";
5353

54-
5554
$request = new ServerRequest('POST', 'http://example.com/', array(
5655
'Content-Type' => 'multipart/mixed; boundary=' . $boundary,
5756
), $data, 1.1);
@@ -77,7 +76,6 @@ public function testEmptyPostKey()
7776
$data .= "value\r\n";
7877
$data .= "--$boundary--\r\n";
7978

80-
8179
$request = new ServerRequest('POST', 'http://example.com/', array(
8280
'Content-Type' => 'multipart/mixed; boundary=' . $boundary,
8381
), $data, 1.1);
@@ -93,6 +91,64 @@ public function testEmptyPostKey()
9391
);
9492
}
9593

94+
public function testNestedPostKeyAssoc()
95+
{
96+
$boundary = "---------------------------5844729766471062541057622570";
97+
98+
$data = "--$boundary\r\n";
99+
$data .= "Content-Disposition: form-data; name=\"a[b][c]\"\r\n";
100+
$data .= "\r\n";
101+
$data .= "value\r\n";
102+
$data .= "--$boundary--\r\n";
103+
104+
$request = new ServerRequest('POST', 'http://example.com/', array(
105+
'Content-Type' => 'multipart/mixed; boundary=' . $boundary,
106+
), $data, 1.1);
107+
108+
$parsedRequest = MultipartParser::parseRequest($request);
109+
110+
$this->assertEmpty($parsedRequest->getUploadedFiles());
111+
$this->assertSame(
112+
array(
113+
'a' => array(
114+
'b' => array(
115+
'c' => 'value'
116+
)
117+
)
118+
),
119+
$parsedRequest->getParsedBody()
120+
);
121+
}
122+
123+
public function testNestedPostKeyVector()
124+
{
125+
$boundary = "---------------------------5844729766471062541057622570";
126+
127+
$data = "--$boundary\r\n";
128+
$data .= "Content-Disposition: form-data; name=\"a[][]\"\r\n";
129+
$data .= "\r\n";
130+
$data .= "value\r\n";
131+
$data .= "--$boundary--\r\n";
132+
133+
$request = new ServerRequest('POST', 'http://example.com/', array(
134+
'Content-Type' => 'multipart/mixed; boundary=' . $boundary,
135+
), $data, 1.1);
136+
137+
$parsedRequest = MultipartParser::parseRequest($request);
138+
139+
$this->assertEmpty($parsedRequest->getUploadedFiles());
140+
$this->assertSame(
141+
array(
142+
'a' => array(
143+
array(
144+
'value'
145+
)
146+
)
147+
),
148+
$parsedRequest->getParsedBody()
149+
);
150+
}
151+
96152
public function testFileUpload()
97153
{
98154
$boundary = "---------------------------12758086162038677464950549563";

0 commit comments

Comments
 (0)