8000 [Form] Moved POST_MAX_SIZE validation from FormValidator to request h… · symfony/symfony@b7ead29 · GitHub
[go: up one dir, main page]

Skip to content

Commit b7ead29

Browse files
committed
[Form] Moved POST_MAX_SIZE validation from FormValidator to request handler
1 parent 4780210 commit b7ead29

File tree

14 files changed

+204
-193
lines changed

14 files changed

+204
-193
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' F438 => 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+
/**
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: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
namespace Symfony\Component\Form\Extension\HttpFoundation;
1313

1414
use Symfony\Component\Form\Exception\UnexpectedTypeException;
15-
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
1615
use Symfony\Component\Form\FormError;
1716
use Symfony\Component\Form\FormInterface;
1817
use Symfony\Component\Form\RequestHandlerInterface;
18+
use Symfony\Component\Form\Util\ServerParams;
1919
use Symfony\Component\HttpFoundation\Request;
2020

2121
/**
@@ -34,9 +34,9 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
3434
/**
3535
* {@inheritdoc}
3636
*/
37-
public function __construct(ServerParams $params = null)
37+
public function __construct(ServerParams $serverParams = null)
3838
{
39-
$this->serverParams = $params ?: new ServerParams();
39+
$this->serverParams = $serverParams ?: new ServerParams();
4040
}
4141

4242
/**
@@ -68,6 +68,25 @@ public function handleRequest(FormInterface $form, $request = null)
6868
$data = $request->query->get($name);
6969
}
7070
} 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+
7190
if ('' === $name) {
7291
$params = $request->request->all();
7392
$files = $request->files->all();
@@ -76,10 +95,6 @@ public function handleRequest(FormInterface $form, $request = null)
7695
$params = $request->request->get($name, $default);
7796
$files = $request->files->get($name, $default);
7897
} else {
79-
if ($this->serverParams->getContentLength() > $this->serverParams->getPostMaxSize()) {
80-
$form->addError(new FormError('Max post size exceeded.'));
81-
}
82-
8398
// Don't submit the form if it is not present in the request
8499
return;
85100
}

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: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,60 +13,10 @@
1313

1414
/**
1515
* @author Bernhard Schussek <bschussek@gmail.com>
16+
*
17+
* @deprecated To be removed in Symfony 3.0. Use {@link \Symfony\Component\Form\Util\ServerParams}
18+
* instead.
1619
*/
17-
class ServerParams
20+
class ServerParams extends \Symfony\Component\Form\Util\ServerParams
1821
{
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-
}
7222
}

src/Symfony/Component/Form/NativeRequestHandler.php

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

1414
use Symfony\Component\Form\Exception\UnexpectedTypeException;
15-
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
15+
use Symfony\Component\Form\Util\ServerParams;
1616

1717
/**
1818
* A request handler using PHP's super globals $_GET, $_POST and $_SERVER.
@@ -76,6 +76,25 @@ public function handleRequest(FormInterface $form, $request = null)
7676
$data = $_GET[$name];
7777
}
7878
} 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+
7998
$fixedFiles = array();
8099
foreach ($_FILES as $name => $file) {
81100
$fixedFiles[$name] = self::stripEmptyFiles(self::fixPhpFilesArray($file));
@@ -89,10 +108,6 @@ public function handleRequest(FormInterface $form, $request = null)
89108
$params = array_key_exists($name, $_POST) ? $_POST[$name] : $default;
90109
$files = array_key_exists($name, $fixedFiles) ? $fixedFiles[$name] : $default;
91110
} else {
92-
if ($this->serverParams->getContentLength() > $this->serverParams->getPostMaxSize()) {
93-
$form->addError(new FormError('Max post size exceeded.'));
94-
}
95-
96111
// Don't submit the form if it is not present in the request
97112
return;
98113
}

0 commit comments

Comments
 (0)
0