mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-07-31 03:10:09 +02:00
[3.1.0] De-crudify the ConfigSchema space; we're starting over again
- Optimize ConfigSchema by removing non-essential runtime data. We can probably optimize even more by collapsing object structures to arrays. - Removed validation data from ConfigSchema; this will be reimplemented on Interchange - Implement a sane Interchange composite hierarchy that doesn't use arrays - Implement StringHash -> Interchange -> ConfigSchema, and rewrite maintenance file to account for this git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1615 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
@@ -127,22 +127,14 @@ require 'HTMLPurifier/ConfigDef/DirectiveAlias.php';
|
||||
require 'HTMLPurifier/ConfigDef/Namespace.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Exception.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Interchange.php';
|
||||
require 'HTMLPurifier/ConfigSchema/InterchangeBuilder.php';
|
||||
require 'HTMLPurifier/ConfigSchema/InterchangeValidator.php';
|
||||
require 'HTMLPurifier/ConfigSchema/StringHash.php';
|
||||
require 'HTMLPurifier/ConfigSchema/StringHashAdapter.php';
|
||||
require 'HTMLPurifier/ConfigSchema/StringHashParser.php';
|
||||
require 'HTMLPurifier/ConfigSchema/StringHashReverseAdapter.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/Alnum.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/Composite.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/Exists.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/If.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/NamespaceExists.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/Or.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/ParseDefault.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/ParseId.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/ParseType.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Validator/Unique.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Interchange/Directive.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Interchange/Id.php';
|
||||
require 'HTMLPurifier/ConfigSchema/Interchange/Namespace.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Decorator.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Null.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Serializer.php';
|
||||
|
@@ -11,13 +11,11 @@ class HTMLPurifier_ConfigDef_Directive extends HTMLPurifier_ConfigDef
|
||||
|
||||
public function __construct(
|
||||
$type = null,
|
||||
$description = null,
|
||||
$allow_null = null,
|
||||
$allowed = null,
|
||||
$aliases = null
|
||||
) {
|
||||
if ( $type !== null) $this->type = $type;
|
||||
if ($description !== null) $this->description = $description;
|
||||
if ( $allow_null !== null) $this->allow_null = $allow_null;
|
||||
if ( $allowed !== null) $this->allowed = $allowed;
|
||||
if ( $aliases !== null) $this->aliases = $aliases;
|
||||
@@ -37,11 +35,6 @@ class HTMLPurifier_ConfigDef_Directive extends HTMLPurifier_ConfigDef
|
||||
*/
|
||||
public $type = 'mixed';
|
||||
|
||||
/**
|
||||
* Plaintext description of the configuration entity is.
|
||||
*/
|
||||
public $description = null;
|
||||
|
||||
/**
|
||||
* Is null allowed? Has no effect for mixed type.
|
||||
* @bool
|
||||
|
@@ -3,18 +3,8 @@
|
||||
/**
|
||||
* Structure object describing of a namespace
|
||||
*/
|
||||
class HTMLPurifier_ConfigDef_Namespace extends HTMLPurifier_ConfigDef {
|
||||
|
||||
public function HTMLPurifier_ConfigDef_Namespace($description = null) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
class HTMLPurifier_ConfigDef_Namespace extends HTMLPurifier_ConfigDef
|
||||
{
|
||||
public $class = 'namespace';
|
||||
|
||||
/**
|
||||
* String description of what kinds of directives go in this namespace.
|
||||
*/
|
||||
public $description;
|
||||
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
if (!defined('HTMLPURIFIER_SCHEMA_STRICT')) define('HTMLPURIFIER_SCHEMA_STRICT', false);
|
||||
|
||||
/**
|
||||
* Configuration definition, defines directives and their defaults.
|
||||
*/
|
||||
@@ -18,11 +16,6 @@ class HTMLPurifier_ConfigSchema {
|
||||
*/
|
||||
public $info = array();
|
||||
|
||||
/**
|
||||
* Definition of namespaces.
|
||||
*/
|
||||
public $info_namespace = array();
|
||||
|
||||
/**
|
||||
* Application-wide singleton
|
||||
*/
|
||||
@@ -33,23 +26,6 @@ class HTMLPurifier_ConfigSchema {
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* Lookup table of allowed types.
|
||||
*/
|
||||
public $types = array(
|
||||
'string' => 'String',
|
||||
'istring' => 'Case-insensitive string',
|
||||
'text' => 'Text',
|
||||
'itext' => 'Case-insensitive text',
|
||||
'int' => 'Integer',
|
||||
'float' => 'Float',
|
||||
'bool' => 'Boolean',
|
||||
'lookup' => 'Lookup array',
|
||||
'list' => 'Array list',
|
||||
'hash' => 'Associative array',
|
||||
'mixed' => 'Mixed'
|
||||
);
|
||||
|
||||
public function __construct() {
|
||||
$this->parser = new HTMLPurifier_VarParser_Flexible();
|
||||
}
|
||||
@@ -73,114 +49,37 @@ class HTMLPurifier_ConfigSchema {
|
||||
return HTMLPurifier_ConfigSchema::$singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an E_USER_NOTICE stating that a method is deprecated.
|
||||
*/
|
||||
private static function deprecated($method) {
|
||||
trigger_error("Static HTMLPurifier_ConfigSchema::$method deprecated, use add*() method instead", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->set() */
|
||||
public static function define($namespace, $name, $default, $type, $description) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->add($namespace, $name, $default, $type, $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a directive for configuration
|
||||
* @warning Will fail of directive's namespace is defined
|
||||
* @warning Will fail of directive's namespace is defined.
|
||||
* @warning This method's signature is slightly different from the legacy
|
||||
* define() static method! Beware!
|
||||
* @param $namespace Namespace the directive is in
|
||||
* @param $name Key of directive
|
||||
* @param $default Default value of directive
|
||||
* @param $type Allowed type of the directive. See
|
||||
* HTMLPurifier_DirectiveDef::$type for allowed values
|
||||
* @param $description Description of directive for documentation
|
||||
* @param $allow_null Whether or not to allow null values
|
||||
*/
|
||||
public function add($namespace, $name, $default, $type, $description) {
|
||||
// basic sanity checks
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!isset($this->info[$namespace])) {
|
||||
trigger_error('Cannot define directive for undefined namespace',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (!ctype_alnum($name)) {
|
||||
trigger_error('Directive name must be alphanumeric',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (empty($description)) {
|
||||
trigger_error('Description must be non-empty',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->info[$namespace][$name])) {
|
||||
// already defined
|
||||
trigger_error('Cannot redefine directive');
|
||||
return;
|
||||
} else {
|
||||
// needs defining
|
||||
|
||||
// process modifiers (OPTIMIZE!)
|
||||
$type_values = explode('/', $type, 2);
|
||||
$type = $type_values[0];
|
||||
$modifier = isset($type_values[1]) ? $type_values[1] : false;
|
||||
$allow_null = ($modifier === 'null');
|
||||
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!isset($this->types[$type])) {
|
||||
trigger_error('Invalid type for configuration directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$default = $this->parser->parse($default, $type, $allow_null);
|
||||
} catch (HTMLPurifier_VarParserException $e) {
|
||||
trigger_error('Default value does not match directive type',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->info[$namespace][$name] =
|
||||
new HTMLPurifier_ConfigDef_Directive();
|
||||
$this->info[$namespace][$name]->type = $type;
|
||||
$this->info[$namespace][$name]->allow_null = $allow_null;
|
||||
$this->defaults[$namespace][$name] = $default;
|
||||
}
|
||||
if (!HTMLPURIFIER_SCHEMA_STRICT) return;
|
||||
$this->info[$namespace][$name]->description = $description;
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addNamespace() */
|
||||
public static function defineNamespace($namespace, $description) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addNamespace($namespace, $description);
|
||||
public function add($namespace, $name, $default, $type, $allow_null) {
|
||||
$default = $this->parser->parse($default, $type, $allow_null);
|
||||
$this->info[$namespace][$name] = new HTMLPurifier_ConfigDef_Directive();
|
||||
$this->info[$namespace][$name]->type = $type;
|
||||
$this->info[$namespace][$name]->allow_null = $allow_null;
|
||||
$this->defaults[$namespace][$name] = $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a namespace for directives to be put into.
|
||||
* @warning This is slightly different from the corresponding static
|
||||
* method.
|
||||
* @param $namespace Namespace's name
|
||||
* @param $description Description of the namespace
|
||||
*/
|
||||
public function addNamespace($namespace, $description) {
|
||||
public function addNamespace($namespace) {
|
||||
$this->info[$namespace] = array();
|
||||
$this->info_namespace[$namespace] = new HTMLPurifier_ConfigDef_Namespace();
|
||||
$this->info_namespace[$namespace]->description = $description;
|
||||
$this->defaults[$namespace] = array();
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addValueAliases() */
|
||||
public static function defineValueAliases($namespace, $name, $aliases) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addValueAliases($namespace, $name, $aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a directive value alias.
|
||||
*
|
||||
@@ -188,83 +87,26 @@ class HTMLPurifier_ConfigSchema {
|
||||
* them set a directive to several values and get the same result.
|
||||
* @param $namespace Directive's namespace
|
||||
* @param $name Name of Directive
|
||||
* @param $alias Name of aliased value
|
||||
* @param $real Value aliased value will be converted into
|
||||
* @param $aliases Hash of aliased values to the real alias
|
||||
*/
|
||||
public function addValueAliases($namespace, $name, $aliases) {
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT && !isset($this->info[$namespace][$name])) {
|
||||
trigger_error('Cannot set value alias for non-existant directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
foreach ($aliases as $alias => $real) {
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!$this->info[$namespace][$name] !== true &&
|
||||
!isset($this->info[$namespace][$name]->allowed[$real])
|
||||
) {
|
||||
trigger_error('Cannot define alias to value that is not allowed',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (isset($this->info[$namespace][$name]->allowed[$alias])) {
|
||||
trigger_error('Cannot define alias over allowed value',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->info[$namespace][$name]->aliases[$alias] = $real;
|
||||
}
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addAllowedValues() */
|
||||
public static function defineAllowedValues($namespace, $name, $allowed_values) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAllowedValues($namespace, $name, $allowed_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a set of allowed values for a directive.
|
||||
* @warning This is slightly different from the corresponding static
|
||||
* method definition.
|
||||
* @param $namespace Namespace of directive
|
||||
* @param $name Name of directive
|
||||
* @param $allowed_values Arraylist of allowed values
|
||||
* @param $allowed Lookup array of allowed values
|
||||
*/
|
||||
public function addAllowedValues($namespace, $name, $allowed_values) {
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT && !isset($this->info[$namespace][$name])) {
|
||||
trigger_error('Cannot define allowed values for undefined directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
public function addAllowedValues($namespace, $name, $allowed) {
|
||||
$directive =& $this->info[$namespace][$name];
|
||||
$type = $directive->type;
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT && $type != 'string' && $type != 'istring') {
|
||||
trigger_error('Cannot define allowed values for directive whose type is not string',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if ($directive->allowed === true) {
|
||||
$directive->allowed = array();
|
||||
}
|
||||
foreach ($allowed_values as $value) {
|
||||
$directive->allowed[$value] = true;
|
||||
}
|
||||
if (
|
||||
HTMLPURIFIER_SCHEMA_STRICT &&
|
||||
$this->defaults[$namespace][$name] !== null &&
|
||||
!isset($directive->allowed[$this->defaults[$namespace][$name]])
|
||||
) {
|
||||
trigger_error('Default value must be in allowed range of variables',
|
||||
E_USER_ERROR);
|
||||
$directive->allowed = true; // undo undo!
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addAlias() */
|
||||
public static function defineAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAlias($namespace, $name, $new_namespace, $new_name);
|
||||
$directive->allowed = $allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,61 +117,54 @@ class HTMLPurifier_ConfigSchema {
|
||||
* @param $new_name Directive that the alias will be to
|
||||
*/
|
||||
public function addAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!isset($this->info[$namespace])) {
|
||||
trigger_error('Cannot define directive alias in undefined namespace',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (!ctype_alnum($name)) {
|
||||
trigger_error('Directive name must be alphanumeric',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (isset($this->info[$namespace][$name])) {
|
||||
trigger_error('Cannot define alias over directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (!isset($this->info[$new_namespace][$new_name])) {
|
||||
trigger_error('Cannot define alias to undefined directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if ($this->info[$new_namespace][$new_name]->class == 'alias') {
|
||||
trigger_error('Cannot define alias to alias',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->info[$namespace][$name] =
|
||||
new HTMLPurifier_ConfigDef_DirectiveAlias(
|
||||
$new_namespace, $new_name);
|
||||
$this->info[$namespace][$name] = new HTMLPurifier_ConfigDef_DirectiveAlias($new_namespace, $new_name);
|
||||
$this->info[$new_namespace][$new_name]->directiveAliases[] = "$namespace.$name";
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an absolute path and munges it into a more manageable relative path
|
||||
* @todo Consider making protected
|
||||
* @param $filename Filename to check
|
||||
* @return string munged filename
|
||||
*/
|
||||
public function mungeFilename($filename) {
|
||||
if (!HTMLPURIFIER_SCHEMA_STRICT) return $filename;
|
||||
$offset = strrpos($filename, 'HTMLPurifier');
|
||||
$filename = substr($filename, $offset);
|
||||
$filename = str_replace('\\', '/', $filename);
|
||||
return $filename;
|
||||
// DEPRECATED METHODS
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->set() */
|
||||
public static function define($namespace, $name, $default, $type, $description) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
// process modifiers (OPTIMIZE!)
|
||||
$type_values = explode('/', $type, 2);
|
||||
$type = $type_values[0];
|
||||
$modifier = isset($type_values[1]) ? $type_values[1] : false;
|
||||
$allow_null = ($modifier === 'null');
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->add($namespace, $name, $default, $type, $allow_null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if var is an HTMLPurifier_Error object
|
||||
* @todo Consider making protected
|
||||
*/
|
||||
public function isError($var) {
|
||||
if (!is_object($var)) return false;
|
||||
if (!($var instanceof HTMLPurifier_Error)) return false;
|
||||
return true;
|
||||
/** @see HTMLPurifier_ConfigSchema->addNamespace() */
|
||||
public static function defineNamespace($namespace, $description) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addNamespace($namespace);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addValueAliases() */
|
||||
public static function defineValueAliases($namespace, $name, $aliases) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addValueAliases($namespace, $name, $aliases);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addAllowedValues() */
|
||||
public static function defineAllowedValues($namespace, $name, $allowed_values) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$allowed = array();
|
||||
foreach ($allowed_values as $value) {
|
||||
$allowed[$value] = true;
|
||||
}
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAllowedValues($namespace, $name, $allowed);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addAlias() */
|
||||
public static function defineAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAlias($namespace, $name, $new_namespace, $new_name);
|
||||
}
|
||||
|
||||
/** @deprecated, use HTMLPurifier_VarParser->parse() */
|
||||
@@ -338,6 +173,13 @@ class HTMLPurifier_ConfigSchema {
|
||||
return $this->parser->parse($a, $b, $c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an E_USER_NOTICE stating that a method is deprecated.
|
||||
*/
|
||||
private static function deprecated($method) {
|
||||
trigger_error("Static HTMLPurifier_ConfigSchema::$method deprecated, use add*() method instead", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
48
library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php
Normal file
48
library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Converts HTMLPurifier_ConfigSchema_Interchange to our runtime
|
||||
* representation used to perform checks on user configuration.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Builder_ConfigSchema
|
||||
{
|
||||
|
||||
public function build($interchange) {
|
||||
$schema = new HTMLPurifier_ConfigSchema();
|
||||
foreach ($this->namespaces as $n) {
|
||||
$schema->addNamespace($n->namespace);
|
||||
}
|
||||
foreach ($this->directives as $d) {
|
||||
$schema->add(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->default,
|
||||
$d->type,
|
||||
$d->typeAllowsNull
|
||||
);
|
||||
if ($d->allowed !== null) {
|
||||
$schema->addAllowedValues(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->allowed
|
||||
);
|
||||
}
|
||||
foreach ($d->aliases as $alias) {
|
||||
$schema->addAlias(
|
||||
$alias->id->namespace,
|
||||
$alias->id->directive,
|
||||
$d->id->namespace,
|
||||
$d->id->directive
|
||||
);
|
||||
}
|
||||
if ($d->valueAliases !== null) {
|
||||
$schema->addValueAliases(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->valueAliases
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -21,69 +21,15 @@ class HTMLPurifier_ConfigSchema_Interchange
|
||||
/**
|
||||
* Adds a namespace array to $namespaces
|
||||
*/
|
||||
public function addNamespace($arr) {
|
||||
$this->namespaces[$arr['ID']] = $arr;
|
||||
public function addNamespace($namespace) {
|
||||
$this->namespaces[$namespace->namespace] = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a directive array to $directives
|
||||
*/
|
||||
public function addDirective($arr) {
|
||||
$this->directives[$arr['ID']] = $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a version of this object wrapped in the validator adapter
|
||||
* to be used for data-input.
|
||||
*/
|
||||
public function getValidatorAdapter() {
|
||||
$validator = new HTMLPurifier_ConfigSchema_InterchangeValidator($this);
|
||||
|
||||
// Validators should be defined in the order they are to be called.
|
||||
$namespace = $validator->namespace;
|
||||
$directive = $validator->directive;
|
||||
|
||||
// ID tests
|
||||
$validator->addValidator($this->make('Exists', 'ID'));
|
||||
$validator->addValidator($this->make('Unique'));
|
||||
|
||||
// ID: Namespace test
|
||||
$namespace->addValidator($this->make('Alnum', 'ID'));
|
||||
|
||||
// ID: Common tests
|
||||
$validator->addValidator($this->make('ParseId'));
|
||||
$validator->addValidator($this->make('Exists', '_NAMESPACE'));
|
||||
$validator->addValidator($this->make('Alnum', '_NAMESPACE'));
|
||||
|
||||
// ID: Directive tests
|
||||
$directive->addValidator($this->make('Exists', '_DIRECTIVE'));
|
||||
$directive->addValidator($this->make('Alnum', '_DIRECTIVE'));
|
||||
$directive->addValidator($this->make('NamespaceExists'));
|
||||
|
||||
// Directive: Type and Default tests
|
||||
$directive->addValidator($this->make('Exists', 'TYPE'));
|
||||
$directive->addValidator($this->make('ParseType'));
|
||||
$directive->addValidator($this->make('Exists', '_TYPE'));
|
||||
$directive->addValidator($this->make('Exists', '_NULL'));
|
||||
$directive->addValidator($this->make('Exists', 'DEFAULT'));
|
||||
$directive->addValidator($this->make('ParseDefault'));
|
||||
|
||||
// Common tests
|
||||
$validator->addValidator($this->make('Exists', 'DESCRIPTION'));
|
||||
|
||||
return $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a validator.
|
||||
* @warning
|
||||
* Only *one* argument is supported; multiple args shouldn't use
|
||||
* this function.
|
||||
*/
|
||||
protected function make($name, $arg = null) {
|
||||
$class = "HTMLPurifier_ConfigSchema_Validator_$name";
|
||||
if ($arg === null) return new $class();
|
||||
else return new $class($arg);
|
||||
public function addDirective($directive) {
|
||||
$this->directives[(string) $directive->id] = $directive;
|
||||
}
|
||||
|
||||
}
|
||||
|
70
library/HTMLPurifier/ConfigSchema/Interchange/Directive.php
Normal file
70
library/HTMLPurifier/ConfigSchema/Interchange/Directive.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interchange component class describing configuration directives.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Directive
|
||||
{
|
||||
|
||||
/**
|
||||
* ID of directive, instance of HTMLPurifier_ConfigSchema_Interchange_Id.
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* String type, e.g. 'integer' or 'istring'.
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Default value, e.g. 3 or 'DefaultVal'.
|
||||
*/
|
||||
public $default;
|
||||
|
||||
/**
|
||||
* HTML description.
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* Boolean whether or not null is allowed as a value.
|
||||
*/
|
||||
public $typeAllowsNull = false;
|
||||
|
||||
/**
|
||||
* Lookup table of allowed scalar values, e.g. array('allowed' => true).
|
||||
* Null if all values are allowed.
|
||||
*/
|
||||
public $allowed;
|
||||
|
||||
/**
|
||||
* List of aliases for the directive, e.g. array('Alt.Directive').
|
||||
*/
|
||||
public $aliases = array();
|
||||
|
||||
/**
|
||||
* Hash of value aliases, e.g. array('alt' => 'real'). Null if value
|
||||
* aliasing is disabled (necessary for non-scalar types).
|
||||
*/
|
||||
public $valueAliases;
|
||||
|
||||
/**
|
||||
* Version of HTML Purifier the directive was introduced, e.g. '1.3.1'.
|
||||
* Null if the directive has always existed.
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* ID of directive that supercedes this old directive, is an instance
|
||||
* of HTMLPurifier_ConfigSchema_Interchange_Id. Null if not deprecated.
|
||||
*/
|
||||
public $deprecatedUse;
|
||||
|
||||
/**
|
||||
* Version of HTML Purifier this directive was deprecated. Null if not
|
||||
* deprecated.
|
||||
*/
|
||||
public $deprecatedVersion;
|
||||
|
||||
|
||||
}
|
25
library/HTMLPurifier/ConfigSchema/Interchange/Id.php
Normal file
25
library/HTMLPurifier/ConfigSchema/Interchange/Id.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Represents a directive ID in the interchange format.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
{
|
||||
|
||||
public $namespace, $directive;
|
||||
|
||||
public function __construct($namespace, $directive) {
|
||||
$this->namespace = $namespace;
|
||||
$this->directive = $directive;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->namespace . '.' . $this->directive;
|
||||
}
|
||||
|
||||
public static function make($id) {
|
||||
list($namespace, $directive) = explode('.', $id);
|
||||
return new HTMLPurifier_ConfigSchema_Interchange_Id($namespace, $directive);
|
||||
}
|
||||
|
||||
}
|
19
library/HTMLPurifier/ConfigSchema/Interchange/Namespace.php
Normal file
19
library/HTMLPurifier/ConfigSchema/Interchange/Namespace.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interchange component class describing namespaces.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of namespace defined.
|
||||
*/
|
||||
public $namespace;
|
||||
|
||||
/**
|
||||
* HTML description.
|
||||
*/
|
||||
public $description;
|
||||
|
||||
}
|
109
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php
Normal file
109
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_ConfigSchema_InterchangeBuilder
|
||||
{
|
||||
|
||||
protected $varParser;
|
||||
|
||||
public function __construct($varParser = null) {
|
||||
$this->varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an interchange object based on a hash.
|
||||
* @param $interchange HTMLPurifier_ConfigSchema_Interchange object to build
|
||||
* @param $hash HTMLPurifier_ConfigSchema_StringHash source data
|
||||
*/
|
||||
public function build($interchange, $hash) {
|
||||
if (strpos($hash['ID'], '.') === false) {
|
||||
$this->buildNamespace($interchange, $hash);
|
||||
} else {
|
||||
$this->buildDirective($interchange, $hash);
|
||||
}
|
||||
$this->_findUnused($hash);
|
||||
}
|
||||
|
||||
public function buildNamespace($interchange, $hash) {
|
||||
$namespace = new HTMLPurifier_ConfigSchema_Interchange_Namespace();
|
||||
$namespace->namespace = $hash->offsetGet('ID');
|
||||
$namespace->description = $hash->offsetGet('DESCRIPTION');
|
||||
$interchange->addNamespace($namespace);
|
||||
}
|
||||
|
||||
public function buildDirective($interchange, $hash) {
|
||||
$directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
||||
|
||||
// These are required elements:
|
||||
$directive->id = $this->id($hash->offsetGet('ID'));
|
||||
$type = explode('/', $hash->offsetGet('TYPE'));
|
||||
if (isset($type[1])) $directive->typeAllowsNull = true;
|
||||
$directive->type = $type[0];
|
||||
$directive->description = $directive->offsetGet('DESCRIPTION');
|
||||
|
||||
// These are extras:
|
||||
if (isset($directive['ALLOWED'])) {
|
||||
$directive->allowed = $this->lookup($this->evalArray($directive->offsetGet('ALLOWED')));
|
||||
}
|
||||
if (isset($directive['VALUE-ALIASES'])) {
|
||||
$directive->valueAliases = $this->evalArray($directive->offsetGet('VALUE-ALIASES'));
|
||||
}
|
||||
if (isset($directive['ALIASES'])) {
|
||||
$raw_aliases = trim($hash->offsetGet('ALIASES'));
|
||||
$aliases = preg_split('/\s*,\s*/', $raw_aliases);
|
||||
foreach ($aliases as $alias) {
|
||||
$this->aliases[] = $this->id($alias);
|
||||
}
|
||||
}
|
||||
if (isset($directive['VERSION'])) {
|
||||
$directive->version = $directive->offsetGet('VERSION');
|
||||
}
|
||||
if (isset($directive['DEPRECATED-USE'])) {
|
||||
$directive->deprecatedUse = $this->id($directive->offsetGet('DEPRECATED-USE'));
|
||||
}
|
||||
if (isset($directive['DEPRECATED-VERSION'])) {
|
||||
$directive->deprecatedVersion = $directive->offsetGet('DEPRECATED-VERSION');
|
||||
}
|
||||
|
||||
$interchange->addDirective($directive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates an array PHP code string without array() wrapper
|
||||
*/
|
||||
protected function evalArray($contents) {
|
||||
return eval('return array('. $contents .');');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array list into a lookup array.
|
||||
*/
|
||||
protected function lookup($array) {
|
||||
$ret = array();
|
||||
foreach ($array as $val) $ret[$val] = true;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
* object based on a string Id.
|
||||
*/
|
||||
protected function id($id) {
|
||||
return HTMLPurifier_ConfigSchema_Interchange_Id::make($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers errors for any unused keys passed in the hash; such keys
|
||||
* may indicate typos, missing values, etc.
|
||||
* @param $hash Instance of ConfigSchema_StringHash to check.
|
||||
*/
|
||||
protected function _findUnused($hash) {
|
||||
$accessed = $hash->getAccessed();
|
||||
foreach ($hash as $k => $v) {
|
||||
if (!isset($accessed[$k])) {
|
||||
trigger_error("String hash key '$k' not used by builder", E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Takes an array of keys to strings, probably generated by
|
||||
* HTMLPurifier_ConfigSchema_StringHashParser
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_StringHashAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* Takes a string hash and calls the appropriate functions in $schema
|
||||
* based on its values.
|
||||
*/
|
||||
public function adapt($hash, $schema) {
|
||||
|
||||
if (! $hash instanceof HTMLPurifier_ConfigSchema_StringHash) {
|
||||
$hash = new HTMLPurifier_ConfigSchema_StringHash($hash);
|
||||
}
|
||||
|
||||
if (!isset($hash['ID'])) {
|
||||
trigger_error('Missing key ID in string hash');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check namespace:
|
||||
if (strpos($hash['ID'], '.') === false) {
|
||||
// This will cause problems if we decide to support nested
|
||||
// namespaces, but for now it's ok.
|
||||
$schema->addNamespace($hash->offsetGet('ID'), $hash->offsetGet('DESCRIPTION'));
|
||||
$this->_findUnused($hash);
|
||||
return;
|
||||
}
|
||||
|
||||
list($ns, $directive) = explode('.', $hash->offsetGet('ID'), 2);
|
||||
|
||||
if (isset($hash['TYPE'], $hash['DEFAULT'], $hash['DESCRIPTION'])) {
|
||||
$type = $hash->offsetGet('TYPE');
|
||||
$raw_default = $hash->offsetGet('DEFAULT');
|
||||
$default = eval("return $raw_default;");
|
||||
$description = $hash->offsetGet('DESCRIPTION');
|
||||
$schema->add($ns, $directive, $default, $type, $description);
|
||||
}
|
||||
|
||||
if (isset($hash['ALLOWED'])) {
|
||||
$raw_allowed = $hash->offsetGet('ALLOWED');
|
||||
$allowed = eval("return array($raw_allowed);");
|
||||
$schema->addAllowedValues($ns, $directive, $allowed);
|
||||
}
|
||||
|
||||
// This must be after ALLOWED
|
||||
if (isset($hash['VALUE-ALIASES'])) {
|
||||
$raw_value_aliases = $hash->offsetGet('VALUE-ALIASES');
|
||||
$value_aliases = eval("return array($raw_value_aliases);");
|
||||
$schema->addValueAliases($ns, $directive, $value_aliases);
|
||||
}
|
||||
|
||||
if (isset($hash['ALIASES'])) {
|
||||
$raw_aliases = trim($hash->offsetGet('ALIASES'));
|
||||
$aliases = preg_split('/\s*,\s*/', $raw_aliases);
|
||||
foreach ($aliases as $alias) {
|
||||
list($alias_ns, $alias_directive) = explode('.', $alias, 2);
|
||||
$schema->addAlias($alias_ns, $alias_directive, $ns, $directive);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use these yet, but they're specified
|
||||
if (isset($hash['VERSION'])) $hash->offsetGet('VERSION');
|
||||
if (isset($hash['DEPRECATED-USE'])) $hash->offsetGet('DEPRECATED-USE');
|
||||
if (isset($hash['DEPRECATED-VERSION'])) $hash->offsetGet('DEPRECATED-VERSION');
|
||||
|
||||
$this->_findUnused($hash);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers errors for any unused keys passed in the hash; such keys
|
||||
* may indicate typos, missing values, etc.
|
||||
* @param $hash Instance of ConfigSchema_StringHash to check.
|
||||
*/
|
||||
protected function _findUnused($hash) {
|
||||
$accessed = $hash->getAccessed();
|
||||
foreach ($hash as $k => $v) {
|
||||
if (!isset($accessed[$k])) {
|
||||
trigger_error("String hash key '$k' not used by adapter", E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,127 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Converts HTMLPurifier_ConfigSchema into a StringHash which can be
|
||||
* easily saved to a file.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_StringHashReverseAdapter
|
||||
{
|
||||
|
||||
protected $schema;
|
||||
|
||||
/**
|
||||
* @param $schema Instance of HTMLPurifier_ConfigSchema to generate
|
||||
* string hashes from.
|
||||
*/
|
||||
public function __construct($schema) {
|
||||
$this->schema = $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a string hash from a specific ID, could be a directive
|
||||
* or a namespace.
|
||||
* @param $ns string namespace
|
||||
* @param $directive string directive name
|
||||
*/
|
||||
public function get($ns, $directive = null) {
|
||||
$ret = array();
|
||||
if ($directive === null) {
|
||||
if (!isset($this->schema->info_namespace[$ns])) {
|
||||
trigger_error("Namespace '$ns' doesn't exist in schema");
|
||||
return;
|
||||
}
|
||||
$def = $this->schema->info_namespace[$ns];
|
||||
$ret['ID'] = $ns;
|
||||
$ret['DESCRIPTION'] = $def->description;
|
||||
return $ret;
|
||||
}
|
||||
if (!isset($this->schema->info[$ns][$directive])) {
|
||||
trigger_error("Directive '$ns.$directive' doesn't exist in schema");
|
||||
return;
|
||||
}
|
||||
|
||||
$def = $this->schema->info[$ns][$directive];
|
||||
|
||||
if ($def instanceof HTMLPurifier_ConfigDef_DirectiveAlias) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ret['ID'] = "$ns.$directive";
|
||||
$ret['TYPE'] = $def->type;
|
||||
|
||||
// Attempt to extract version information from description.
|
||||
$description = $this->normalize($def->description);
|
||||
list($description, $version) = $this->extractVersion($description);
|
||||
|
||||
if ($version) $ret['VERSION'] = $version;
|
||||
$ret['DEFAULT'] = $this->export($this->schema->defaults[$ns][$directive]);
|
||||
$ret['DESCRIPTION'] = wordwrap($description, 75, "\n");
|
||||
|
||||
if ($def->allowed !== true) {
|
||||
$ret['ALLOWED'] = $this->exportLookup($def->allowed);
|
||||
}
|
||||
if (!empty($def->aliases)) {
|
||||
$ret['VALUE-ALIASES'] = $this->exportHash($def->aliases);
|
||||
}
|
||||
if (!empty($def->directiveAliases)) {
|
||||
$ret['ALIASES'] = implode(', ', $def->directiveAliases);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a variable into a PHP-readable format
|
||||
*/
|
||||
public function export($var) {
|
||||
if ($var === array()) return 'array()'; // single-line format
|
||||
return var_export($var, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a lookup array into the form 'key1', 'key2', ...
|
||||
*/
|
||||
public function exportLookup($lookup) {
|
||||
if (!is_array($lookup)) return $this->export($lookup);
|
||||
if (empty($lookup)) return '';
|
||||
$keys = array_map(array($this, 'export'), array_keys($lookup));
|
||||
return implode(', ', $keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a hash into the form 'key' => 'val',\n ...
|
||||
*/
|
||||
public function exportHash($hash) {
|
||||
if (!is_array($hash)) return $this->export($hash);
|
||||
if (empty($hash)) return '';
|
||||
$code = $this->export($hash);
|
||||
$lines = explode("\n", $code);
|
||||
$ret = '';
|
||||
foreach ($lines as $line) {
|
||||
if ($line == 'array (') continue;
|
||||
if ($line == ')') continue;
|
||||
$ret .= substr($line, 2) . "\n";
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a string to Unix style newlines
|
||||
*/
|
||||
protected function normalize($string) {
|
||||
return str_replace(array("\r\n", "\r"), "\n", $string);
|
||||
}
|
||||
|
||||
public function extractVersion($description) {
|
||||
$regex = '/This directive (?:has been|was) available since (\d+\.\d+\.\d+)\./';
|
||||
$regex = str_replace(' ', '\s+', $regex); // allow any number of spaces between statements
|
||||
$ok = preg_match($regex, $description, $matches);
|
||||
if ($ok) {
|
||||
$version = $matches[1];
|
||||
} else {
|
||||
$version = false;
|
||||
}
|
||||
$description = preg_replace($regex, '', $description, 1);
|
||||
return array($description, $version);
|
||||
}
|
||||
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base validator for HTMLPurifier_ConfigSchema_Interchange
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
/**
|
||||
* Common validator, throwing an exception on error. It can
|
||||
* also performing filtering or evaluation functions.
|
||||
*
|
||||
* @param $arr Array to validate.
|
||||
* @param $interchange HTMLPurifier_ConfigSchema_Interchange object
|
||||
* that is being processed.
|
||||
*/
|
||||
public function validate(&$arr, $interchange) {}
|
||||
|
||||
/**
|
||||
* Throws a HTMLPurifier_ConfigSchema_Exception
|
||||
*/
|
||||
protected function error($msg) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception($msg);
|
||||
}
|
||||
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates that a field is alphanumeric in the array. Expects $index
|
||||
* to exist.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_Alnum extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
protected $index;
|
||||
|
||||
public function __construct($index) {
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
if (!ctype_alnum($arr[$this->index])) {
|
||||
$this->error($arr[$this->index] . ' in '. $this->index .' must be alphanumeric');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Groups several validators together, which can be used with logical validators
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_Composite extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
protected $validators = array();
|
||||
|
||||
public function addValidator($validator) {
|
||||
$this->validators[] = $validator;
|
||||
}
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
foreach ($this->validators as $validator) {
|
||||
$validator->validate($arr, $interchange);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates that an field exists in the array
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_Exists extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
protected $index;
|
||||
|
||||
public function __construct($index) {
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
if (empty($arr[$this->index])) {
|
||||
$this->error($this->index . ' must exist');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* If a validator passes, run another validator.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_If extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
protected $condition;
|
||||
protected $then;
|
||||
protected $else;
|
||||
|
||||
public function __construct($cond = null) {
|
||||
$this->setCondition($cond);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $validator Validator to run as a condition. Exceptions thrown by it
|
||||
* do not bubble up.
|
||||
*/
|
||||
public function setCondition($validator) {
|
||||
$this->condition = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $validator Validator to run if condition is true
|
||||
*/
|
||||
public function setThen($validator) {
|
||||
$this->then = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $validator Validator to run if condition is false
|
||||
*/
|
||||
public function setElse($validator) {
|
||||
$this->else = $validator;
|
||||
}
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
try {
|
||||
$this->condition->validate($arr, $interchange);
|
||||
} catch (HTMLPurifier_ConfigSchema_Exception $e) {
|
||||
if ($this->else) $this->else->validate($arr, $interchange);
|
||||
return;
|
||||
}
|
||||
if ($this->then) $this->then->validate($arr, $interchange);
|
||||
}
|
||||
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates that the directive's namespace exists. Expects _NAMESPACE
|
||||
* to have been created via HTMLPurifier_ConfigSchema_Validator_ParseId
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_NamespaceExists extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
if (!isset($interchange->namespaces[$arr['_NAMESPACE']])) {
|
||||
$this->error('Cannot define directive for undefined namespace ' . $arr['_NAMESPACE']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Groups several validators together, but as an 'or': if the first
|
||||
* one passes, we abort; if it throws an exception, we try the next validator,
|
||||
* and the next. If all validators fail, we throw an exception.
|
||||
*
|
||||
* @note If no validators are registered, this validator automatically
|
||||
* "passes".
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_Or extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
protected $validators = array();
|
||||
|
||||
public function addValidator($validator) {
|
||||
$this->validators[] = $validator;
|
||||
}
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
$exceptions = array();
|
||||
$pass = false;
|
||||
foreach ($this->validators as $validator) {
|
||||
try {
|
||||
$validator->validate($arr, $interchange);
|
||||
} catch (HTMLPurifier_ConfigSchema_Exception $e) {
|
||||
$exceptions[] = $e;
|
||||
continue;
|
||||
}
|
||||
$exceptions = array();
|
||||
break;
|
||||
}
|
||||
if ($exceptions) {
|
||||
// I wonder how we can make the exceptions "lossless"
|
||||
throw new HTMLPurifier_ConfigSchema_Exception('All validators failed: ' . implode(";\n", $exceptions));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Parses DEFAULT into _DEFAULT. Expects DEFAULT, _TYPE, _NULL and ID to exist.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_ParseDefault extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
$parser = new HTMLPurifier_VarParser_Native(); // not configurable yet
|
||||
try {
|
||||
$arr['_DEFAULT'] = $parser->parse($arr['DEFAULT'], $arr['_TYPE'], $arr['_NULL']);
|
||||
} catch (HTMLPurifier_VarParserException $e) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception('Invalid type for default value in '. $arr['ID'] .': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Parses ID into NAMESPACE and, if appropriate, DIRECTIVE. Expects ID to exist.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_ParseId extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
$r = explode('.', $arr['ID'], 2);
|
||||
$arr['_NAMESPACE'] = $r[0];
|
||||
if (isset($r[1])) $arr['_DIRECTIVE'] = $r[1];
|
||||
}
|
||||
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Parses TYPE into _TYPE and _NULL. Expects TYPE and ID to exist.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_ParseType extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
$r = explode('/', $arr['TYPE'], 2);
|
||||
if (!isset(HTMLPurifier_VarParser::$types[$r[0]])) {
|
||||
$this->error('Invalid type ' . $r[0] . ' for configuration directive ' . $arr['ID']);
|
||||
}
|
||||
$arr['_TYPE'] = $r[0];
|
||||
$arr['_NULL'] = (isset($r[1]) && $r[1] === 'null');
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates that this ID does not exist already in the interchange object.
|
||||
* Expects ID to exist.
|
||||
*
|
||||
* @note
|
||||
* Although this tests both possible values, in practice the ID
|
||||
* will only be in one or the other. We do this to keep things simple.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator_Unique extends HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
public function validate(&$arr, $interchange) {
|
||||
if (isset($interchange->namespaces[$arr['ID']])) {
|
||||
$this->error('Cannot redefine namespace');
|
||||
}
|
||||
if (isset($interchange->directives[$arr['ID']])) {
|
||||
$this->error('Cannot redefine directive');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user