8000 bug #11924 [Form] Moved POST_MAX_SIZE validation from FormValidator t… · symfony/symfony@6ad5d31 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6ad5d31

Browse files
committed
bug #11924 [Form] Moved POST_MAX_SIZE validation from FormValidator to request handler (rpg600, webmozart)
This PR was merged into the 2.3 branch. Discussion ---------- [Form] Moved POST_MAX_SIZE validation from FormValidator to request handler | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #11729, #11877 | License | MIT | Doc PR | - Commits ------- 759ae1a [Form] Moved POST_MAX_SIZE validation from FormValidator to request handler 4780210 [Form] Add a form error if post_max_size has been reached.
2 parents c3feed6 + 759ae1a commit 6ad5d31

File tree

14 files changed

+241
-175
lines changed

14 files changed

+241
-175
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,11 @@
151151
</service>
152152

153153
<!-- FormTypeHttpFoundationExtension -->
154+
<service id="form.server_params" class="Symfony\Component\Form\Util\ServerParams" public="false"/>
155+
154156
<service id="form.type_extension.form.http_foundation" class="Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension">
155157
<tag name="form.type_extension" alias="form" />
158+
<argument type="service" id="form.server_params"/>
156159
</service>
157160

158161
<!-- FormTypeValidatorExtension -->

src/Symfony/Component/Form/Extension/Core/Type/FormType.php

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
5656
->setDataLocked($isDataOptionSet)
5757
->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)
5858
->setMethod($options['method'])
59-
->setAction($options['action'])
60-
;
59+
->setAction($options['action']);
6160

6261
if ($options['trim']) {
6362
$builder->addEventSubscriber(new TrimListener());
@@ -170,25 +169,26 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
170169
));
171170

172171
$resolver->setDefaults(array(
173-
'data_class' => $dataClass,
174-
'empty_data' => $emptyData,
175-
'trim' => true,
176-
'required' => true,
177-
'read_only' => false,
178-
'max_length' => null,
179-
'pattern' => null,
180-
'property_path' => null,
181-
'mapped' => true,
182-
'by_reference' => true,
183-
'error_bubbling' => $errorBubbling,
184-
'label_attr' => array(),
185-
'virtual' => null,
186-
'inherit_data' => $inheritData,
187-
'compound' => true,
188-
'method' => 'POST',
172+
'data_class' => $dataClass,
173+
'empty_data' => $emptyData,
174+
'trim' => true,
175+
'required' => true,
176+
'read_only' => false,
177+
'max_length' => null,
178+
'pattern' => null,
179+
'property_path' => null,
180+
'mapped' => true,
181+
'by_reference' => true,
182+
'error_bubbling' => $errorBubbling,
183+
'label_attr' => array(),
184+
'virtual' => null,
185+
'inherit_data' => $inheritData,
186+
'compound' => true,
187+
'method' => 'POST',
189188
// According to RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt)
190189
// section 4.2., empty URIs are considered same-document references
191-
'action' => '',
190+
'action' => '',
191+
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
192192
));
193193

194194
$resolver->setAllowedTypes(array(

src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationExtension.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\HttpFoundation;
1313

1414
use Symfony\Component\Form\AbstractExtension;
15+
use Symfony\Component\Form\Util\ServerParams;
1516

1617
/**
1718
* Integrates the HttpFoundation component with the Form library.
@@ -20,10 +21,20 @@
2021
*/
2122
class HttpFoundationExtension extends AbstractExtension
2223
{
24 10000 +
/**
25+
* @var ServerParams
26+
*/
27+
private $serverParams;
28+
29+
public function __construct(ServerParams $serverParams = null)
30+
{
31+
$this->serverParams = $serverParams;
32+
}
33+
2334
protected function loadTypeExtensions()
2435
{
2536
return array(
26-
new Type\FormTypeHttpFoundationExtension(),
37+
new Type\FormTypeHttpFoundationExtension($this->serverParams),
2738
);
2839
}
2940
}

src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
namespace Symfony\Component\Form\Extension\HttpFoundation;
1313

1414
use Symfony\Component\Form\Exception\UnexpectedTypeException;
15+
use Symfony\Component\Form\FormError;
1516
use Symfony\Component\Form\FormInterface;
1617
use Symfony\Component\Form\RequestHandlerInterface;
18+
use Symfony\Component\Form\Util\ServerParams;
1719
use Symfony\Component\HttpFoundation\Request;
1820

1921
/**
@@ -24,6 +26,19 @@
2426
*/
2527
class HttpFoundationRequestHandler implements RequestHandlerInterface
2628
{
29+
/**
30+
* @var ServerParams
31+
*/
32+
private $serverParams;
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function __construct(ServerParams $serverParams = null)
38+
{
39+
$this->serverParams = $serverParams ?: new ServerParams();
40+
}
41+
2742
/**
2843
* {@inheritdoc}
2944
*/
@@ -53,6 +68,25 @@ public function handleRequest(FormInterface $form, $request = null)
5368
$data = $request->query->get($name);
5469
}
5570
} else {
71+
// Mark the form with an error if the uploaded size was too large
72+
// This is done here and not in FormValidator because $_POST is
73+
// empty when that error occurs. Hence the form is never submitted.
74+
$contentLength = $this->serverParams->getContentLength();
75+
$maxContentLength = $this->serverParams->getPostMaxSize();
76+
77+
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
78+
// Submit the form, but don't clear the default values
79+
$form->submit(null, false);
80+
81+
$form->addError(new FormError(
82+
$form->getConfig()->getOption('post_max_size_message'),
83+
null,
84+
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
85+
));
86+
87+
return;
88+
}
89+
5690
if ('' === $name) {
5791
$params = $request->request->all();
5892
$files = $request->files->all();

src/Symfony/Component/Form/Extension/HttpFoundation/Type/FormTypeHttpFoundationExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener;
1616
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
1717
use Symfony\Component\Form\FormBuilderInterface;
18+
use Symfony\Component\Form\Util\ServerParams;
1819

1920
/**
2021
* @author Bernhard Schussek <bschussek@gmail.com>
@@ -31,10 +32,10 @@ class FormTypeHttpFoundationExtension extends AbstractTypeExtension
3132
*/
3233
private $requestHandler;
3334

34-
public function __construct()
35+
public function __construct(ServerParams $serverParams = null)
3536
{
3637
$this->listener = new BindRequestListener();
37-
$this->requestHandler = new HttpFoundationRequestHandler();
38+
$this->requestHandler = new HttpFoundationRequestHandler($serverParams);
3839
}
3940

4041
/**

src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\Form\Extension\Validator\Constraints;
1313

1414
use Symfony\Component\Form\FormInterface;
15-
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
1615
use Symfony\Component\Validator\Constraint;
1716
use Symfony\Component\Validator\ConstraintValidator;
1817

@@ -21,22 +20,6 @@
2120
*/
2221
class FormValidator extends ConstraintValidator
2322
{
24-
/**
25-
* @var ServerParams
26-
*/
27-
private $serverParams;
28-
29-
/**
30-
* Creates a validator with the given server parameters.
31-
*
32-
* @param ServerParams $params The server parameters. Default
33-
* parameters are created if null.
34-
*/
35-
public function __construct(ServerParams $params = null)
36-
{
37-
$this->serverParams = $params ?: new ServerParams();
38-
}
39-
4023
/**
4124
* {@inheritdoc}
4225
*/
@@ -113,21 +96,6 @@ public function validate($form, Constraint $constraint)
11396
$form->getExtraData()
11497
);
11598
}
116-
117-
// Mark the form with an error if the uploaded size was too large
118-
$length = $this->serverParams->getContentLength();
119-
120-
if ($form->isRoot() && null !== $length) {
121-
$max = $this->serverParams->getPostMaxSize();
122-
123-
if (!empty($max) && $length > $max) {
124-
$this->context->addViolation(
125-
$config->getOption('post_max_size_message'),
126-
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize()),
127-
$length
128-
);
129-
}
130-
}
13199
}
132100

133101
/**

src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
6666
'invalid_message' => 'This value is not valid.',
6767
'invalid_message_parameters' => array(),
6868
'extra_fields_message' => 'This form should not contain extra fields.',
69-
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
7069
));
7170

7271
$resolver->setNormalizers(array(

src/Symfony/Component/Form/Extension/Validator/Util/ServerParams.php

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,59 +14,6 @@
1414
/**
1515
* @author Bernhard Schussek <bschussek@gmail.com>
1616
*/
17-
class ServerParams
17+
class ServerParams extends \Symfony\Component\Form\Util\ServerParams
1818
{
19-
/**
20-
* Returns maximum post size in bytes.
21-
*
22-
* @return null|int The maximum post size in bytes
23-
*/
24-
public function getPostMaxSize()
25-
{
26-
$iniMax = strtolower($this->getNormalizedIniPostMaxSize());
27-
28-
if ('' === $iniMax) {
29-
return;
30-
}
31-
32-
$max = ltrim($iniMax, '+');
33-
if (0 === strpos($max, '0x')) {
34-
$max = intval($max, 16);
35-
} elseif (0 === strpos($max, '0')) {
36-
$max = intval($max, 8);
37-
} else {
38-
$max = intval($max);
39-
}
40-
41-
switch (substr($iniMax, -1)) {
42-
case 't': $max *= 1024;
43-
case 'g': $max *= 1024;
44-
case 'm': $max *= 1024;
45-
case 'k': $max *= 1024;
46-
}
47-
48-
return $max;
49-
}
50-
51-
/**
52-
* Returns the normalized "post_max_size" ini setting.
53-
*
54-
* @return string
55-
*/
56-
public function getNormalizedIniPostMaxSize()
57-
{
58-
return strtoupper(trim(ini_get('post_max_size')));
59-
}
60-
61-
/**
62-
* Returns the content length of the request.
63-
*
64-
* @return mixed The request content length.
65-
*/
66-
public function getContentLength()
67-
{
68-
return isset($_SERVER['CONTENT_LENGTH'])
69-
? (int) $_SERVER['CONTENT_LENGTH']
70-
: null;
71-
}
7219
}

src/Symfony/Component/Form/NativeRequestHandler.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form;
1313

1414
use Symfony\Component\Form\Exception\UnexpectedTypeException;
15+
use Symfony\Component\Form\Util\ServerParams;
1516

1617
/**
1718
* A request handler using PHP's super globals $_GET, $_POST and $_SERVER.
@@ -20,6 +21,19 @@
2021
*/
2122
class NativeRequestHandler implements RequestHandlerInterface
2223
{
24+
/**
25+
* @var ServerParams
26+
*/
27+
private $serverParams;
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
public function __construct(ServerParams $params = null)
33+
{
34+
$this->serverParams = $params ?: new ServerParams();
35+
}
36+
2337
/**
2438
* The allowed keys of the $_FILES array.
2539
*
@@ -62,6 +76,25 @@ public function handleRequest(FormInterface $form, $request = null)
6276
$data = $_GET[$name];
6377
}
6478
} else {
79+
// Mark the form with an error if the uploaded size was too large
80+
// This is done here and not in FormValidator because $_POST is
81+
// empty when that error occurs. Hence the form is never submitted.
82+
$contentLength = $this->serverParams->getContentLength();
83+
$maxContentLength = $this->serverParams->getPostMaxSize();
84+
85+
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
86+
// Submit the form, but don't clear the default values
87+
$form->submit(null, false);
88+
89+
$form->addError(new FormError(
90+
$form->getConfig()->getOption('post_max_size_message'),
91+
null,
92+
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
93+
));
94+
95+
return;
96+
}
97+
6598
$fixedFiles = array();
6699
foreach ($_FILES as $name => $file) {
67100
$fixedFiles[$name] = self::stripEmptyFiles(self::fixPhpFilesArray($file));

0 commit comments

Comments
 (0)
0