Skip to content

Commit

Permalink
merged branch pylebecq/2.2 (PR #8221)
Browse files Browse the repository at this point in the history
This PR was merged into the 2.2 branch.

Discussion
----------

[DomCrawler] Fixed a fatal error when setting a value in a malformed field name

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Hi,

I found a case where a fatal error happen when trying to set a value in a form field with a malformed name.

```
Fatal error: Call to a member function setValue() on a non-object in /home/pierreyves/projects/symfony2/symfony/src/Symfony/Component/DomCrawler/FormFieldRegistry.php on line 128

Call Stack:
    0.0001     231832   1. {main}() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/composer/bin/phpunit:0
    0.0035     688768   2. PHPUnit_TextUI_Command::main() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/composer/bin/phpunit:63
    0.0035     689000   3. PHPUnit_TextUI_Command->run() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:129
    0.0224    2705448   4. PHPUnit_TextUI_TestRunner->doRun() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:176
    0.0301    2997392   5. PHPUnit_Framework_TestSuite->run() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php:349
    0.0477    3613296   6. PHPUnit_Framework_TestSuite->runTest() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:745
    0.0477    3613296   7. PHPUnit_Framework_TestCase->run() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:775
    0.0477    3613296   8. PHPUnit_Framework_TestResult->run() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:776
    0.0478    3614208   9. PHPUnit_Framework_TestCase->runBare() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestResult.php:648
    0.0478    3630992  10. PHPUnit_Framework_TestCase->runTest() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:831
    0.0478    3631856  11. ReflectionMethod->invokeArgs() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
    0.0478    3631888  12. Symfony\Component\DomCrawler\Tests\FormTest->testSetValueOnMultiValuedFieldsWithMalformedName() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
    0.0481    3635560  13. Symfony\Component\DomCrawler\Form->offsetSet() /home/pierreyves/projects/symfony2/symfony/vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:255
    0.0481    3635560  14. Symfony\Component\DomCrawler\FormFieldRegistry->set() /home/pierreyves/projects/symfony2/symfony/src/Symfony/Component/DomCrawler/Form.php:320
```

In this case, `FormFieldRegistry::getSegments('foo[bar')` method is called and it will return `array('foo')` only. Therefore the return of `FormFieldRegistry::get('foo[bar')` returns an array instead of a `FormField` and so the `setValue()` call happen on the array which leads to the fatal error.

I tried to fix that. I don't know if it's the best way to do this so, as always, comments are welcome.

Commits
-------

bce6bd2 [DomCrawler] Fixed a fatal error when setting a value in a malformed field name.
  • Loading branch information
fabpot committed Jun 8, 2013
2 parents 18f55ff + bce6bd2 commit 1f26887
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/Symfony/Component/DomCrawler/FormFieldRegistry.php
Expand Up @@ -204,8 +204,12 @@ private function getSegments($name)
{
if (preg_match('/^(?P<base>[^[]+)(?P<extra>(\[.*)|$)/', $name, $m)) {
$segments = array($m['base']);
while (preg_match('/^\[(?P<segment>.*?)\](?P<extra>.*)$/', $m['extra'], $m)) {
$segments[] = $m['segment'];
while (!empty($m['extra'])) {
if (preg_match('/^\[(?P<segment>.*?)\](?P<extra>.*)$/', $m['extra'], $m)) {
$segments[] = $m['segment'];
} else {
throw new \InvalidArgumentException(sprintf('Malformed field path "%s"', $name));
}
}

return $segments;
Expand Down
12 changes: 12 additions & 0 deletions src/Symfony/Component/DomCrawler/Tests/FormTest.php
Expand Up @@ -247,6 +247,18 @@ public function testGetSetValue()
}
}

public function testSetValueOnMultiValuedFieldsWithMalformedName()
{
$form = $this->createForm('<form><input type="text" name="foo[bar]" value="bar" /><input type="text" name="foo[baz]" value="baz" /><input type="submit" /></form>');

try {
$form['foo[bar'] = 'bar';
$this->fail('->offsetSet() throws an \InvalidArgumentException exception if the name is malformed.');
} catch (\InvalidArgumentException $e) {
$this->assertTrue(true, '->offsetSet() throws an \InvalidArgumentException exception if the name is malformed.');
}
}

public function testOffsetUnset()
{
$form = $this->createForm('<form><input type="text" name="foo" value="foo" /><input type="submit" /></form>');
Expand Down

0 comments on commit 1f26887

Please sign in to comment.