/system/guard/HTMLPurifier.php
PHP | 7165 lines | 7140 code | 11 blank | 14 comment | 1389 complexity | b19b343e79634ba3a38a8d8cb07b31a0 MD5 | raw file
Possible License(s): BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- <?php
- class HTMLPurifier
- {
- public $version = '3.1.0';
- const VERSION = '3.1.0';
- public $config;
- private $filters = array();
- private static $instance;
- protected $strategy, $generator;
- public $context;
- public function __construct($config = null) {
- $this->config = HTMLPurifier_Config::create($config);
- $this->strategy = new HTMLPurifier_Strategy_Core();
- }
- public function addFilter($filter) {
- trigger_error('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom', E_USER_WARNING);
- $this->filters[] = $filter;
- }
- public function purify($html, $config = null) {
- $config = $config ? HTMLPurifier_Config::create($config) : $this->config;
- $lexer = HTMLPurifier_Lexer::create($config);
- $context = new HTMLPurifier_Context();
- $this->generator = new HTMLPurifier_Generator($config, $context);
- $context->register('Generator', $this->generator);
- if ($config->get('Core', 'CollectErrors')) {
- $language_factory = HTMLPurifier_LanguageFactory::instance();
- $language = $language_factory->create($config, $context);
- $context->register('Locale', $language);
- $error_collector = new HTMLPurifier_ErrorCollector($context);
- $context->register('ErrorCollector', $error_collector);
- }
- $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context);
- $context->register('IDAccumulator', $id_accumulator);
- $html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
- $filter_flags = $config->getBatch('Filter');
- $custom_filters = $filter_flags['Custom'];
- unset($filter_flags['Custom']);
- $filters = array();
- foreach ($filter_flags as $filter => $flag) {
- if (!$flag) continue;
- $class = "HTMLPurifier_Filter_$filter";
- $filters[] = new $class;
- }
- foreach ($custom_filters as $filter) {
- $filters[] = $filter;
- }
- $filters = array_merge($filters, $this->filters);
- for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) {
- $html = $filters[$i]->preFilter($html, $config, $context);
- }
- $html =
- $this->generator->generateFromTokens(
- $this->strategy->execute(
- $lexer->tokenizeHTML(
- $html, $config, $context
- ),
- $config, $context
- )
- );
- for ($i = $filter_size - 1; $i >= 0; $i--) {
- $html = $filters[$i]->postFilter($html, $config, $context);
- }
- $html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);
- $this->context =& $context;
- return $html;
- }
- public function purifyArray($array_of_html, $config = null) {
- $context_array = array();
- foreach ($array_of_html as $key => $html) {
- $array_of_html[$key] = $this->purify($html, $config);
- $context_array[$key] = $this->context;
- }
- $this->context = $context_array;
- return $array_of_html;
- }
- public static function instance($prototype = null) {
- if (!self::$instance || $prototype) {
- if ($prototype instanceof HTMLPurifier) {
- self::$instance = $prototype;
- } elseif ($prototype) {
- self::$instance = new HTMLPurifier($prototype);
- } else {
- self::$instance = new HTMLPurifier();
- }
- }
- return self::$instance;
- }
- public static function getInstance($prototype = null) {
- return HTMLPurifier::instance($prototype);
- }
- }
- class HTMLPurifier_AttrCollections
- {
- public $info = array();
- public function __construct($attr_types, $modules) {
- foreach ($modules as $module) {
- foreach ($module->attr_collections as $coll_i => $coll) {
- if (!isset($this->info[$coll_i])) {
- $this->info[$coll_i] = array();
- }
- foreach ($coll as $attr_i => $attr) {
- if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) {
- $this->info[$coll_i][$attr_i] = array_merge(
- $this->info[$coll_i][$attr_i], $attr);
- continue;
- }
- $this->info[$coll_i][$attr_i] = $attr;
- }
- }
- }
- foreach ($this->info as $name => $attr) {
- $this->performInclusions($this->info[$name]);
- $this->expandIdentifiers($this->info[$name], $attr_types);
- }
- }
- public function performInclusions(&$attr) {
- if (!isset($attr[0])) return;
- $merge = $attr[0];
- $seen = array();
- for ($i = 0; isset($merge[$i]); $i++) {
- if (isset($seen[$merge[$i]])) continue;
- $seen[$merge[$i]] = true;
- if (!isset($this->info[$merge[$i]])) continue;
- foreach ($this->info[$merge[$i]] as $key => $value) {
- if (isset($attr[$key])) continue;
- $attr[$key] = $value;
- }
- if (isset($this->info[$merge[$i]][0])) {
- $merge = array_merge($merge, $this->info[$merge[$i]][0]);
- }
- }
- unset($attr[0]);
- }
- public function expandIdentifiers(&$attr, $attr_types) {
- $processed = array();
- foreach ($attr as $def_i => $def) {
- if ($def_i === 0) continue;
- if (isset($processed[$def_i])) continue;
- if ($required = (strpos($def_i, '*') !== false)) {
- unset($attr[$def_i]);
- $def_i = trim($def_i, '*');
- $attr[$def_i] = $def;
- }
- $processed[$def_i] = true;
- if (is_object($def)) {
- $attr[$def_i]->required = ($required || $attr[$def_i]->required);
- continue;
- }
- if ($def === false) {
- unset($attr[$def_i]);
- continue;
- }
- if ($t = $attr_types->get($def)) {
- $attr[$def_i] = $t;
- $attr[$def_i]->required = $required;
- } else {
- unset($attr[$def_i]);
- }
- }
- }
- }
- abstract class HTMLPurifier_AttrDef
- {
- public $minimized = false;
- public $required = false;
- abstract public function validate($string, $config, $context);
- public function parseCDATA($string) {
- $string = trim($string);
- $string = str_replace("\n", '', $string);
- $string = str_replace(array("\r", "\t"), ' ', $string);
- return $string;
- }
- public function make($string) {
- return $this;
- }
- protected function mungeRgb($string) {
- return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
- }
- }
- abstract class HTMLPurifier_AttrTransform
- {
- abstract public function transform($attr, $config, $context);
- public function prependCSS(&$attr, $css) {
- $attr['style'] = isset($attr['style']) ? $attr['style'] : '';
- $attr['style'] = $css . $attr['style'];
- }
- public function confiscateAttr(&$attr, $key) {
- if (!isset($attr[$key])) return null;
- $value = $attr[$key];
- unset($attr[$key]);
- return $value;
- }
- }
- class HTMLPurifier_AttrTypes
- {
- protected $info = array();
- public function __construct() {
- $this->info['Enum'] = new HTMLPurifier_AttrDef_Enum();
- $this->info['Bool'] = new HTMLPurifier_AttrDef_HTML_Bool();
- $this->info['CDATA'] = new HTMLPurifier_AttrDef_Text();
- $this->info['ID'] = new HTMLPurifier_AttrDef_HTML_ID();
- $this->info['Length'] = new HTMLPurifier_AttrDef_HTML_Length();
- $this->info['MultiLength'] = new HTMLPurifier_AttrDef_HTML_MultiLength();
- $this->info['NMTOKENS'] = new HTMLPurifier_AttrDef_HTML_Nmtokens();
- $this->info['Pixels'] = new HTMLPurifier_AttrDef_HTML_Pixels();
- $this->info['Text'] = new HTMLPurifier_AttrDef_Text();
- $this->info['URI'] = new HTMLPurifier_AttrDef_URI();
- $this->info['LanguageCode'] = new HTMLPurifier_AttrDef_Lang();
- $this->info['Color'] = new HTMLPurifier_AttrDef_HTML_Color();
- $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text();
- $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true);
- }
- public function get($type) {
- if (strpos($type, '#') !== false) list($type, $string) = explode('#', $type, 2);
- else $string = '';
- if (!isset($this->info[$type])) {
- trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR);
- return;
- }
- return $this->info[$type]->make($string);
- }
- public function set($type, $impl) {
- $this->info[$type] = $impl;
- }
- }
- class HTMLPurifier_AttrValidator
- {
- public function validateToken(&$token, &$config, $context) {
- $definition = $config->getHTMLDefinition();
- $e =& $context->get('ErrorCollector', true);
- $ok =& $context->get('IDAccumulator', true);
- if (!$ok) {
- $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context);
- $context->register('IDAccumulator', $id_accumulator);
- }
- $current_token =& $context->get('CurrentToken', true);
- if (!$current_token) $context->register('CurrentToken', $token);
- if (
- !$token instanceof HTMLPurifier_Token_Start &&
- !$token instanceof HTMLPurifier_Token_Empty
- ) return $token;
- $d_defs = $definition->info_global_attr;
- $attr =& $token->attr;
- foreach ($definition->info_attr_transform_pre as $transform) {
- $attr = $transform->transform($o = $attr, $config, $context);
- if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
- }
- foreach ($definition->info[$token->name]->attr_transform_pre as $transform) {
- $attr = $transform->transform($o = $attr, $config, $context);
- if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
- }
- $defs = $definition->info[$token->name]->attr;
- $attr_key = false;
- $context->register('CurrentAttr', $attr_key);
- foreach ($attr as $attr_key => $value) {
- if ( isset($defs[$attr_key]) ) {
- if ($defs[$attr_key] === false) {
- $result = false;
- } else {
- $result = $defs[$attr_key]->validate(
- $value, $config, $context
- );
- }
- } elseif ( isset($d_defs[$attr_key]) ) {
- $result = $d_defs[$attr_key]->validate(
- $value, $config, $context
- );
- } else {
- $result = false;
- }
- if ($result === false || $result === null) {
- if ($e) $e->send(E_ERROR, 'AttrValidator: Attribute removed');
- unset($attr[$attr_key]);
- } elseif (is_string($result)) {
- $attr[$attr_key] = $result;
- }
- }
- $context->destroy('CurrentAttr');
- foreach ($definition->info_attr_transform_post as $transform) {
- $attr = $transform->transform($o = $attr, $config, $context);
- if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
- }
- foreach ($definition->info[$token->name]->attr_transform_post as $transform) {
- $attr = $transform->transform($o = $attr, $config, $context);
- if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
- }
- if (!$current_token) $context->destroy('CurrentToken');
- }
- }
- if (!defined('HTMLPURIFIER_PREFIX')) {
- define('HTMLPURIFIER_PREFIX', dirname(__FILE__));
- set_include_path(HTMLPURIFIER_PREFIX . PATH_SEPARATOR . get_include_path());
- }
- if (!defined('PHP_EOL')) {
- switch (strtoupper(substr(PHP_OS, 0, 3))) {
- case 'WIN':
- define('PHP_EOL', "\r\n");
- break;
- case 'DAR':
- define('PHP_EOL', "\r");
- break;
- default:
- define('PHP_EOL', "\n");
- }
- }
- class HTMLPurifier_Bootstrap
- {
- public static function autoload($class) {
- $file = HTMLPurifier_Bootstrap::getPath($class);
- if (!$file) return false;
- require HTMLPURIFIER_PREFIX . '/' . $file;
- return true;
- }
- public static function getPath($class) {
- if (strncmp('HTMLPurifier', $class, 12) !== 0) return false;
- if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) {
- $code = str_replace('_', '-', substr($class, 22));
- $file = 'HTMLPurifier/Language/classes/' . $code . '.php';
- } else {
- $file = str_replace('_', '/', $class) . '.php';
- }
- if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) return false;
- return $file;
- }
- public static function registerAutoload() {
- $autoload = array('HTMLPurifier_Bootstrap', 'autoload');
- if ( ($funcs = spl_autoload_functions()) === false ) {
- spl_autoload_register($autoload);
- } elseif (function_exists('spl_autoload_unregister')) {
- $compat = version_compare(PHP_VERSION, '5.1.2', '<=') &&
- version_compare(PHP_VERSION, '5.1.0', '>=');
- foreach ($funcs as $func) {
- if (is_array($func)) {
- $reflector = new ReflectionMethod($func[0], $func[1]);
- if (!$reflector->isStatic()) {
- throw new Exception('
- HTML Purifier autoloader registrar is not compatible
- with non-static object methods due to PHP Bug #44144;
- Please do not use HTMLPurifier.autoload.php (or any
- file that includes this file); instead, place the code:
- spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\'))
- after your own autoloaders.
- ');
- }
- if ($compat) $func = implode('::', $func);
- }
- spl_autoload_unregister($func);
- }
- spl_autoload_register($autoload);
- foreach ($funcs as $func) spl_autoload_register($func);
- }
- }
- }
- abstract class HTMLPurifier_Definition
- {
- public $setup = false;
- public $type;
- abstract protected function doSetup($config);
- public function setup($config) {
- if ($this->setup) return;
- $this->setup = true;
- $this->doSetup($config);
- }
- }
- class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
- {
- public $type = 'CSS';
- public $info = array();
- protected function doSetup($config) {
- $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum(
- array('left', 'right', 'center', 'justify'), false);
- $border_style =
- $this->info['border-bottom-style'] =
- $this->info['border-right-style'] =
- $this->info['border-left-style'] =
- $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum(
- array('none', 'hidden', 'dotted', 'dashed', 'solid', 'double',
- 'groove', 'ridge', 'inset', 'outset'), false);
- $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style);
- $this->info['clear'] = new HTMLPurifier_AttrDef_Enum(
- array('none', 'left', 'right', 'both'), false);
- $this->info['float'] = new HTMLPurifier_AttrDef_Enum(
- array('none', 'left', 'right'), false);
- $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum(
- array('normal', 'italic', 'oblique'), false);
- $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum(
- array('normal', 'small-caps'), false);
- $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite(
- array(
- new HTMLPurifier_AttrDef_Enum(array('none')),
- new HTMLPurifier_AttrDef_CSS_URI()
- )
- );
- $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum(
- array('inside', 'outside'), false);
- $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum(
- array('disc', 'circle', 'square', 'decimal', 'lower-roman',
- 'upper-roman', 'lower-alpha', 'upper-alpha', 'none'), false);
- $this->info['list-style-image'] = $uri_or_none;
- $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config);
- $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum(
- array('capitalize', 'uppercase', 'lowercase', 'none'), false);
- $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color();
- $this->info['background-image'] = $uri_or_none;
- $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum(
- array('repeat', 'repeat-x', 'repeat-y', 'no-repeat')
- );
- $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum(
- array('scroll', 'fixed')
- );
- $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition();
- $border_color =
- $this->info['border-top-color'] =
- $this->info['border-bottom-color'] =
- $this->info['border-left-color'] =
- $this->info['border-right-color'] =
- $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_Enum(array('transparent')),
- new HTMLPurifier_AttrDef_CSS_Color()
- ));
- $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config);
- $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color);
- $border_width =
- $this->info['border-top-width'] =
- $this->info['border-bottom-width'] =
- $this->info['border-left-width'] =
- $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
- new HTMLPurifier_AttrDef_CSS_Length(true)
- ));
- $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
- $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_Enum(array('normal')),
- new HTMLPurifier_AttrDef_CSS_Length()
- ));
- $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_Enum(array('normal')),
- new HTMLPurifier_AttrDef_CSS_Length()
- ));
- $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_Enum(array('xx-small', 'x-small',
- 'small', 'medium', 'large', 'x-large', 'xx-large',
- 'larger', 'smaller')),
- new HTMLPurifier_AttrDef_CSS_Percentage(),
- new HTMLPurifier_AttrDef_CSS_Length()
- ));
- $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_Enum(array('normal')),
- new HTMLPurifier_AttrDef_CSS_Number(true),
- new HTMLPurifier_AttrDef_CSS_Length(true),
- new HTMLPurifier_AttrDef_CSS_Percentage(true)
- ));
- $margin =
- $this->info['margin-top'] =
- $this->info['margin-bottom'] =
- $this->info['margin-left'] =
- $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_CSS_Length(),
- new HTMLPurifier_AttrDef_CSS_Percentage(),
- new HTMLPurifier_AttrDef_Enum(array('auto'))
- ));
- $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin);
- $padding =
- $this->info['padding-top'] =
- $this->info['padding-bottom'] =
- $this->info['padding-left'] =
- $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_CSS_Length(true),
- new HTMLPurifier_AttrDef_CSS_Percentage(true)
- ));
- $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding);
- $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_CSS_Length(),
- new HTMLPurifier_AttrDef_CSS_Percentage()
- ));
- $this->info['width'] =
- $this->info['height'] =
- new HTMLPurifier_AttrDef_CSS_DenyElementDecorator(
- new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_CSS_Length(true),
- new HTMLPurifier_AttrDef_CSS_Percentage(true),
- new HTMLPurifier_AttrDef_Enum(array('auto'))
- )), 'img');
- $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
- $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();
- $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum(
- array('normal', 'bold', 'bolder', 'lighter', '100', '200', '300',
- '400', '500', '600', '700', '800', '900'), false);
- $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config);
- $this->info['border'] =
- $this->info['border-bottom'] =
- $this->info['border-top'] =
- $this->info['border-left'] =
- $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config);
- $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(array(
- 'collapse', 'separate'));
- $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(array(
- 'top', 'bottom'));
- $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(array(
- 'auto', 'fixed'));
- $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
- new HTMLPurifier_AttrDef_Enum(array('baseline', 'sub', 'super',
- 'top', 'text-top', 'middle', 'bottom', 'text-bottom')),
- new HTMLPurifier_AttrDef_CSS_Length(),
- new HTMLPurifier_AttrDef_CSS_Percentage()
- ));
- $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2);
- $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap'));
- if ($config->get('CSS', 'Proprietary')) {
- $this->doSetupProprietary($config);
- }
- if ($config->get('CSS', 'AllowTricky')) {
- $this->doSetupTricky($config);
- }
- $allow_important = $config->get('CSS', 'AllowImportant');
- foreach ($this->info as $k => $v) {
- $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important);
- }
- $this->setupConfigStuff($config);
- }
- protected function doSetupProprietary($config) {
- $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
- $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color();
- $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
- $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color();
- $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color();
- $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
- $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
- $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
- $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
- $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter();
- }
- protected function doSetupTricky($config) {
- $this->info['display'] = new HTMLPurifier_AttrDef_Enum(array(
- 'inline', 'block', 'list-item', 'run-in', 'compact',
- 'marker', 'table', 'inline-table', 'table-row-group',
- 'table-header-group', 'table-footer-group', 'table-row',
- 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none'
- ));
- $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(array(
- 'visible', 'hidden', 'collapse'
- ));
- }
- protected function setupConfigStuff($config) {
- $support = "(for information on implementing this, see the ".
- "support forums) ";
- $allowed_attributes = $config->get('CSS', 'AllowedProperties');
- if ($allowed_attributes !== null) {
- foreach ($this->info as $name => $d) {
- if(!isset($allowed_attributes[$name])) unset($this->info[$name]);
- unset($allowed_attributes[$name]);
- }
- foreach ($allowed_attributes as $name => $d) {
- $name = htmlspecialchars($name);
- trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING);
- }
- }
- }
- }
- abstract class HTMLPurifier_ChildDef
- {
- public $type;
- public $allow_empty;
- public $elements = array();
- abstract public function validateChildren($tokens_of_children, $config, $context);
- }
- class HTMLPurifier_Config
- {
- public $version = '3.1.0';
- public $autoFinalize = true;
- protected $serials = array();
- protected $serial;
- protected $conf;
- protected $parser;
- public $def;
- protected $definitions;
- protected $finalized = false;
- public function __construct($definition) {
- $this->conf = $definition->defaults;
- $this->def = $definition;
- $this->parser = new HTMLPurifier_VarParser_Flexible();
- }
- public static function create($config, $schema = null) {
- if ($config instanceof HTMLPurifier_Config) {
- return $config;
- }
- if (!$schema) {
- $ret = HTMLPurifier_Config::createDefault();
- } else {
- $ret = new HTMLPurifier_Config($schema);
- }
- if (is_string($config)) $ret->loadIni($config);
- elseif (is_array($config)) $ret->loadArray($config);
- return $ret;
- }
- public static function createDefault() {
- $definition = HTMLPurifier_ConfigSchema::instance();
- $config = new HTMLPurifier_Config($definition);
- return $config;
- }
- public function get($namespace, $key) {
- if (!$this->finalized && $this->autoFinalize) $this->finalize();
- if (!isset($this->def->info[$namespace][$key])) {
- trigger_error('Cannot retrieve value of undefined directive ' . htmlspecialchars("$namespace.$key"),
- E_USER_WARNING);
- return;
- }
- if ($this->def->info[$namespace][$key]->class == 'alias') {
- $d = $this->def->info[$namespace][$key];
- trigger_error('Cannot get value from aliased directive, use real name ' . $d->namespace . '.' . $d->name,
- E_USER_ERROR);
- return;
- }
- return $this->conf[$namespace][$key];
- }
- public function getBatch($namespace) {
- if (!$this->finalized && $this->autoFinalize) $this->finalize();
- if (!isset($this->def->info[$namespace])) {
- trigger_error('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace),
- E_USER_WARNING);
- return;
- }
- return $this->conf[$namespace];
- }
- public function getBatchSerial($namespace) {
- if (empty($this->serials[$namespace])) {
- $batch = $this->getBatch($namespace);
- unset($batch['DefinitionRev']);
- $this->serials[$namespace] = md5(serialize($batch));
- }
- return $this->serials[$namespace];
- }
- public function getSerial() {
- if (empty($this->serial)) {
- $this->serial = md5(serialize($this->getAll()));
- }
- return $this->serial;
- }
- public function getAll() {
- if (!$this->finalized && $this->autoFinalize) $this->finalize();
- return $this->conf;
- }
- public function set($namespace, $key, $value, $from_alias = false) {
- if ($this->isFinalized('Cannot set directive after finalization')) return;
- if (!isset($this->def->info[$namespace][$key])) {
- trigger_error('Cannot set undefined directive ' . htmlspecialchars("$namespace.$key") . ' to value',
- E_USER_WARNING);
- return;
- }
- if ($this->def->info[$namespace][$key]->class == 'alias') {
- if ($from_alias) {
- trigger_error('Double-aliases not allowed, please fix '.
- 'ConfigSchema bug with' . "$namespace.$key", E_USER_ERROR);
- return;
- }
- $this->set($new_ns = $this->def->info[$namespace][$key]->namespace,
- $new_dir = $this->def->info[$namespace][$key]->name,
- $value, true);
- trigger_error("$namespace.$key is an alias, preferred directive name is $new_ns.$new_dir", E_USER_NOTICE);
- return;
- }
- try {
- $value = $this->parser->parse(
- $value,
- $type = $this->def->info[$namespace][$key]->type,
- $this->def->info[$namespace][$key]->allow_null
- );
- } catch (HTMLPurifier_VarParserException $e) {
- trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . $type, E_USER_WARNING);
- return;
- }
- if (is_string($value)) {
- if (isset($this->def->info[$namespace][$key]->aliases[$value])) {
- $value = $this->def->info[$namespace][$key]->aliases[$value];
- }
- if ($this->def->info[$namespace][$key]->allowed !== true) {
- if (!isset($this->def->info[$namespace][$key]->allowed[$value])) {
- trigger_error('Value not supported, valid values are: ' .
- $this->_listify($this->def->info[$namespace][$key]->allowed), E_USER_WARNING);
- return;
- }
- }
- }
- $this->conf[$namespace][$key] = $value;
- if ($namespace == 'HTML' || $namespace == 'CSS') {
- $this->definitions[$namespace] = null;
- }
- $this->serials[$namespace] = false;
- }
- private function _listify($lookup) {
- $list = array();
- foreach ($lookup as $name => $b) $list[] = $name;
- return implode(', ', $list);
- }
- public function getHTMLDefinition($raw = false) {
- return $this->getDefinition('HTML', $raw);
- }
- public function getCSSDefinition($raw = false) {
- return $this->getDefinition('CSS', $raw);
- }
- public function getDefinition($type, $raw = false) {
- if (!$this->finalized && $this->autoFinalize) $this->finalize();
- $factory = HTMLPurifier_DefinitionCacheFactory::instance();
- $cache = $factory->create($type, $this);
- if (!$raw) {
- if (!empty($this->definitions[$type])) {
- if (!$this->definitions[$type]->setup) {
- $this->definitions[$type]->setup($this);
- $cache->set($this->definitions[$type], $this);
- }
- return $this->definitions[$type];
- }
- $this->definitions[$type] = $cache->get($this);
- if ($this->definitions[$type]) {
- return $this->definitions[$type];
- }
- } elseif (
- !empty($this->definitions[$type]) &&
- !$this->definitions[$type]->setup
- ) {
- return $this->definitions[$type];
- }
- if ($type == 'HTML') {
- $this->definitions[$type] = new HTMLPurifier_HTMLDefinition();
- } elseif ($type == 'CSS') {
- $this->definitions[$type] = new HTMLPurifier_CSSDefinition();
- } elseif ($type == 'URI') {
- $this->definitions[$type] = new HTMLPurifier_URIDefinition();
- } else {
- throw new HTMLPurifier_Exception("Definition of $type type not supported");
- }
- if ($raw) {
- if (is_null($this->get($type, 'DefinitionID'))) {
- throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID");
- }
- return $this->definitions[$type];
- }
- $this->definitions[$type]->setup($this);
- $cache->set($this->definitions[$type], $this);
- return $this->definitions[$type];
- }
- public function loadArray($config_array) {
- if ($this->isFinalized('Cannot load directives after finalization')) return;
- foreach ($config_array as $key => $value) {
- $key = str_replace('_', '.', $key);
- if (strpos($key, '.') !== false) {
- list($namespace, $directive) = explode('.', $key);
- $this->set($namespace, $directive, $value);
- } else {
- $namespace = $key;
- $namespace_values = $value;
- foreach ($namespace_values as $directive => $value) {
- $this->set($namespace, $directive, $value);
- }
- }
- }
- }
- public static function getAllowedDirectivesForForm($allowed, $schema = null) {
- if (!$schema) {
- $schema = HTMLPurifier_ConfigSchema::instance();
- }
- if ($allowed !== true) {
- if (is_string($allowed)) $allowed = array($allowed);
- $allowed_ns = array();
- $allowed_directives = array();
- $blacklisted_directives = array();
- foreach ($allowed as $ns_or_directive) {
- if (strpos($ns_or_directive, '.') !== false) {
- if ($ns_or_directive[0] == '-') {
- $blacklisted_directives[substr($ns_or_directive, 1)] = true;
- } else {
- $allowed_directives[$ns_or_directive] = true;
- }
- } else {
- $allowed_ns[$ns_or_directive] = true;
- }
- }
- }
- $ret = array();
- foreach ($schema->info as $ns => $keypairs) {
- foreach ($keypairs as $directive => $def) {
- if ($allowed !== true) {
- if (isset($blacklisted_directives["$ns.$directive"])) continue;
- if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
- }
- if ($def->class == 'alias') continue;
- if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
- $ret[] = array($ns, $directive);
- }
- }
- return $ret;
- }
- public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) {
- $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema);
- $config = HTMLPurifier_Config::create($ret, $schema);
- return $config;
- }
- public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true) {
- $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def);
- $this->loadArray($ret);
- }
- public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) {
- if ($index !== false) $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array();
- $mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc();
- $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema);
- $ret = array();
- foreach ($allowed as $key) {
- list($ns, $directive) = $key;
- $skey = "$ns.$directive";
- if (!empty($array["Null_$skey"])) {
- $ret[$ns][$directive] = null;
- continue;
- }
- if (!isset($array[$skey])) continue;
- $value = $mq ? stripslashes($array[$skey]) : $array[$skey];
- $ret[$ns][$directive] = $value;
- }
- return $ret;
- }
- public function loadIni($filename) {
- if ($this->isFinalized('Cannot load directives after finalization')) return;
- $array = parse_ini_file($filename, true);
- $this->loadArray($array);
- }
- public function isFinalized($error = false) {
- if ($this->finalized && $error) {
- trigger_error($error, E_USER_ERROR);
- }
- return $this->finalized;
- }
- public function autoFinalize() {
- if (!$this->finalized && $this->autoFinalize) $this->finalize();
- }
- public function finalize() {
- $this->finalized = true;
- }
- }
- abstract class HTMLPurifier_ConfigDef {
- public $class = false;
- }
- class HTMLPurifier_ConfigSchema {
- public $defaults = array();
- public $info = array();
- static protected $singleton;
- protected $parser;
- public function __construct() {
- $this->parser = new HTMLPurifier_VarParser_Flexible();
- }
- public static function makeFromSerial() {
- return unserialize(file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'));
- }
- public static function instance($prototype = null) {
- if ($prototype !== null) {
- HTMLPurifier_ConfigSchema::$singleton = $prototype;
- } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) {
- HTMLPurifier_ConfigSchema::$singleton = HTMLPurifier_ConfigSchema::makeFromSerial();
- }
- return HTMLPurifier_ConfigSchema::$singleton;
- }
- 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;
- }
- public function addNamespace($namespace) {
- $this->info[$namespace] = array();
- $this->defaults[$namespace] = array();
- }
- public function addValueAliases($namespace, $name, $aliases) {
- foreach ($aliases as $alias => $real) {
- $this->info[$namespace][$name]->aliases[$alias] = $real;
- }
- }
- public function addAllowedValues($namespace, $name, $allowed) {
- $type = $this->info[$namespace][$name]->type;
- $this->info[$namespace][$name]->allowed = $allowed;
- }
- public function addAlias($namespace, $name, $new_namespace, $new_name) {
- $this->info[$namespace][$name] = new HTMLPurifier_ConfigDef_DirectiveAlias($new_namespace, $new_name);
- }
- /** @see HTMLPurifier_ConfigSchema->set() */
- public static function define($namespace, $name, $default, $type, $description) {
- HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
- $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);
- }
- /** @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() */
- public function validate($a, $b, $c = false) {
- trigger_error("HTMLPurifier_ConfigSchema->validate deprecated, use HTMLPurifier_VarParser->parse instead", E_USER_NOTICE);
- return $this->parser->parse($a, $b, $c);
- }
- private static function deprecated($method) {
- trigger_error("Static HTMLPurifier_ConfigSchema::$method deprecated, use add*() method instead", E_USER_NOTICE);
- }
- }
- class HTMLPurifier_ContentSets
- {
- public $info = array();
- public $lookup = array();
- protected $keys = array();
- protected $values = array();
- public function __construct($modules) {
- if (!is_array($modules)) $modules = array($modules);
- foreach ($modules as $module_i => $module) {
- foreach ($module->content_sets as $key => $value) {
- if (isset($this->info[$key])) {
- $this->info[$key] = $this->info[$key] . ' | ' . $value;
- } else {
- $this->info[$key] = $value;
- }
- }
- }
- $this->keys = array_keys($this->info);
- foreach ($this->info as $i => $set) {
- $this->info[$i] =
- str_replace(
- $this->keys,
- array_values($this->info),
- $set);
- }
- $this->values = array_values($this->info);
- foreach ($this->info as $name => $set) {
- $this->lookup[$name] = $this->convertToLookup($set);
- }
- }
- public function generateChildDef(&$def, $module) {
- if (!empty($def->child)) return;
- $content_model = $def->content_model;
- if (is_string($content_model)) {
- $def->content_model = str_replace(
- $this->keys, $this->values, $content_model);
- }
- $def->child = $this->getChildDef($def, $module);
- }
- public function getChildDef($def, $module) {
- $value = $def->content_model;
- if (is_object($value)) {
- trigger_error(
- 'Literal object child definitions should be stored in '.
- 'ElementDef->child not ElementDef->content_model',
- E_USER_NOTICE
- );
- return $value;
- }
- switch ($def->content_model_type) {
- case 'required':
- return new HTMLPurifier_ChildDef_Required($value);
- case 'optional':
- return new HTMLPurifier_ChildDef_Optional($value);
- case 'empty':
- return new HTMLPurifier_ChildDef_Empty();
- case 'custom':
- return new HTMLPurifier_ChildDef_Custom($value);
- }
- $return = false;
- if ($module->defines_child_def) {
- $return = $module->getChildDef($def);
- }
- if ($return !== false) return $return;
- trigger_error(
- 'Could not determine which ChildDef class to instantiate',
- E_USER_ERROR
- );
- return false;
- }
- protected function convertToLookup($string) {
- $array = explode('|', str_replace(' ', '', $string));
- $ret = array();
- foreach ($array as $i => $k) {
- $ret[$k] = true;
- }
- return $ret;
- }
- }
- class HTMLPurifier_Context
- {
- private $_storage = array();
- public function register($name, &$ref) {
- if (isset($this->_storage[$name])) {
- trigger_error("Name $name produces collision, cannot re-register",
- E_USER_ERROR);
- return;
- }
- $this->_storage[$name] =& $ref;
- }
- public function &get($name, $ignore_error = false) {
- if (!isset($this->_storage[$name])) {
- if (!$ignore_error) {
- trigger_error("Attempted to retrieve non-existent variable $name",
- E_USER_ERROR);
- }
- $var = null;
- return $var;
- }
- return $this->_storage[$name];
- }
- public function destroy($name) {
- if (!isset($this->_storage[$name])) {
- trigger_error("Attempted to destroy non-existent variable $name",
- E_USER_ERROR);
- return;
- }
- unset($this->_storage[$name]);
- }
- public function exists($name) {
- return isset($this->_storage[$name]);
- }
- public function loadArray($context_array) {
- foreach ($context_array as $key => $discard) {
- $this->register($key, $context_array[$key]);
- }
- }
- }
- abstract class HTMLPurifier_DefinitionCache
- {
- public $type;
- public function __construct($type) {
- $this->type = $type;
- }
- public function generateKey($config) {
- return $config->version . ',' .
- $config->getBatchSerial($this->type) . ',' .
- $config->get($this->type, 'DefinitionRev');
- }
- public function isOld($key, $config) {
- if (substr_count($key, ',') < 2) return true;
- list($version, $hash, $revision) = explode(',', $key, 3);
- $compare = version_compare($version, $config->version);
- if ($compare != 0) return true;
- if (
- $hash == $config->getBatchSerial($this->type) &&
- $revision < $config->get($this->type, 'DefinitionRev')
- ) return true;
- return false;
- }
- public function checkDefType($def) {
- if ($def->type !== $this->type) {
- trigger_error("Cannot use definition of type {$def->type} in cache for {$this->type}");
- return false;
- }
- return true;
- }
- abstract public function add($def, $config);
- abstract public function set($def, $config);
- abstract public function replace($def, $config);
- abstract public function get($config);
- abstract public function remove($config);
- abstract public function flush($config);
- abstract public function cleanup($config);
- }
- class HTMLPurifier_DefinitionCacheFactory
- {
- protected $caches = array('Serializer' => array());
- protected $implementations = array();
- protected $decorators = array();
- public function setup() {
- $this->addDecorator('Cleanup');
- }
- public static function instance($prototype = null) {
- static $instance;
- if ($prototype !== null) {
- $instance = $prototype;
- } elseif ($instance === null || $prototype === true) {
- $instance = new HTMLPurifier_DefinitionCacheFactory();
- $instance->setup();
- }
- return $instance;
- }
- public function register($short, $long) {
- $this->implementations[$short] = $long;
- }
- public function create($type, $config) {
- $method = $config->get('Cache', 'DefinitionImpl');
- if ($method === null) {
- return new HTMLPurifier_DefinitionCache_Null($type);
- }
- if (!empty($this->caches[$method][$type])) {
- return $this->caches[$method][$type];
- }
- if (
- isset($this->implementations[$method]) &&
- class_exists($class = $this->implementations[$method], false)
- ) {
- $cache = new $class($type);
- } else {
- if ($method != 'Serializer') {
- trigger_error("Unrecognized DefinitionCache $method, using Serializer instead", E_USER_WARNING);
- }
- $cache = new HTMLPurifier_DefinitionCache_Serializer($type);
- }
- foreach ($this->decorators as $decorator) {
- $new_cache = $decorator->decorate($cache);
- unset($cache);
- $cache = $new_cache;
- }
- $this->caches[$method][$type] = $cache;
- return $this->caches[$method][$type];
- }
- public function addDecorator($decorator) {
- if (is_string($decorator)) {
- $class = "HTMLPurifier_DefinitionCache_Decorator_$decorator";
- $decorator = new $class;
- }
- $this->decorators[$decorator->name] = $decorator;
- }
- }
- class HTMLPurifier_Doctype
- {
- public $name;
- public $modules = array();
- public $tidyModules = array();
- public $xml = true;
- public $aliases = array();
- public $dtdPublic;
- public $dtdSystem;
- public function __construct($name = null, $xml = true, $modules = array(),
- $tidyModules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null
- ) {
- $this->name = $name;
- $this->xml = $xml;
- $this->modules = $modules;
- $this->tidyModules = $tidyModules;
- $this->aliases = $aliases;
- $this->dtdPublic = $dtd_public;
- $this->dtdSystem = …
Large files files are truncated, but you can click here to view the full file