Fix #18789: Added JSONP support in yii\web\JsonParser::parse()

This commit is contained in:
Anton
2021-08-07 15:31:35 +03:00
committed by GitHub
parent 38ba100320
commit 7ebaaf0216
3 changed files with 33 additions and 2 deletions

View File

@ -21,6 +21,7 @@ Yii Framework 2 Change Log
- Enh #18734: Added `yii\validators\EmailValidator::$enableLocalIDN` (brandonkelly)
- Bug #18756: Fix `\yii\validators\ExistValidator::queryValueExists` to validate against an array of unique values (DrDeath72)
- Enh #18656: Added ability for `yii serve`'s `--router` param to take an alias (markhuot)
- Enh #18789: Added JSONP support in `yii\web\JsonParser::parse()` (WinterSilence)
- Bug #18274: Fix `yii\log\Logger` to calculate profile timings no matter the value of the flush interval (bizley)

View File

@ -33,7 +33,7 @@ class JsonParser implements RequestParserInterface
*/
public $asArray = true;
/**
* @var bool whether to throw a [[BadRequestHttpException]] if the body is invalid json
* @var bool whether to throw a [[BadRequestHttpException]] if the body is invalid JSON
*/
public $throwException = true;
@ -42,11 +42,16 @@ class JsonParser implements RequestParserInterface
* Parses a HTTP request body.
* @param string $rawBody the raw HTTP request body.
* @param string $contentType the content type specified for the request body.
* @return array parameters parsed from the request body
* @return array|\stdClass parameters parsed from the request body
* @throws BadRequestHttpException if the body contains invalid json and [[throwException]] is `true`.
*/
public function parse($rawBody, $contentType)
{
// converts JSONP to JSON
if (strpos($contentType, 'application/javascript') !== false) {
$rawBody = preg_filter('/(^[^{]+|[^}]+$)/', '', $rawBody);
}
try {
$parameters = Json::decode($rawBody, $this->asArray);
return $parameters === null ? [] : $parameters;

View File

@ -12,6 +12,7 @@ use yiiunit\TestCase;
/**
* @group web
* @backupGlobals enabled
*/
class RequestTest extends TestCase
{
@ -1049,6 +1050,30 @@ class RequestTest extends TestCase
$this->assertSame('default', $request->getBodyParam('unexisting', 'default'));
}
public function getBodyParamsDataProvider()
{
return [
'json' => ['application/json', '{"foo":"bar","baz":1}', ['foo' => 'bar', 'baz' => 1]],
'jsonp' => ['application/javascript', 'parseResponse({"foo":"bar","baz":1});', ['foo' => 'bar', 'baz' => 1]],
'get' => ['application/x-www-form-urlencoded', 'foo=bar&baz=1', ['foo' => 'bar', 'baz' => '1']],
];
}
/**
* @dataProvider getBodyParamsDataProvider
*/
public function testGetBodyParams($contentType, $rawBody, array $expected)
{
$_SERVER['CONTENT_TYPE'] = $contentType;
$request = new Request();
$request->parsers = [
'application/json' => 'yii\web\JsonParser',
'application/javascript' => 'yii\web\JsonParser',
];
$request->setRawBody($rawBody);
$this->assertSame($expected, $request->getBodyParams());
}
public function trustedHostAndInjectedXForwardedForDataProvider()
{
return [