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 handler4780210
[Form] Add a form error if post_max_size has been reached.
This commit is contained in:
commit
6ad5d31dd8
@ -151,8 +151,11 @@
|
|||||||
</service>
|
</service>
|
||||||
|
|
||||||
<!-- FormTypeHttpFoundationExtension -->
|
<!-- FormTypeHttpFoundationExtension -->
|
||||||
|
<service id="form.server_params" class="Symfony\Component\Form\Util\ServerParams" public="false"/>
|
||||||
|
|
||||||
<service id="form.type_extension.form.http_foundation" class="Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension">
|
<service id="form.type_extension.form.http_foundation" class="Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension">
|
||||||
<tag name="form.type_extension" alias="form" />
|
<tag name="form.type_extension" alias="form" />
|
||||||
|
<argument type="service" id="form.server_params"/>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<!-- FormTypeValidatorExtension -->
|
<!-- FormTypeValidatorExtension -->
|
||||||
|
@ -56,8 +56,7 @@ class FormType extends BaseType
|
|||||||
->setDataLocked($isDataOptionSet)
|
->setDataLocked($isDataOptionSet)
|
||||||
->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)
|
->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)
|
||||||
->setMethod($options['method'])
|
->setMethod($options['method'])
|
||||||
->setAction($options['action'])
|
->setAction($options['action']);
|
||||||
;
|
|
||||||
|
|
||||||
if ($options['trim']) {
|
if ($options['trim']) {
|
||||||
$builder->addEventSubscriber(new TrimListener());
|
$builder->addEventSubscriber(new TrimListener());
|
||||||
@ -170,25 +169,26 @@ class FormType extends BaseType
|
|||||||
));
|
));
|
||||||
|
|
||||||
$resolver->setDefaults(array(
|
$resolver->setDefaults(array(
|
||||||
'data_class' => $dataClass,
|
'data_class' => $dataClass,
|
||||||
'empty_data' => $emptyData,
|
'empty_data' => $emptyData,
|
||||||
'trim' => true,
|
'trim' => true,
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'read_only' => false,
|
'read_only' => false,
|
||||||
'max_length' => null,
|
'max_length' => null,
|
||||||
'pattern' => null,
|
'pattern' => null,
|
||||||
'property_path' => null,
|
'property_path' => null,
|
||||||
'mapped' => true,
|
'mapped' => true,
|
||||||
'by_reference' => true,
|
'by_reference' => true,
|
||||||
'error_bubbling' => $errorBubbling,
|
'error_bubbling' => $errorBubbling,
|
||||||
'label_attr' => array(),
|
'label_attr' => array(),
|
||||||
'virtual' => null,
|
'virtual' => null,
|
||||||
'inherit_data' => $inheritData,
|
'inherit_data' => $inheritData,
|
||||||
'compound' => true,
|
'compound' => true,
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
// According to RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt)
|
// According to RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt)
|
||||||
// section 4.2., empty URIs are considered same-document references
|
// section 4.2., empty URIs are considered same-document references
|
||||||
'action' => '',
|
'action' => '',
|
||||||
|
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
|
||||||
));
|
));
|
||||||
|
|
||||||
$resolver->setAllowedTypes(array(
|
$resolver->setAllowedTypes(array(
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Form\Extension\HttpFoundation;
|
namespace Symfony\Component\Form\Extension\HttpFoundation;
|
||||||
|
|
||||||
use Symfony\Component\Form\AbstractExtension;
|
use Symfony\Component\Form\AbstractExtension;
|
||||||
|
use Symfony\Component\Form\Util\ServerParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integrates the HttpFoundation component with the Form library.
|
* Integrates the HttpFoundation component with the Form library.
|
||||||
@ -20,10 +21,20 @@ use Symfony\Component\Form\AbstractExtension;
|
|||||||
*/
|
*/
|
||||||
class HttpFoundationExtension extends AbstractExtension
|
class HttpFoundationExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var ServerParams
|
||||||
|
*/
|
||||||
|
private $serverParams;
|
||||||
|
|
||||||
|
public function __construct(ServerParams $serverParams = null)
|
||||||
|
{
|
||||||
|
$this->serverParams = $serverParams;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadTypeExtensions()
|
protected function loadTypeExtensions()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
new Type\FormTypeHttpFoundationExtension(),
|
new Type\FormTypeHttpFoundationExtension($this->serverParams),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,10 @@
|
|||||||
namespace Symfony\Component\Form\Extension\HttpFoundation;
|
namespace Symfony\Component\Form\Extension\HttpFoundation;
|
||||||
|
|
||||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Form\FormError;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\RequestHandlerInterface;
|
use Symfony\Component\Form\RequestHandlerInterface;
|
||||||
|
use Symfony\Component\Form\Util\ServerParams;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,6 +26,19 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
*/
|
*/
|
||||||
class HttpFoundationRequestHandler implements RequestHandlerInterface
|
class HttpFoundationRequestHandler implements RequestHandlerInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var ServerParams
|
||||||
|
*/
|
||||||
|
private $serverParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ServerParams $serverParams = null)
|
||||||
|
{
|
||||||
|
$this->serverParams = $serverParams ?: new ServerParams();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -53,6 +68,25 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
|
|||||||
$data = $request->query->get($name);
|
$data = $request->query->get($name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Mark the form with an error if the uploaded size was too large
|
||||||
|
// This is done here and not in FormValidator because $_POST is
|
||||||
|
// empty when that error occurs. Hence the form is never submitted.
|
||||||
|
$contentLength = $this->serverParams->getContentLength();
|
||||||
|
$maxContentLength = $this->serverParams->getPostMaxSize();
|
||||||
|
|
||||||
|
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
|
||||||
|
// Submit the form, but don't clear the default values
|
||||||
|
$form->submit(null, false);
|
||||||
|
|
||||||
|
$form->addError(new FormError(
|
||||||
|
$form->getConfig()->getOption('post_max_size_message'),
|
||||||
|
null,
|
||||||
|
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
||||||
|
));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ('' === $name) {
|
if ('' === $name) {
|
||||||
$params = $request->request->all();
|
$params = $request->request->all();
|
||||||
$files = $request->files->all();
|
$files = $request->files->all();
|
||||||
|
@ -15,6 +15,7 @@ use Symfony\Component\Form\AbstractTypeExtension;
|
|||||||
use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener;
|
use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener;
|
||||||
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
|
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Form\Util\ServerParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
@ -31,10 +32,10 @@ class FormTypeHttpFoundationExtension extends AbstractTypeExtension
|
|||||||
*/
|
*/
|
||||||
private $requestHandler;
|
private $requestHandler;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct(ServerParams $serverParams = null)
|
||||||
{
|
{
|
||||||
$this->listener = new BindRequestListener();
|
$this->listener = new BindRequestListener();
|
||||||
$this->requestHandler = new HttpFoundationRequestHandler();
|
$this->requestHandler = new HttpFoundationRequestHandler($serverParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
namespace Symfony\Component\Form\Extension\Validator\Constraints;
|
namespace Symfony\Component\Form\Extension\Validator\Constraints;
|
||||||
|
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
|
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\ConstraintValidator;
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
|
|
||||||
@ -21,22 +20,6 @@ use Symfony\Component\Validator\ConstraintValidator;
|
|||||||
*/
|
*/
|
||||||
class FormValidator extends ConstraintValidator
|
class FormValidator extends ConstraintValidator
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var ServerParams
|
|
||||||
*/
|
|
||||||
private $serverParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a validator with the given server parameters.
|
|
||||||
*
|
|
||||||
* @param ServerParams $params The server parameters. Default
|
|
||||||
* parameters are created if null.
|
|
||||||
*/
|
|
||||||
public function __construct(ServerParams $params = null)
|
|
||||||
{
|
|
||||||
$this->serverParams = $params ?: new ServerParams();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -113,21 +96,6 @@ class FormValidator extends ConstraintValidator
|
|||||||
$form->getExtraData()
|
$form->getExtraData()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the form with an error if the uploaded size was too large
|
|
||||||
$length = $this->serverParams->getContentLength();
|
|
||||||
|
|
||||||
if ($form->isRoot() && null !== $length) {
|
|
||||||
$max = $this->serverParams->getPostMaxSize();
|
|
||||||
|
|
||||||
if (!empty($max) && $length > $max) {
|
|
||||||
$this->context->addViolation(
|
|
||||||
$config->getOption('post_max_size_message'),
|
|
||||||
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize()),
|
|
||||||
$length
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,7 +66,6 @@ class FormTypeValidatorExtension extends BaseValidatorExtension
|
|||||||
'invalid_message' => 'This value is not valid.',
|
'invalid_message' => 'This value is not valid.',
|
||||||
'invalid_message_parameters' => array(),
|
'invalid_message_parameters' => array(),
|
||||||
'extra_fields_message' => 'This form should not contain extra fields.',
|
'extra_fields_message' => 'This form should not contain extra fields.',
|
||||||
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$resolver->setNormalizers(array(
|
$resolver->setNormalizers(array(
|
||||||
|
@ -14,59 +14,6 @@ namespace Symfony\Component\Form\Extension\Validator\Util;
|
|||||||
/**
|
/**
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class ServerParams
|
class ServerParams extends \Symfony\Component\Form\Util\ServerParams
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Returns maximum post size in bytes.
|
|
||||||
*
|
|
||||||
* @return null|int The maximum post size in bytes
|
|
||||||
*/
|
|
||||||
public function getPostMaxSize()
|
|
||||||
{
|
|
||||||
$iniMax = strtolower($this->getNormalizedIniPostMaxSize());
|
|
||||||
|
|
||||||
if ('' === $iniMax) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$max = ltrim($iniMax, '+');
|
|
||||||
if (0 === strpos($max, '0x')) {
|
|
||||||
$max = intval($max, 16);
|
|
||||||
} elseif (0 === strpos($max, '0')) {
|
|
||||||
$max = intval($max, 8);
|
|
||||||
} else {
|
|
||||||
$max = intval($max);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (substr($iniMax, -1)) {
|
|
||||||
case 't': $max *= 1024;
|
|
||||||
case 'g': $max *= 1024;
|
|
||||||
case 'm': $max *= 1024;
|
|
||||||
case 'k': $max *= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the normalized "post_max_size" ini setting.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getNormalizedIniPostMaxSize()
|
|
||||||
{
|
|
||||||
return strtoupper(trim(ini_get('post_max_size')));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the content length of the request.
|
|
||||||
*
|
|
||||||
* @return mixed The request content length.
|
|
||||||
*/
|
|
||||||
public function getContentLength()
|
|
||||||
{
|
|
||||||
return isset($_SERVER['CONTENT_LENGTH'])
|
|
||||||
? (int) $_SERVER['CONTENT_LENGTH']
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Form;
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Form\Util\ServerParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A request handler using PHP's super globals $_GET, $_POST and $_SERVER.
|
* A request handler using PHP's super globals $_GET, $_POST and $_SERVER.
|
||||||
@ -20,6 +21,19 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
|||||||
*/
|
*/
|
||||||
class NativeRequestHandler implements RequestHandlerInterface
|
class NativeRequestHandler implements RequestHandlerInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var ServerParams
|
||||||
|
*/
|
||||||
|
private $serverParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ServerParams $params = null)
|
||||||
|
{
|
||||||
|
$this->serverParams = $params ?: new ServerParams();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The allowed keys of the $_FILES array.
|
* The allowed keys of the $_FILES array.
|
||||||
*
|
*
|
||||||
@ -62,6 +76,25 @@ class NativeRequestHandler implements RequestHandlerInterface
|
|||||||
$data = $_GET[$name];
|
$data = $_GET[$name];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Mark the form with an error if the uploaded size was too large
|
||||||
|
// This is done here and not in FormValidator because $_POST is
|
||||||
|
// empty when that error occurs. Hence the form is never submitted.
|
||||||
|
$contentLength = $this->serverParams->getContentLength();
|
||||||
|
$maxContentLength = $this->serverParams->getPostMaxSize();
|
||||||
|
|
||||||
|
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
|
||||||
|
// Submit the form, but don't clear the default values
|
||||||
|
$form->submit(null, false);
|
||||||
|
|
||||||
|
$form->addError(new FormError(
|
||||||
|
$form->getConfig()->getOption('post_max_size_message'),
|
||||||
|
null,
|
||||||
|
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
||||||
|
));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$fixedFiles = array();
|
$fixedFiles = array();
|
||||||
foreach ($_FILES as $name => $file) {
|
foreach ($_FILES as $name => $file) {
|
||||||
$fixedFiles[$name] = self::stripEmptyFiles(self::fixPhpFilesArray($file));
|
$fixedFiles[$name] = self::stripEmptyFiles(self::fixPhpFilesArray($file));
|
||||||
|
@ -11,21 +11,38 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Form\Tests;
|
namespace Symfony\Component\Form\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\FormError;
|
||||||
|
use Symfony\Component\Form\FormFactory;
|
||||||
|
use Symfony\Component\Form\Forms;
|
||||||
|
use Symfony\Component\Form\RequestHandlerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
|
abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \Symfony\Component\Form\RequestHandlerInterface
|
* @var RequestHandlerInterface
|
||||||
*/
|
*/
|
||||||
protected $requestHandler;
|
protected $requestHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FormFactory
|
||||||
|
*/
|
||||||
|
protected $factory;
|
||||||
|
|
||||||
protected $request;
|
protected $request;
|
||||||
|
|
||||||
|
protected $serverParams;
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
|
$this->serverParams = $this->getMock(
|
||||||
|
'Symfony\Component\Form\Util\ServerParams',
|
||||||
|
array('getNormalizedIniPostMaxSize', 'getContentLength')
|
||||||
|
);
|
||||||
$this->requestHandler = $this->getRequestHandler();
|
$this->requestHandler = $this->getRequestHandler();
|
||||||
|
$this->factory = Forms::createFormFactoryBuilder()->getFormFactory();
|
||||||
$this->request = null;
|
$this->request = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +266,50 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->requestHandler->handleRequest($form, $this->request);
|
$this->requestHandler->handleRequest($form, $this->request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getPostMaxSizeFixtures
|
||||||
|
*/
|
||||||
|
public function testAddFormErrorIfPostMaxSizeExceeded($contentLength, $iniMax, $shouldFail, array $errorParams = array())
|
||||||
|
{
|
||||||
|
$this->serverParams->expects($this->once())
|
||||||
|
->method('getContentLength')
|
||||||
|
->will($this->returnValue($contentLength));
|
||||||
|
$this->serverParams->expects($this->any())
|
||||||
|
->method('getNormalizedIniPostMaxSize')
|
||||||
|
->will($this->returnValue($iniMax));
|
||||||
|
|
||||||
|
$options = array('post_max_size_message' => 'Max {{ max }}!');
|
||||||
|
$form = $this->factory->createNamed('name', 'text', null, $options);
|
||||||
|
$this->setRequestData('POST', array(), array());
|
||||||
|
|
||||||
|
$this->requestHandler->handleRequest($form, $this->request);
|
||||||
|
|
||||||
|
if ($shouldFail) {
|
||||||
|
$errors = array(new FormError($options['post_max_size_message'], null, $errorParams));
|
||||||
|
|
||||||
|
$this->assertEquals($errors, $form->getErrors());
|
||||||
|
$this->assertTrue($form->isSubmitted());
|
||||||
|
} else {
|
||||||
|
$this->assertCount(0, $form->getErrors());
|
||||||
|
$this->assertFalse($form->isSubmitted());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPostMaxSizeFixtures()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(pow(1024, 3) + 1, '1G', true, array('{{ max }}' => '1G')),
|
||||||
|
array(pow(1024, 3), '1G', false),
|
||||||
|
array(pow(1024, 2) + 1, '1M', true, array('{{ max }}' => '1M')),
|
||||||
|
array(pow(1024, 2), '1M', false),
|
||||||
|
array(1024 + 1, '1K', true, array('{{ max }}' => '1K')),
|
||||||
|
array(1024, '1K', false),
|
||||||
|
array(null, '1K', false),
|
||||||
|
array(1024, '', false),
|
||||||
|
array(1024, 0, false),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
abstract protected function setRequestData($method, $data, $files = array());
|
abstract protected function setRequestData($method, $data, $files = array());
|
||||||
|
|
||||||
abstract protected function getRequestHandler();
|
abstract protected function getRequestHandler();
|
||||||
|
@ -43,7 +43,7 @@ class HttpFoundationRequestHandlerTest extends AbstractRequestHandlerTest
|
|||||||
|
|
||||||
protected function getRequestHandler()
|
protected function getRequestHandler()
|
||||||
{
|
{
|
||||||
return new HttpFoundationRequestHandler();
|
return new HttpFoundationRequestHandler($this->serverParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getMockFile()
|
protected function getMockFile()
|
||||||
|
@ -542,69 +542,6 @@ class FormValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
), 'property.path', array('foo' => 'bar'));
|
), 'property.path', array('foo' => 'bar'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider getPostMaxSizeFixtures
|
|
||||||
*/
|
|
||||||
public function testPostMaxSizeViolation($contentLength, $iniMax, $nbViolation, array $params = array())
|
|
||||||
{
|
|
||||||
$this->serverParams->expects($this->once())
|
|
||||||
->method('getContentLength')
|
|
||||||
->will($this->returnValue($contentLength));
|
|
||||||
$this->serverParams->expects($this->any())
|
|
||||||
->method('getNormalizedIniPostMaxSize')
|
|
||||||
->will($this->returnValue($iniMax));
|
|
||||||
|
|
||||||
$options = array('post_max_size_message' => 'Max {{ max }}!');
|
|
||||||
$form = $this->getBuilder('name', null, $options)->getForm();
|
|
||||||
|
|
||||||
$this->validator->validate($form, new Form());
|
|
||||||
|
|
||||||
$violations = array();
|
|
||||||
|
|
||||||
for ($i = 0; $i < $nbViolation; ++$i) {
|
|
||||||
$violations[] = $this->createViolation($options['post_max_size_message'], $params, 'property.path', $contentLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->assertViolations($violations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPostMaxSizeFixtures()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
array(pow(1024, 3) + 1, '1G', 1, array('{{ max }}' => '1G')),
|
|
||||||
array(pow(1024, 3), '1G', 0),
|
|
||||||
array(pow(1024, 2) + 1, '1M', 1, array('{{ max }}' => '1M')),
|
|
||||||
array(pow(1024, 2), '1M', 0),
|
|
||||||
array(1024 + 1, '1K', 1, array('{{ max }}' => '1K')),
|
|
||||||
array(1024, '1K', 0),
|
|
||||||
array(null, '1K', 0),
|
|
||||||
array(1024, '', 0),
|
|
||||||
array(1024, 0, 0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNoViolationIfNotRoot()
|
|
||||||
{
|
|
||||||
$this->serverParams->expects($this->once())
|
|
||||||
->method('getContentLength')
|
|
||||||
->will($this->returnValue(1025));
|
|
||||||
$this->serverParams->expects($this->never())
|
|
||||||
->method('getNormalizedIniPostMaxSize');
|
|
||||||
|
|
||||||
$parent = $this->getBuilder()
|
|
||||||
->setCompound(true)
|
|
||||||
->setDataMapper($this->getDataMapper())
|
|
||||||
->getForm();
|
|
||||||
$form = $this->getForm();
|
|
||||||
$parent->add($form);
|
|
||||||
|
|
||||||
$this->expectNoValidate();
|
|
||||||
|
|
||||||
$this->validator->validate($form, new Form());
|
|
||||||
|
|
||||||
$this->assertNoViolation();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access has to be public, as this method is called via callback array
|
* Access has to be public, as this method is called via callback array
|
||||||
* in {@link testValidateFormDataCanHandleCallbackValidationGroups()}
|
* in {@link testValidateFormDataCanHandleCallbackValidationGroups()}
|
||||||
|
@ -203,7 +203,7 @@ class NativeRequestHandlerTest extends AbstractRequestHandlerTest
|
|||||||
|
|
||||||
protected function getRequestHandler()
|
protected function getRequestHandler()
|
||||||
{
|
{
|
||||||
return new NativeRequestHandler();
|
return new NativeRequestHandler($this->serverParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getMockFile()
|
protected function getMockFile()
|
||||||
|
72
src/Symfony/Component/Form/Util/ServerParams.php
Normal file
72
src/Symfony/Component/Form/Util/ServerParams.php
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class ServerParams
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns maximum post size in bytes.
|
||||||
|
*
|
||||||
|
* @return null|int The maximum post size in bytes
|
||||||
|
*/
|
||||||
|
public function getPostMaxSize()
|
||||||
|
{
|
||||||
|
$iniMax = strtolower($this->getNormalizedIniPostMaxSize());
|
||||||
|
|
||||||
|
if ('' === $iniMax) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$max = ltrim($iniMax, '+');
|
||||||
|
if (0 === strpos($max, '0x')) {
|
||||||
|
$max = intval($max, 16);
|
||||||
|
} elseif (0 === strpos($max, '0')) {
|
||||||
|
$max = intval($max, 8);
|
||||||
|
} else {
|
||||||
|
$max = intval($max);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (substr($iniMax, -1)) {
|
||||||
|
case 't': $max *= 1024;
|
||||||
|
case 'g': $max *= 1024;
|
||||||
|
case 'm': $max *= 1024;
|
||||||
|
case 'k': $max *= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the normalized "post_max_size" ini setting.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getNormalizedIniPostMaxSize()
|
||||||
|
{
|
||||||
|
return strtoupper(trim(ini_get('post_max_size')));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content length of the request.
|
||||||
|
*
|
||||||
|
* @return mixed The request content length.
|
||||||
|
*/
|
||||||
|
public function getContentLength()
|
||||||
|
{
|
||||||
|
return isset($_SERVER['CONTENT_LENGTH'])
|
||||||
|
? (int) $_SERVER['CONTENT_LENGTH']
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user