diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index a18e2384..aeecdb97 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -131,7 +131,8 @@ require 'HTMLPurifier/ConfigSchema/StringHashAdapter.php'; require 'HTMLPurifier/ConfigSchema/StringHashParser.php'; require 'HTMLPurifier/ConfigSchema/StringHashReverseAdapter.php'; require 'HTMLPurifier/ConfigSchema/Validator.php'; -require 'HTMLPurifier/ConfigSchema/Validator/IdExists.php'; +require 'HTMLPurifier/ConfigSchema/Validator/Alnum.php'; +require 'HTMLPurifier/ConfigSchema/Validator/Exists.php'; require 'HTMLPurifier/DefinitionCache/Decorator.php'; require 'HTMLPurifier/DefinitionCache/Null.php'; require 'HTMLPurifier/DefinitionCache/Serializer.php'; diff --git a/library/HTMLPurifier/ConfigSchema/Interchange.php b/library/HTMLPurifier/ConfigSchema/Interchange.php index 09f49fa6..ce4ab741 100644 --- a/library/HTMLPurifier/ConfigSchema/Interchange.php +++ b/library/HTMLPurifier/ConfigSchema/Interchange.php @@ -55,7 +55,13 @@ class HTMLPurifier_ConfigSchema_Interchange */ public function getValidatorAdapter() { $validator = new HTMLPurifier_ConfigSchema_InterchangeValidator($this); - $validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_IdExists()); + // Common validators + $validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Exists('ID')); + $validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Exists('DESCRIPTION')); + // Namespace validators + + // Directive validators + return $validator; } diff --git a/library/HTMLPurifier/ConfigSchema/InterchangeValidator.php b/library/HTMLPurifier/ConfigSchema/InterchangeValidator.php index 55a83bc6..9dd3fe42 100644 --- a/library/HTMLPurifier/ConfigSchema/InterchangeValidator.php +++ b/library/HTMLPurifier/ConfigSchema/InterchangeValidator.php @@ -7,6 +7,9 @@ class HTMLPurifier_ConfigSchema_InterchangeValidator { protected $interchange; protected $validators = array(); + protected $namespaceValidators = array(); + protected $directiveVaildators = array(); + protected $index = 0; /** * @param $interchange Instance of HTMLPurifier_ConfigSchema_Interchange @@ -20,15 +23,32 @@ class HTMLPurifier_ConfigSchema_InterchangeValidator * Registers a HTMLPurifier_ConfigSchema_Validator to run when adding. */ public function addValidator($validator) { - $this->validators[] = $validator; + $this->validators[$this->index++] = $validator; + } + + /** + * Register validators to be used only on directives + */ + public function addDirectiveValidator($validator) { + $this->directiveValidators[$this->index++] = $validator; + } + + /** + * Register validators to be used only on namespaces + */ + public function addNamespaceValidator($validator) { + $this->namespaceValidators[$this->index++] = $validator; } /** * Validates and adds a namespace hash */ public function addNamespace($hash) { - foreach ($this->validators as $validator) { - $validator->validateNamespace($hash, $this->interchange); + for ($i = 0; $i < $this->index; $i++) { + if (isset($this->validators[$i])) $validator = $this->validators[$i]; + elseif (isset($this->namespaceValidators[$i])) $validator = $this->namespaceValidators[$i]; + else continue; + $validator->validate($hash, $this->interchange); } $this->interchange->addNamespace($hash); } @@ -37,8 +57,11 @@ class HTMLPurifier_ConfigSchema_InterchangeValidator * Validates and adds a directive hash */ public function addDirective($hash) { - foreach ($this->validators as $validator) { - $validator->validateDirective($hash, $this->interchange); + for ($i = 0; $i < $this->index; $i++) { + if (isset($this->validators[$i])) $validator = $this->validators[$i]; + elseif (isset($this->directiveValidators[$i])) $validator = $this->directiveValidators[$i]; + else continue; + $validator->validate($hash, $this->interchange); } $this->interchange->addDirective($hash); } diff --git a/library/HTMLPurifier/ConfigSchema/Validator.php b/library/HTMLPurifier/ConfigSchema/Validator.php index e87302a0..700cccfb 100644 --- a/library/HTMLPurifier/ConfigSchema/Validator.php +++ b/library/HTMLPurifier/ConfigSchema/Validator.php @@ -6,34 +6,14 @@ class HTMLPurifier_ConfigSchema_Validator { - /** - * Validates and filters a namespace. - */ - public function validateNamespace(&$arr, $interchange) { - $this->validate($arr, $interchange, 'namespace'); - } - - /** - * Validates and filters a directive. - */ - public function validateDirective(&$arr, $interchange) { - $this->validate($arr, $interchange, 'directive'); - } - /** * Common validator, throwing an exception on error. It can * also performing filtering or evaluation functions. * - * @note This is strictly for convenience reasons when subclasing. - * * @param $arr Array to validate. * @param $interchange HTMLPurifier_ConfigSchema_Interchange object * that is being processed. - * @param $type Type of object being validated, this saves a little work - * if only cosmetic changes are being made between namespaces - * and directives. */ - protected function validate(&$arr, $interchange, $type) {} - + public function validate(&$arr, $interchange) {} } diff --git a/library/HTMLPurifier/ConfigSchema/Validator/Alnum.php b/library/HTMLPurifier/ConfigSchema/Validator/Alnum.php new file mode 100644 index 00000000..3233b9d3 --- /dev/null +++ b/library/HTMLPurifier/ConfigSchema/Validator/Alnum.php @@ -0,0 +1,22 @@ +index = $index; + } + + public function validate(&$arr, $interchange) { + if (!ctype_alnum($arr[$this->index])) { + throw new HTMLPurifier_ConfigSchema_Exception($arr[$this->index] . ' in '. $this->index .' must be alphanumeric'); + } + } + +} diff --git a/library/HTMLPurifier/ConfigSchema/Validator/Exists.php b/library/HTMLPurifier/ConfigSchema/Validator/Exists.php new file mode 100644 index 00000000..b6ef67cb --- /dev/null +++ b/library/HTMLPurifier/ConfigSchema/Validator/Exists.php @@ -0,0 +1,21 @@ +index = $index; + } + + public function validate(&$arr, $interchange) { + if (empty($arr[$this->index])) { + throw new HTMLPurifier_ConfigSchema_Exception($this->index . ' must exist'); + } + } + +} diff --git a/library/HTMLPurifier/ConfigSchema/Validator/IdExists.php b/library/HTMLPurifier/ConfigSchema/Validator/IdExists.php deleted file mode 100644 index 2b12d2de..00000000 --- a/library/HTMLPurifier/ConfigSchema/Validator/IdExists.php +++ /dev/null @@ -1,15 +0,0 @@ -interchange->getValidatorAdapter(); - $this->expectException(new HTMLPurifier_ConfigSchema_Exception('ID must exist in directive')); + $this->expectException(new HTMLPurifier_ConfigSchema_Exception('ID must exist')); $adapter->addDirective(array()); } diff --git a/tests/HTMLPurifier/ConfigSchema/InterchangeValidatorTest.php b/tests/HTMLPurifier/ConfigSchema/InterchangeValidatorTest.php index 1e42133f..8eab87aa 100644 --- a/tests/HTMLPurifier/ConfigSchema/InterchangeValidatorTest.php +++ b/tests/HTMLPurifier/ConfigSchema/InterchangeValidatorTest.php @@ -9,10 +9,11 @@ class HTMLPurifier_ConfigSchema_InterchangeValidatorTest extends UnitTestCase $this->validator = new HTMLPurifier_ConfigSchema_InterchangeValidator($this->mock); } - protected function makeValidator($expect_method, $expect_params) { + protected function makeValidator($expect_params = null) { generate_mock_once('HTMLPurifier_ConfigSchema_Validator'); $validator = new HTMLPurifier_ConfigSchema_ValidatorMock(); - $validator->expectOnce($expect_method, $expect_params); + if ($expect_params !== null) $validator->expectOnce('validate', $expect_params); + else $validator->expectNever('validate'); return $validator; } @@ -24,10 +25,20 @@ class HTMLPurifier_ConfigSchema_InterchangeValidatorTest extends UnitTestCase public function testAddNamespaceWithValidators() { $hash = array('ID' => 'Namespace'); - $this->validator->addValidator($this->makeValidator('validateNamespace', array($hash, $this->mock))); - $this->validator->addValidator($this->makeValidator('validateNamespace', array($hash, $this->mock))); + $this->validator->addValidator($this->makeValidator(array($hash, $this->mock))); + $this->validator->addNamespaceValidator($this->makeValidator(array($hash, $this->mock))); + $this->validator->addDirectiveValidator($this->makeValidator()); // not called $this->mock->expectOnce('addNamespace', array($hash)); $this->validator->addNamespace($hash); } + public function testAddDirectiveWithValidators() { + $hash = array('ID' => 'Namespace.Directive'); + $this->validator->addValidator($this->makeValidator(array($hash, $this->mock))); + $this->validator->addNamespaceValidator($this->makeValidator()); // not called + $this->validator->addDirectiveValidator($this->makeValidator(array($hash, $this->mock))); + $this->mock->expectOnce('addDirective', array($hash)); + $this->validator->addDirective($hash); + } + } diff --git a/tests/HTMLPurifier/ConfigSchema/Validator/AlnumTest.php b/tests/HTMLPurifier/ConfigSchema/Validator/AlnumTest.php new file mode 100644 index 00000000..ddf317b1 --- /dev/null +++ b/tests/HTMLPurifier/ConfigSchema/Validator/AlnumTest.php @@ -0,0 +1,17 @@ +validator = new HTMLPurifier_ConfigSchema_Validator_Alnum('ID'); + } + + public function testValidate() { + $this->expectSchemaException('R&D in ID must be alphanumeric'); + $arr = array('ID' => 'R&D'); + $this->validator->validate($arr, $this->interchange); + } + +} diff --git a/tests/HTMLPurifier/ConfigSchema/Validator/ExistsTest.php b/tests/HTMLPurifier/ConfigSchema/Validator/ExistsTest.php new file mode 100644 index 00000000..ed0c9e21 --- /dev/null +++ b/tests/HTMLPurifier/ConfigSchema/Validator/ExistsTest.php @@ -0,0 +1,17 @@ +validator = new HTMLPurifier_ConfigSchema_Validator_Exists('ID'); + } + + public function testValidate() { + $this->expectSchemaException('ID must exist'); + $arr = array(); + $this->validator->validate($arr, $this->interchange); + } + +} diff --git a/tests/HTMLPurifier/ConfigSchema/Validator/IdExistsTest.php b/tests/HTMLPurifier/ConfigSchema/Validator/IdExistsTest.php deleted file mode 100644 index 6a42e1ed..00000000 --- a/tests/HTMLPurifier/ConfigSchema/Validator/IdExistsTest.php +++ /dev/null @@ -1,23 +0,0 @@ -validator = new HTMLPurifier_ConfigSchema_Validator_IdExists(); - } - - public function testValidateNamespace() { - $this->expectSchemaException('ID must exist in namespace'); - $arr = array(); - $this->validator->validateNamespace($arr, $this->interchange); - } - - public function testValidateDirective() { - $this->expectSchemaException('ID must exist in directive'); - $arr = array(); - $this->validator->validateDirective($arr, $this->interchange); - } - -}