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) - Enh #18734: Added `yii\validators\EmailValidator::$enableLocalIDN` (brandonkelly)
- Bug #18756: Fix `\yii\validators\ExistValidator::queryValueExists` to validate against an array of unique values (DrDeath72) - 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 #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) - 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; 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; public $throwException = true;
@ -42,11 +42,16 @@ class JsonParser implements RequestParserInterface
* Parses a HTTP request body. * Parses a HTTP request body.
* @param string $rawBody the raw HTTP request body. * @param string $rawBody the raw HTTP request body.
* @param string $contentType the content type specified for the 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`. * @throws BadRequestHttpException if the body contains invalid json and [[throwException]] is `true`.
*/ */
public function parse($rawBody, $contentType) public function parse($rawBody, $contentType)
{ {
// converts JSONP to JSON
if (strpos($contentType, 'application/javascript') !== false) {
$rawBody = preg_filter('/(^[^{]+|[^}]+$)/', '', $rawBody);
}
try { try {
$parameters = Json::decode($rawBody, $this->asArray); $parameters = Json::decode($rawBody, $this->asArray);
return $parameters === null ? [] : $parameters; return $parameters === null ? [] : $parameters;

View File

@ -12,6 +12,7 @@ use yiiunit\TestCase;
/** /**
* @group web * @group web
* @backupGlobals enabled
*/ */
class RequestTest extends TestCase class RequestTest extends TestCase
{ {
@ -1049,6 +1050,30 @@ class RequestTest extends TestCase
$this->assertSame('default', $request->getBodyParam('unexisting', 'default')); $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() public function trustedHostAndInjectedXForwardedForDataProvider()
{ {
return [ return [