diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml
index f20552ed18..5da44c464e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml
@@ -16,6 +16,7 @@
%form.type_extension.csrf.field_name%
%validator.translation_domain%
+
diff --git a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php
index 64378336e9..034f30612d 100644
--- a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php
+++ b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php
@@ -18,6 +18,7 @@ use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
+use Symfony\Component\Form\Util\ServerParams;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Translation\TranslatorInterface;
@@ -68,6 +69,11 @@ class CsrfValidationListener implements EventSubscriberInterface
*/
private $translationDomain;
+ /**
+ * @var ServerParams
+ */
+ private $serverParams;
+
public static function getSubscribedEvents()
{
return array(
@@ -75,7 +81,7 @@ class CsrfValidationListener implements EventSubscriberInterface
);
}
- public function __construct($fieldName, $tokenManager, $tokenId, $errorMessage, TranslatorInterface $translator = null, $translationDomain = null)
+ public function __construct($fieldName, $tokenManager, $tokenId, $errorMessage, TranslatorInterface $translator = null, $translationDomain = null, ServerParams $serverParams = null)
{
if ($tokenManager instanceof CsrfProviderInterface) {
$tokenManager = new CsrfProviderAdapter($tokenManager);
@@ -89,13 +95,15 @@ class CsrfValidationListener implements EventSubscriberInterface
$this->errorMessage = $errorMessage;
$this->translator = $translator;
$this->translationDomain = $translationDomain;
+ $this->serverParams = $serverParams ?: new ServerParams();
}
public function preSubmit(FormEvent $event)
{
$form = $event->getForm();
+ $postRequestSizeExceeded = $form->getConfig()->getMethod() === 'POST' && $this->serverParams->hasPostMaxSizeBeenExceeded();
- if ($form->isRoot() && $form->getConfig()->getOption('compound')) {
+ if ($form->isRoot() && $form->getConfig()->getOption('compound') && !$postRequestSizeExceeded) {
$data = $event->getData();
if (!isset($data[$this->fieldName]) || !$this->tokenManager->isTokenValid(new CsrfToken($this->tokenId, $data[$this->fieldName]))) {
diff --git a/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php b/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php
index 35d8648215..2a34ef0e9e 100644
--- a/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php
+++ b/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php
@@ -20,6 +20,7 @@ use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
+use Symfony\Component\Form\Util\ServerParams;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
@@ -55,7 +56,12 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
*/
private $translationDomain;
- public function __construct($defaultTokenManager, $defaultEnabled = true, $defaultFieldName = '_token', TranslatorInterface $translator = null, $translationDomain = null)
+ /**
+ * @var ServerParams
+ */
+ private $serverParams;
+
+ public function __construct($defaultTokenManager, $defaultEnabled = true, $defaultFieldName = '_token', TranslatorInterface $translator = null, $translationDomain = null, ServerParams $serverParams = null)
{
if ($defaultTokenManager instanceof CsrfProviderInterface) {
$defaultTokenManager = new CsrfProviderAdapter($defaultTokenManager);
@@ -68,6 +74,7 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
$this->defaultFieldName = $defaultFieldName;
$this->translator = $translator;
$this->translationDomain = $translationDomain;
+ $this->serverParams = $serverParams;
}
/**
@@ -89,7 +96,8 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
$options['csrf_token_id'] ?: ($builder->getName() ?: get_class($builder->getType()->getInnerType())),
$options['csrf_message'],
$this->translator,
- $this->translationDomain
+ $this->translationDomain,
+ $this->serverParams
))
;
}
diff --git a/src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php b/src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php
index 98bbd4b9ce..d1e5eece7b 100644
--- a/src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php
+++ b/src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php
@@ -73,10 +73,7 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
// 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) {
+ if ($this->serverParams->hasPostMaxSizeBeenExceeded()) {
// Submit the form, but don't clear the default values
$form->submit(null, false);
diff --git a/src/Symfony/Component/Form/NativeRequestHandler.php b/src/Symfony/Component/Form/NativeRequestHandler.php
index 36a7d7cff2..5541e96ad5 100644
--- a/src/Symfony/Component/Form/NativeRequestHandler.php
+++ b/src/Symfony/Component/Form/NativeRequestHandler.php
@@ -81,10 +81,7 @@ class NativeRequestHandler implements RequestHandlerInterface
// 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) {
+ if ($this->serverParams->hasPostMaxSizeBeenExceeded()) {
// Submit the form, but don't clear the default values
$form->submit(null, false);
diff --git a/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php
index 7206ceede7..4904b679dd 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Form\Tests\Extension\Csrf\EventListener;
+use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener;
@@ -72,4 +73,25 @@ class CsrfValidationListenerTest extends \PHPUnit_Framework_TestCase
// Validate accordingly
$this->assertSame($data, $event->getData());
}
+
+ public function testMaxPostSizeExceeded()
+ {
+ $serverParams = $this
+ ->getMockBuilder('\Symfony\Component\Form\Util\ServerParams')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ;
+
+ $serverParams
+ ->expects($this->once())
+ ->method('hasPostMaxSizeBeenExceeded')
+ ->willReturn(true)
+ ;
+
+ $event = new FormEvent($this->form, array('csrf' => 'token'));
+ $validation = new CsrfValidationListener('csrf', $this->tokenManager, 'unknown', 'Error message', null, null, $serverParams);
+
+ $validation->preSubmit($event);
+ $this->assertEmpty($this->form->getErrors());
+ }
}
diff --git a/src/Symfony/Component/Form/Util/ServerParams.php b/src/Symfony/Component/Form/Util/ServerParams.php
index c4da49db84..b9f5aaff55 100644
--- a/src/Symfony/Component/Form/Util/ServerParams.php
+++ b/src/Symfony/Component/Form/Util/ServerParams.php
@@ -25,6 +25,19 @@ class ServerParams
$this->requestStack = $requestStack;
}
+ /**
+ * Returns true if the POST max size has been exceeded in the request.
+ *
+ * @return bool
+ */
+ public function hasPostMaxSizeBeenExceeded()
+ {
+ $contentLength = $this->getContentLength();
+ $maxContentLength = $this->getPostMaxSize();
+
+ return $maxContentLength && $contentLength > $maxContentLength;
+ }
+
/**
* Returns maximum post size in bytes.
*