mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 14:26:54 +08:00
Fix #17701: Throw BadRequetHttpException
when request params can’t be bound to bool
, int
, and float
controller action arguments
This commit is contained in:

committed by
Alexander Makarov

parent
3ef303968f
commit
40797c1139
@ -5,6 +5,7 @@ Yii Framework 2 Change Log
|
|||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
- Bug #17865: Fix invalid db component in `m180523_151638_rbac_updates_indexes_without_prefix` (rvkulikov)
|
- Bug #17865: Fix invalid db component in `m180523_151638_rbac_updates_indexes_without_prefix` (rvkulikov)
|
||||||
|
- Enh #17701: Throw `BadRequetHttpException` when request params can’t be bound to `bool`, `int`, and `float` controller action arguments (brandonkelly)
|
||||||
|
|
||||||
|
|
||||||
2.0.30 November 19, 2019
|
2.0.30 November 19, 2019
|
||||||
|
@ -128,15 +128,35 @@ class Controller extends \yii\base\Controller
|
|||||||
foreach ($method->getParameters() as $param) {
|
foreach ($method->getParameters() as $param) {
|
||||||
$name = $param->getName();
|
$name = $param->getName();
|
||||||
if (array_key_exists($name, $params)) {
|
if (array_key_exists($name, $params)) {
|
||||||
|
$isValid = true;
|
||||||
if ($param->isArray()) {
|
if ($param->isArray()) {
|
||||||
$args[] = $actionParams[$name] = (array) $params[$name];
|
$params[$name] = (array)$params[$name];
|
||||||
} elseif (!is_array($params[$name])) {
|
} elseif (is_array($params[$name])) {
|
||||||
$args[] = $actionParams[$name] = $params[$name];
|
$isValid = false;
|
||||||
} else {
|
} elseif (
|
||||||
|
PHP_VERSION_ID >= 70000 &&
|
||||||
|
($type = $param->getType()) !== null &&
|
||||||
|
$type->isBuiltin() &&
|
||||||
|
($params[$name] !== null || !$type->allowsNull())
|
||||||
|
) {
|
||||||
|
switch ((string)$type) {
|
||||||
|
case 'int':
|
||||||
|
$params[$name] = filter_var($params[$name], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
|
||||||
|
break;
|
||||||
|
case 'float':
|
||||||
|
$params[$name] = filter_var($params[$name], FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($params[$name] === null) {
|
||||||
|
$isValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$isValid) {
|
||||||
throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', [
|
throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', [
|
||||||
'param' => $name,
|
'param' => $name,
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
$args[] = $actionParams[$name] = $params[$name];
|
||||||
unset($params[$name]);
|
unset($params[$name]);
|
||||||
} elseif ($param->isDefaultValueAvailable()) {
|
} elseif ($param->isDefaultValueAvailable()) {
|
||||||
$args[] = $actionParams[$name] = $param->getDefaultValue();
|
$args[] = $actionParams[$name] = $param->getDefaultValue();
|
||||||
|
@ -32,6 +32,44 @@ class ControllerTest extends TestCase
|
|||||||
$this->assertEquals('avaliable', $other);
|
$this->assertEquals('avaliable', $other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://github.com/yiisoft/yii2/issues/17701
|
||||||
|
*/
|
||||||
|
public function testBindTypedActionParams()
|
||||||
|
{
|
||||||
|
if (PHP_VERSION_ID < 70000) {
|
||||||
|
$this->markTestSkipped('Can not be tested on PHP < 7.0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the PHP7 controller for this test
|
||||||
|
$this->controller = new FakePhp7Controller('fake', new \yii\web\Application([
|
||||||
|
'id' => 'app',
|
||||||
|
'basePath' => __DIR__,
|
||||||
|
|
||||||
|
'components' => [
|
||||||
|
'request' => [
|
||||||
|
'cookieValidationKey' => 'wefJDF8sfdsfSDefwqdxj9oq',
|
||||||
|
'scriptFile' => __DIR__ . '/index.php',
|
||||||
|
'scriptUrl' => '/index.php',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
$this->mockWebApplication(['controller' => $this->controller]);
|
||||||
|
|
||||||
|
$aksi1 = new InlineAction('aksi1', $this->controller, 'actionAksi1');
|
||||||
|
|
||||||
|
$params = ['foo' => '100', 'bar' => null];
|
||||||
|
list($foo, $bar) = $this->controller->bindActionParams($aksi1, $params);
|
||||||
|
$this->assertSame(100, $foo);
|
||||||
|
$this->assertSame(null, $bar);
|
||||||
|
|
||||||
|
$params = ['foo' => 'oops', 'bar' => null];
|
||||||
|
$this->expectException('yii\web\BadRequestHttpException');
|
||||||
|
$this->expectExceptionMessage('Invalid data received for parameter "foo".');
|
||||||
|
$this->controller->bindActionParams($aksi1, $params);
|
||||||
|
}
|
||||||
|
|
||||||
public function testAsJson()
|
public function testAsJson()
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
|
23
tests/framework/web/FakePhp7Controller.php
Normal file
23
tests/framework/web/FakePhp7Controller.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace yiiunit\framework\web;
|
||||||
|
|
||||||
|
use yii\web\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brandon Kelly <branodn@craftcms.com>
|
||||||
|
* @since 2.0.31
|
||||||
|
*/
|
||||||
|
class FakePhp7Controller extends Controller
|
||||||
|
{
|
||||||
|
public $enableCsrfValidation = false;
|
||||||
|
|
||||||
|
public function actionAksi1(int $foo, float $bar = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user