From 399af275acdb5f4f881139f88a5b9d1910a8da75 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Tue, 24 Jan 2012 12:21:25 +0100 Subject: [PATCH] [Form] Implemented checks to assert that values and indices generated in choice lists match their requirements --- .../Extension/Core/ChoiceList/ChoiceList.php | 14 ++++++++- src/Symfony/Component/Form/Form.php | 29 ++++++++++++++----- .../Core/ChoiceList/ChoiceListTest.php | 28 ++++++++++++++++++ 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php index 261a96a66337..374a65543a1f 100644 --- a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php +++ b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php @@ -11,8 +11,10 @@ namespace Symfony\Component\Form\Extension\Core\ChoiceList; +use Symfony\Component\Form\Form; use Symfony\Component\Form\Util\FormUtil; use Symfony\Component\Form\Exception\UnexpectedTypeException; +use Symfony\Component\Form\Exception\InvalidConfigurationException; use Symfony\Component\Form\Extension\Core\View\ChoiceView; /** @@ -429,8 +431,18 @@ protected function addChoice(&$bucketForPreferred, &$bucketForRemaining, $choice { $index = $this->createIndex($choice); + if ('' === $index || null === $index || !Form::isValidName((string)$index)) { + throw new InvalidConfigurationException('The choice list index "' . $index . '" is invalid. Please set the choice field option "index_generation" to ChoiceList::GENERATE.'); + } + + $value = $this->createValue($choice); + + if (!is_scalar($value)) { + throw new InvalidConfigurationException('The choice list value of type "' . gettype($value) . '" should be a scalar. Please set the choice field option "value_generation" to ChoiceList::GENERATE.'); + } + // Always store values as strings to facilitate comparisons - $value = $this->fixValue($this->createValue($choice)); + $value = $this->fixValue($value); $view = new ChoiceView($value, $label); $this->choices[$index] = $this->fixChoice($choice); diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 9a9b58f2f2e8..5d5d8011ce81 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -1063,14 +1063,8 @@ private function clientToNorm($value) /** * Validates whether the given variable is a valid form name. * - * A name is accepted if it - * - * * is empty - * * starts with a letter, digit or underscore - * * contains only letters, digits, numbers, underscores ("_"), - * hyphens ("-") and colons (":") - * * @param string $name The tested form name. + * * @throws UnexpectedTypeException If the name is not a string. * @throws \InvalidArgumentException If the name contains invalid characters. */ @@ -1080,11 +1074,30 @@ static public function validateName($name) throw new UnexpectedTypeException($name, 'string'); } - if ($name !== '' && !preg_match('/^[a-zA-Z0-9_][a-zA-Z0-9_\-:]*$/D', $name)) { + if (!self::isValidName($name)) { throw new \InvalidArgumentException(sprintf( 'The name "%s" contains illegal characters. Names should start with a letter, digit or underscore and only contains letters, digits, numbers, underscores ("_"), hyphens ("-") and colons (":").', $name )); } } + + /** + * Returns whether the given variable contains a valid form name. + * + * A name is accepted if it + * + * * is empty + * * starts with a letter, digit or underscore + * * contains only letters, digits, numbers, underscores ("_"), + * hyphens ("-") and colons (":") + * + * @param string $name The tested form name. + * + * @return Boolean Whether the name is valid. + */ + static public function isValidName($name) + { + return $name === '' || preg_match('/^[a-zA-Z0-9_][a-zA-Z0-9_\-:]*$/D', $name); + } } diff --git a/tests/Symfony/Tests/Component/Form/Extension/Core/ChoiceList/ChoiceListTest.php b/tests/Symfony/Tests/Component/Form/Extension/Core/ChoiceList/ChoiceListTest.php index db37a5786877..7774b876c110 100644 --- a/tests/Symfony/Tests/Component/Form/Extension/Core/ChoiceList/ChoiceListTest.php +++ b/tests/Symfony/Tests/Component/Form/Extension/Core/ChoiceList/ChoiceListTest.php @@ -87,6 +87,34 @@ public function testInitNestedArray() ), $this->list->getRemainingViews()); } + /** + * @expectedException Symfony\Component\Form\Exception\InvalidConfigurationException + */ + public function testInitIndexCopyChoiceWithInvalidIndex() + { + new ChoiceList( + array('a.'), + array('A'), + array(), + ChoiceList::GENERATE, + ChoiceList::COPY_CHOICE + ); + } + + /** + * @expectedException Symfony\Component\Form\Exception\InvalidConfigurationException + */ + public function testInitValueCopyChoiceWithInvalidValue() + { + new ChoiceList( + array($this->obj1), + array('A'), + array(), + ChoiceList::COPY_CHOICE, + ChoiceList::GENERATE + ); + } + public function testGetIndicesForChoices() { $choices = array($this->obj2, $this->obj3);