Skip to content

Commit 13e4a7f

Browse files
authored
[9.x] Manually populate POST request body with JSON data only when required (#37921)
* Manually populate POST request body with JSON data only when required This fixes a 6 year old bug introduced in #7026 where GET requests would have GET data populated in the POST body property leading to issues around Request::post() and $request->getParsedBody() returning GET values when called on GET requests. This is a resubmit of #17087 & #36708, and fixes #22805. Credit to @dan-har for the initial solution and @mixlion for updating it for >=6.x. The original PR was meant to support POST requests where their Content-type was set to application/json (instead of the typical application/x-www-form-urlencoded), but it introduced a subtle and dangerous bug because while $request->getInputSource() does return the JSON data for JSON requests, it also returns the GET data for GET requests. This commit solves the underlying issue without breaking compatibility with the original functionality. * Add test for non-JSON GET requests * Style fixes * Extra space removal * GitHub's editor needs some work
1 parent 76b3417 commit 13e4a7f

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

src/Illuminate/Http/Request.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,9 @@ public static function createFromBase(SymfonyRequest $request)
432432

433433
$newRequest->content = $request->content;
434434

435-
$newRequest->request = $newRequest->getInputSource();
435+
if ($newRequest->isJson()) {
436+
$newRequest->request = $newRequest->json();
437+
}
436438

437439
return $newRequest;
438440
}

tests/Http/HttpRequestTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,12 @@ public function testFingerprintWithoutRoute()
10071007
$request->fingerprint();
10081008
}
10091009

1010-
public function testCreateFromBase()
1010+
/**
1011+
* Ensure JSON GET requests populate $request->request with the JSON content.
1012+
*
1013+
* @link https://github.com/laravel/framework/pull/7052 Correctly fill the $request->request parameter bag on creation.
1014+
*/
1015+
public function testJsonRequestFillsRequestBodyParams()
10111016
{
10121017
$body = [
10131018
'foo' => 'bar',
@@ -1025,6 +1030,24 @@ public function testCreateFromBase()
10251030
$this->assertEquals($request->request->all(), $body);
10261031
}
10271032

1033+
/**
1034+
* Ensure non-JSON GET requests don't pollute $request->request with the GET parameters.
1035+
*
1036+
* @link https://github.com/laravel/framework/pull/37921 Manually populate POST request body with JSON data only when required.
1037+
*/
1038+
public function testNonJsonRequestDoesntFillRequestBodyParams()
1039+
{
1040+
$params = ['foo' => 'bar'];
1041+
1042+
$getRequest = Request::create('/', 'GET', $params, [], [], []);
1043+
$this->assertEquals($getRequest->request->all(), []);
1044+
$this->assertEquals($getRequest->query->all(), $params);
1045+
1046+
$postRequest = Request::create('/', 'POST', $params, [], [], []);
1047+
$this->assertEquals($postRequest->request->all(), $params);
1048+
$this->assertEquals($postRequest->query->all(), []);
1049+
}
1050+
10281051
/**
10291052
* Tests for Http\Request magic methods `__get()` and `__isset()`.
10301053
*

0 commit comments

Comments
 (0)