@@ -215,8 +215,7 @@ public function testMultipartFormDataParsing()
215215 $ data .= "Content-Disposition: form-data; name= \"users[two] \"\r\n" ;
216216 $ data .= "\r\n" ;
217217 $ data .= "second \r\n" ;
218- $ data .= "-- $ boundary \r\n" ;
219-
218+ $ data .= "-- $ boundary-- \r\n" ;
220219
221220 $ request = new ServerRequest ('POST ' , 'http://example.com/ ' , array (
222221 'Content-Type ' => 'multipart/form-data; boundary= ' . $ boundary ,
@@ -241,4 +240,80 @@ function (ServerRequestInterface $request) {
241240 );
242241 $ this ->assertSame ($ data , (string )$ parsedRequest ->getBody ());
243242 }
243+
244+ public function testMultipartFormDataIgnoresFieldWithExcessiveNesting ()
245+ {
246+ // supported in all Zend PHP versions and HHVM
247+ // ini setting does exist everywhere but HHVM: https://3v4l.org/hXLiK
248+ // HHVM limits to 64 and otherwise returns an empty array structure
249+ $ allowed = (int )ini_get ('max_input_nesting_level ' );
250+ if ($ allowed === 0 ) {
251+ $ allowed = 64 ;
252+ }
253+
254+ $ middleware = new RequestBodyParserMiddleware ();
255+
256+ $ boundary = "---------------------------12758086162038677464950549563 " ;
257+
258+ $ data = "-- $ boundary \r\n" ;
259+ $ data .= "Content-Disposition: form-data; name= \"hello " . str_repeat ("[] " , $ allowed + 1 ) . "\"\r\n" ;
260+ $ data .= "\r\n" ;
261+ $ data .= "world \r\n" ;
262+ $ data .= "-- $ boundary-- \r\n" ;
263+
264+ $ request = new ServerRequest ('POST ' , 'http://example.com/ ' , array (
265+ 'Content-Type ' => 'multipart/form-data; boundary= ' . $ boundary ,
266+ ), $ data , 1.1 );
267+
268+ /** @var ServerRequestInterface $parsedRequest */
269+ $ parsedRequest = $ middleware (
270+ $ request ,
271+ function (ServerRequestInterface $ request ) {
272+ return $ request ;
273+ }
274+ );
275+
276+ $ this ->assertEmpty ($ parsedRequest ->getParsedBody ());
277+ }
278+
279+ public function testMultipartFormDataTruncatesBodyWithExcessiveLength ()
280+ {
281+ // ini setting exists in PHP 5.3.9, not in HHVM: https://3v4l.org/VF6oV
282+ // otherwise default to 1000 as implemented within
283+ $ allowed = (int )ini_get ('max_input_vars ' );
284+ if ($ allowed === 0 ) {
285+ $ allowed = 1000 ;
286+ }
287+
288+ $ middleware = new RequestBodyParserMiddleware ();
289+
290+ $ boundary = "---------------------------12758086162038677464950549563 " ;
291+
292+ $ data = "" ;
293+ for ($ i = 0 ; $ i < $ allowed + 1 ; ++$ i ) {
294+ $ data .= "-- $ boundary \r\n" ;
295+ $ data .= "Content-Disposition: form-data; name= \"a[] \"\r\n" ;
296+ $ data .= "\r\n" ;
297+ $ data .= "b \r\n" ;
298+ }
299+ $ data .= "-- $ boundary-- \r\n" ;
300+
301+ $ request = new ServerRequest ('POST ' , 'http://example.com/ ' , array (
302+ 'Content-Type ' => 'multipart/form-data; boundary= ' . $ boundary ,
303+ ), $ data , 1.1 );
304+
305+ /** @var ServerRequestInterface $parsedRequest */
306+ $ parsedRequest = $ middleware (
307+ $ request ,
308+ function (ServerRequestInterface $ request ) {
309+ return $ request ;
310+ }
311+ );
312+
313+ $ body = $ parsedRequest ->getParsedBody ();
314+
315+ $ this ->assertCount (1 , $ body );
316+ $ this ->assertTrue (isset ($ body ['a ' ]));
317+ $ this ->assertCount ($ allowed , $ body ['a ' ]);
318+ }
244319}
0 commit comments