Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 07701bc

Browse files
Refactor: use ParameterBag::filter() for scalar type validation in RequestAttributeValueResolver
1 parent 736e9dd commit 07701bc

4 files changed

Lines changed: 61 additions & 10 deletions

File tree

src/Symfony/Bundle/FrameworkBundle/Resources/config/web.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DateTimeValueResolver;
2121
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver;
2222
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\QueryParameterValueResolver;
23-
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeScalarValueResolver;
2423
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeValueResolver;
2524
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestPayloadValueResolver;
2625
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestValueResolver;
@@ -56,9 +55,6 @@
5655
abstract_arg('targeted value resolvers'),
5756
])
5857

59-
->set('argument_resolver.request_attribute_scalar', RequestAttributeScalarValueResolver::class)
60-
->tag('controller.argument_value_resolver', ['priority' => 150, 'name' => RequestAttributeScalarValueResolver::class])
61-
6258
->set('argument_resolver.backed_enum_resolver', BackedEnumValueResolver::class)
6359
->tag('controller.argument_value_resolver', ['priority' => 100, 'name' => BackedEnumValueResolver::class])
6460

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ public function getArguments(Request $request, callable $controller, ?\Reflectio
131131
public static function getDefaultArgumentValueResolvers(): iterable
132132
{
133133
return [
134-
new ArgumentResolver\RequestAttributeScalarValueResolver(),
135134
new RequestAttributeValueResolver(),
136135
new RequestValueResolver(),
137136
new SessionValueResolver(),

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributeValueResolver.php

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\HttpFoundation\Request;
1515
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
1616
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
17+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1718

1819
/**
1920
* Yields a non-variadic argument's value from the request attributes.
@@ -24,6 +25,61 @@ final class RequestAttributeValueResolver implements ValueResolverInterface
2425
{
2526
public function resolve(Request $request, ArgumentMetadata $argument): array
2627
{
27-
return !$argument->isVariadic() && $request->attributes->has($argument->getName()) ? [$request->attributes->get($argument->getName())] : [];
28+
if ($argument->isVariadic()) {
29+
return [];
30+
}
31+
32+
$name = $argument->getName();
33+
if (!$request->attributes->has($name)) {
34+
return [];
35+
}
36+
37+
$type = $argument->getType();
38+
39+
// Skip when no type declaration or complex types; fall back to other resolvers/defaults
40+
if (null === $type || str_contains($type, '|') || str_contains($type, '&')) {
41+
return [$value];
42+
}
43+
44+
// Let the dedicated resolver handle backed enums
45+
if (is_subclass_of($type, \BackedEnum::class, true)) {
46+
return [];
47+
}
48+
49+
// Only enforce safe casting for int/float/bool here using ParameterBag::filter()
50+
switch ($type) {
51+
case 'int':
52+
$filtered = $request->attributes->filter($name, null, \FILTER_VALIDATE_INT, [
53+
'flags' => \FILTER_NULL_ON_FAILURE | \FILTER_REQUIRE_SCALAR,
54+
]);
55+
if (null === $filtered) {
56+
throw new NotFoundHttpException(\sprintf('The value for the "%s" route parameter is invalid.', $name));
57+
}
58+
59+
return [$filtered];
60+
61+
case 'float':
62+
$filtered = $request->attributes->filter($name, null, \FILTER_VALIDATE_FLOAT, [
63+
'flags' => \FILTER_NULL_ON_FAILURE | \FILTER_REQUIRE_SCALAR,
64+
]);
65+
if (null === $filtered) {
66+
throw new NotFoundHttpException(\sprintf('The value for the "%s" route parameter is invalid.', $name));
67+
}
68+
69+
return [$filtered];
70+
71+
case 'bool':
72+
$filtered = $request->attributes->filter($name, null, \FILTER_VALIDATE_BOOL, [
73+
'flags' => \FILTER_NULL_ON_FAILURE | \FILTER_REQUIRE_SCALAR,
74+
]);
75+
if (null === $filtered) {
76+
throw new NotFoundHttpException(\sprintf('The value for the "%s" route parameter is invalid.', $name));
77+
}
78+
79+
return [$filtered];
80+
}
81+
82+
// Strings and any other types: keep default behavior
83+
return [$request->attributes->get($name)];
2884
}
2985
}

src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestAttributeScalarValueResolverTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\HttpFoundation\Request;
16-
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeScalarValueResolver;
16+
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeValueResolver;
1717
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
1818
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1919

2020
class RequestAttributeScalarValueResolverTest extends TestCase
2121
{
2222
public function testValidIntWithinRangeWorks()
2323
{
24-
$resolver = new RequestAttributeScalarValueResolver();
24+
$resolver = new RequestAttributeValueResolver();
2525
$request = new Request();
2626
$request->attributes->set('id', '123');
2727
$metadata = new ArgumentMetadata('id', 'int', false, false, null);
@@ -33,7 +33,7 @@ public function testValidIntWithinRangeWorks()
3333

3434
public function testInvalidStringBecomes404()
3535
{
36-
$resolver = new RequestAttributeScalarValueResolver();
36+
$resolver = new RequestAttributeValueResolver();
3737
$request = new Request();
3838
$request->attributes->set('id', 'abc');
3939
$metadata = new ArgumentMetadata('id', 'int', false, false, null);
@@ -44,7 +44,7 @@ public function testInvalidStringBecomes404()
4444

4545
public function testOutOfRangeIntBecomes404()
4646
{
47-
$resolver = new RequestAttributeScalarValueResolver();
47+
$resolver = new RequestAttributeValueResolver();
4848
$request = new Request();
4949
// one more than PHP_INT_MAX on 64-bit (string input)
5050
$request->attributes->set('id', '9223372036854775808');

0 commit comments

Comments
 (0)