From e7e61fdcc9aa8533630e79701cbf6260ec19530f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 27 Oct 2012 15:29:28 +0200 Subject: [PATCH] merged branch jfcixmedia/2.1 (PR #5838) This PR was squashed before being merged into the master branch (closes #5838). Commits ------- 201f3e6 [Form] Fixed cannot unset string offsets in CsrfValidationListener Discussion ---------- [Form] Fixed cannot unset string offsets in CsrfValidationListener Bug fix: yes Feature addition: no Backwards compatibility break: no Symfony2 tests pass: yes Fixes the following tickets: - Todo: - License of the code: MIT Documentation PR: - A php fatal error is happening when someone rewrite the entire form data for an object with a single input. ``` Fatal error: Cannot unset string offsets in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php on line 72 ``` Example: ```html

``` If someone alters the html to add a simple input at the bottom of the form like this one: ```html ``` The result will be a php fatal error. --------------------------------------------------------------------------- by bschussek at 2012-10-26T09:49:05Z Thank you for the pull request! Could you please reference the pull request in the test? ```php // https://github.com/symfony/symfony/pull/5838 public function testStringFormData() { ... ``` --------------------------------------------------------------------------- by jfcixmedia at 2012-10-26T10:21:29Z @bschussek Added, thanks. --- .../EventListener/CsrfValidationListener.php | 4 +- .../CsrfValidationListenerTest.php | 78 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php diff --git a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php index 345a7ea9a9..976312f78f 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php +++ b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php @@ -68,7 +68,9 @@ class CsrfValidationListener implements EventSubscriberInterface $form->addError(new FormError('The CSRF token is invalid. Please try to resubmit the form.')); } - unset($data[$this->fieldName]); + if (is_array($data)) { + unset($data[$this->fieldName]); + } } $event->setData($data); diff --git a/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php new file mode 100644 index 0000000000..65d649ab86 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\EventListener; + +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener; + +class CsrfValidationListenerTest extends \PHPUnit_Framework_TestCase +{ + protected $dispatcher; + protected $factory; + protected $csrfProvider; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); + $this->csrfProvider = $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'); + $this->form = $this->getBuilder('post') + ->setDataMapper($this->getDataMapper()) + ->getForm(); + } + + protected function tearDown() + { + $this->dispatcher = null; + $this->factory = null; + $this->csrfProvider = null; + $this->form = null; + } + + protected function getBuilder($name = 'name') + { + return new FormBuilder($name, null, $this->dispatcher, $this->factory, array('compound' => true)); + } + + protected function getForm($name = 'name') + { + return $this->getBuilder($name)->getForm(); + } + + protected function getDataMapper() + { + return $this->getMock('Symfony\Component\Form\DataMapperInterface'); + } + + protected function getMockForm() + { + return $this->getMock('Symfony\Component\Form\Tests\FormInterface'); + } + + // https://github.com/symfony/symfony/pull/5838 + public function testStringFormData() + { + $data = "XP4HUzmHPi"; + $event = new FormEvent($this->form, $data); + + $validation = new CsrfValidationListener('csrf', $this->csrfProvider, 'unknown'); + $validation->preBind($event); + + // Validate accordingly + $this->assertSame($data, $event->getData()); + } +}