diff --git a/.gitattributes b/.gitattributes index c0bcf3bdc..6b39d9fee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,13 +1,23 @@ /.gitattributes export-ignore +/.github export-ignore /.gitignore export-ignore -/.travis.yml export-ignore -/Doxyfile export-ignore -/art/ export-ignore -/benchmarks/ export-ignore -/configdoc/ export-ignore +/art export-ignore +/benchmarks export-ignore +/configdoc export-ignore /configdoc/usage.xml -crlf -/docs/ export-ignore -/phpdoc.ini -/smoketests/ export-ignore -/tests/* export-ignore -/tests/path2class.func.php -export-ignore +/docs export-ignore +/Doxyfile export-ignore +/extras export-ignore +/INSTALL* export-ignore +/maintenance export-ignore +/NEWS export-ignore +/package.php export-ignore +/plugins export-ignore +/phpdoc.ini export-ignore +/smoketests export-ignore +/test-* export-ignore +/tests export-ignore +/TODO export-ignore +/update-for-release export-ignore +/WYSIWYG export-ignore +/release.config.js export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..f0048048d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: ci + +on: + push: + pull_request: + +jobs: + linux_tests: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + + name: PHP ${{ matrix.php }} + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + ini-values: error_reporting=E_ALL + extensions: iconv, bcmath, tidy, mbstring, intl + + - name: Install dependencies + run: composer install + + - name: Configure simpletest + run: cp test-settings.sample.php test-settings.php + + - name: Execute Unit tests + run: php tests/index.php diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml new file mode 100644 index 000000000..597a6ed7d --- /dev/null +++ b/.github/workflows/lint-pr.yml @@ -0,0 +1,19 @@ +name: "Lint PR" + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + name: Validate PR title + + runs-on: ubuntu-latest + + steps: + - uses: amannn/action-semantic-pull-request@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..eb2308a62 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: release + +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + + name: Release + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 5.5 + + - name: Run automated release process with semantic-release + uses: cycjimmy/semantic-release-action@v2 + with: + extra_plugins: | + @semantic-release/changelog + @semantic-release/git + @semantic-release/exec + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b44c52a98..000000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: php -php: - - '5.6' - - '7.0' - - '7.1' - - '7.2' - - '7.3' - - '7.4' -matrix: - include: - - php: '5.4' - dist: trusty - - php: '5.5' - dist: trusty -before_script: - - git clone --depth=50 https://github.com/ezyang/simpletest.git - - cp test-settings.travis.php test-settings.php -script: - - php tests/index.php diff --git a/Doxyfile b/Doxyfile index fb53e475a..51d1fee4f 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 4.12.0 +PROJECT_NUMBER = 4.15.0 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/NEWS b/NEWS index 352835012..a1c98844c 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,52 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier . Internal change ========================== +4.15.0, released 2022-09-18 +! PHP 8.1 and 8.2 support, esp. fixes for deprecation warnings. A joint effort + by David Rans, Tim Düsterhus, Kieran and John Flatness. +! Allow contenteditable="false" (#336), contributed by Kieran. +- Replace PHP 8.1 deprecated utf8_ functions with mbstring (#326), + contributed by John Flatness. +- Enhanced composer suggestions with extensions (#317), contributed by + func0der. + +4.14.0, released 2021-12-24 +! Add "background-size" support (#289), contributed by Václav Smítal +! Transform deprecated width attribute when tidying HTML, contributed by + Kieran. +- PHP 8 support, contributed by Maksims Sļotovs. +- Improved PHP 7.3 compatibility, contributed by kishor. +- Avoid spurious magic quotes notice in PHP 7.4. Thanks + Jasper Zonneveld for the fix. +- Do not remove thead from table even if there are no tbody/tr (#264). + Thanks Marcus Artner for the fix. +- Fix "Parameter must be an array or an object that implements + Countable" (#285)". Thanks Kieran for this fix. +. Fix unnecessary reference assignment, handling behavior change from + PHP5 and PHP7. Thanks Arkadiusz Biczewski for the fix. + +4.13.0, released 2020-06-28 +! Add %HTML.Forms directive, which lets you accept forms in user + HTML without requiring full %HTML.Trusted. Note that forms can + be (trivially) used to setup phishing; e.g., an attacker can + use CSS absolute positioning to overlay a form on top of a login + element, so please be sure to use this with care! Fixes #213. + Thanks Mateusz Turcza for contributing this feature. +! tr@bgcolor attribute is now supported. Thanks Kieran Brahney + for this enhancement. +- Further improvements to PHP 7.4 support, contributed by Witold + Wasiczko and Eloy Lafuente. +- Fix PSR-0 compatibility. Thanks Jordi Boggiano for contributing + part of this fix. +- Fix bug with purifyArray where it doesn't work on empty arrays. + Thanks Fräntz Miccoli for the fix. +- Reduce amount of maintenance scripts included in distribution + packages. Thanks Sergei Morozov for this patch. +- Remove leading zeros unless if it is only a zero, fixes #239. Thanks + lubomirbartos for this fix. +- Correct type hinting of maybeGet*, fixes #240. Thanks Anders Jenbo + for this fix. + 4.12.0, released 2019-10-27 ! PHP 7.4 is supported, thank you Witold Wasiczko, Mateuz Turcza and Edi Modrić diff --git a/README.md b/README.md index 9e0becc0a..e6b7199c1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -HTML Purifier [![Build Status](https://secure.travis-ci.org/ezyang/htmlpurifier.svg?branch=master)](http://travis-ci.org/ezyang/htmlpurifier) +HTML Purifier [![Build Status](https://github.com/ezyang/htmlpurifier/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ezyang/htmlpurifier/actions/workflows/ci.yml) ============= HTML Purifier is an HTML filtering solution that uses a unique combination diff --git a/VERSION b/VERSION index bcd250ed0..f029ee574 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.12.0 \ No newline at end of file +4.15.0 \ No newline at end of file diff --git a/WHATSNEW b/WHATSNEW deleted file mode 100644 index aec9b37c1..000000000 --- a/WHATSNEW +++ /dev/null @@ -1,2 +0,0 @@ -HTML Purifier 4.12.x is a maintenance release which makes -compatibility fixes for PHP 7.4. diff --git a/composer.json b/composer.json index 0ff86b5df..d75582950 100644 --- a/composer.json +++ b/composer.json @@ -13,10 +13,11 @@ } ], "require": { - "php": ">=5.2" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" }, "require-dev": { - "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd" + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" }, "autoload": { "psr-0": { "HTMLPurifier": "library/" }, @@ -24,5 +25,20 @@ "exclude-from-classmap": [ "/library/HTMLPurifier/Language/" ] - } + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-tidy": "Used for pretty-printing HTML" + }, + "config": { + "sort-packages": true + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/ezyang/simpletest.git" + } + ] } diff --git a/configdoc/usage.xml b/configdoc/usage.xml index 65c34638b..9767c7af6 100644 --- a/configdoc/usage.xml +++ b/configdoc/usage.xml @@ -5,8 +5,8 @@ 162 - 85 - 326 + 90 + 331 67 @@ -19,37 +19,37 @@ - 240 + 256 - 365 + 381 - 369 + 385 - 373 + 389 - 377 + 393 - 506 + 522 - 522 + 538 @@ -124,7 +124,7 @@ 122 - 308 + 313 @@ -172,8 +172,11 @@ 234 - 313 - 353 + 318 + 358 + + + 8 37 @@ -250,12 +253,12 @@ - 80 + 85 - 84 + 89 62 @@ -263,23 +266,23 @@ - 215 - 337 + 220 + 342 - 324 + 329 - 347 + 352 - 351 + 356 36 @@ -287,12 +290,12 @@ - 352 + 357 - 353 + 358 35 @@ -451,7 +454,7 @@ - 53 + 58 @@ -480,6 +483,11 @@ 330 + + + 31 + + 28 diff --git a/extras/FSTools.php b/extras/FSTools.php index ce0076316..90d0f986a 100644 --- a/extras/FSTools.php +++ b/extras/FSTools.php @@ -136,7 +136,7 @@ public function rmdirr($dirname) /** * Recursively globs a directory. */ - public function globr($dir, $pattern, $flags = NULL) + public function globr($dir, $pattern, $flags = 0) { $files = $this->glob("$dir/$pattern", $flags); if ($files === false) $files = array(); diff --git a/library/HTMLPurifier.autoload-legacy.php b/library/HTMLPurifier.autoload-legacy.php index c271cd158..0a17ee4ad 100644 --- a/library/HTMLPurifier.autoload-legacy.php +++ b/library/HTMLPurifier.autoload-legacy.php @@ -4,12 +4,11 @@ * @file * Legacy autoloader for systems lacking spl_autoload_register * - * Must be separate to prevent deprecation warning on PHP 7.2 */ -function __autoload($class) +spl_autoload_register(function($class) { - return HTMLPurifier_Bootstrap::autoload($class); -} + return HTMLPurifier_Bootstrap::autoload($class); +}); // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier.autoload.php b/library/HTMLPurifier.autoload.php index 9d8d29926..7a691132f 100644 --- a/library/HTMLPurifier.autoload.php +++ b/library/HTMLPurifier.autoload.php @@ -17,6 +17,7 @@ require dirname(__FILE__) . '/HTMLPurifier.autoload-legacy.php'; } +// phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.zend_ze1_compatibility_modeRemoved if (ini_get('zend.ze1_compatibility_mode')) { trigger_error("HTML Purifier is not compatible with zend.ze1_compatibility_mode; please turn it off", E_USER_ERROR); } diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index 3158b2b86..47ee0133d 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -7,7 +7,7 @@ * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * FILE, changes will be overwritten the next time the script is run. * - * @version 4.12.0 + * @version 4.15.0 * * @warning * You must *not* include any other HTML Purifier files before this file, @@ -107,6 +107,7 @@ require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php'; require 'HTMLPurifier/AttrDef/HTML/Class.php'; require 'HTMLPurifier/AttrDef/HTML/Color.php'; +require 'HTMLPurifier/AttrDef/HTML/ContentEditable.php'; require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php'; require 'HTMLPurifier/AttrDef/HTML/ID.php'; require 'HTMLPurifier/AttrDef/HTML/Pixels.php'; diff --git a/library/HTMLPurifier.php b/library/HTMLPurifier.php index 10e61c149..26f061276 100644 --- a/library/HTMLPurifier.php +++ b/library/HTMLPurifier.php @@ -19,7 +19,7 @@ */ /* - HTML Purifier 4.12.0 - Standards Compliant HTML Filtering + HTML Purifier 4.15.0 - Standards Compliant HTML Filtering Copyright (C) 2006-2008 Edward Z. Yang This library is free software; you can redistribute it and/or @@ -58,12 +58,12 @@ class HTMLPurifier * Version of HTML Purifier. * @type string */ - public $version = '4.12.0'; + public $version = '4.15.0'; /** * Constant with version of HTML Purifier. */ - const VERSION = '4.12.0'; + const VERSION = '4.15.0'; /** * Global configuration object. diff --git a/library/HTMLPurifier.safe-includes.php b/library/HTMLPurifier.safe-includes.php index a3261f8a3..94543f593 100644 --- a/library/HTMLPurifier.safe-includes.php +++ b/library/HTMLPurifier.safe-includes.php @@ -101,6 +101,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php'; +require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ContentEditable.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php'; diff --git a/library/HTMLPurifier/AttrDef/CSS/Background.php b/library/HTMLPurifier/AttrDef/CSS/Background.php index 7f1ea3b0f..28c49883a 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Background.php +++ b/library/HTMLPurifier/AttrDef/CSS/Background.php @@ -25,6 +25,7 @@ public function __construct($config) $this->info['background-repeat'] = $def->info['background-repeat']; $this->info['background-attachment'] = $def->info['background-attachment']; $this->info['background-position'] = $def->info['background-position']; + $this->info['background-size'] = $def->info['background-size']; } /** @@ -53,6 +54,7 @@ public function validate($string, $config, $context) $caught['repeat'] = false; $caught['attachment'] = false; $caught['position'] = false; + $caught['size'] = false; $i = 0; // number of catches diff --git a/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php b/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php new file mode 100644 index 000000000..5b03d3e37 --- /dev/null +++ b/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php @@ -0,0 +1,16 @@ +get('HTML.Trusted')) { + $allowed = array('', 'true', 'false'); + } + + $enum = new HTMLPurifier_AttrDef_Enum($allowed); + + return $enum->validate($string, $config, $context); + } +} diff --git a/library/HTMLPurifier/AttrDef/URI/Host.php b/library/HTMLPurifier/AttrDef/URI/Host.php index 1beeaa5d2..ddc5dfbea 100644 --- a/library/HTMLPurifier/AttrDef/URI/Host.php +++ b/library/HTMLPurifier/AttrDef/URI/Host.php @@ -106,7 +106,7 @@ public function validate($string, $config, $context) // If we have Net_IDNA2 support, we can support IRIs by // punycoding them. (This is the most portable thing to do, // since otherwise we have to assume browsers support - } elseif ($config->get('Core.EnableIDNA')) { + } elseif ($config->get('Core.EnableIDNA') && class_exists('Net_IDNA2')) { $idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true)); // we need to encode each period separately $parts = explode('.', $string); diff --git a/library/HTMLPurifier/AttrTransform/NameSync.php b/library/HTMLPurifier/AttrTransform/NameSync.php index 36079b786..5a1fdbbfc 100644 --- a/library/HTMLPurifier/AttrTransform/NameSync.php +++ b/library/HTMLPurifier/AttrTransform/NameSync.php @@ -8,6 +8,11 @@ class HTMLPurifier_AttrTransform_NameSync extends HTMLPurifier_AttrTransform { + /** + * @type HTMLPurifier_AttrDef_HTML_ID + */ + public $idDef; + public function __construct() { $this->idDef = new HTMLPurifier_AttrDef_HTML_ID(); diff --git a/library/HTMLPurifier/AttrTransform/SafeParam.php b/library/HTMLPurifier/AttrTransform/SafeParam.php index 1143b4b49..1033106b3 100644 --- a/library/HTMLPurifier/AttrTransform/SafeParam.php +++ b/library/HTMLPurifier/AttrTransform/SafeParam.php @@ -24,6 +24,11 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform */ private $uri; + /** + * @type HTMLPurifier_AttrDef_Enum + */ + public $wmode; + public function __construct() { $this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded diff --git a/library/HTMLPurifier/AttrTypes.php b/library/HTMLPurifier/AttrTypes.php index 3b70520b6..e4429e86d 100644 --- a/library/HTMLPurifier/AttrTypes.php +++ b/library/HTMLPurifier/AttrTypes.php @@ -41,6 +41,7 @@ public function __construct() $this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right'); $this->info['LAlign'] = self::makeEnum('top,bottom,left,right'); $this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget(); + $this->info['ContentEditable'] = new HTMLPurifier_AttrDef_HTML_ContentEditable(); // unimplemented aliases $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text(); diff --git a/library/HTMLPurifier/Bootstrap.php b/library/HTMLPurifier/Bootstrap.php index 707122bb2..bd8f9984f 100644 --- a/library/HTMLPurifier/Bootstrap.php +++ b/library/HTMLPurifier/Bootstrap.php @@ -79,44 +79,11 @@ public static function getPath($class) public static function registerAutoload() { $autoload = array('HTMLPurifier_Bootstrap', 'autoload'); - if (($funcs = spl_autoload_functions()) === false) { + if (spl_autoload_functions() === false) { spl_autoload_register($autoload); - } elseif (function_exists('spl_autoload_unregister')) { - if (version_compare(PHP_VERSION, '5.3.0', '>=')) { - // prepend flag exists, no need for shenanigans - spl_autoload_register($autoload, true, true); - } else { - $buggy = version_compare(PHP_VERSION, '5.2.11', '<'); - $compat = version_compare(PHP_VERSION, '5.1.2', '<=') && - version_compare(PHP_VERSION, '5.1.0', '>='); - foreach ($funcs as $func) { - if ($buggy && is_array($func)) { - // :TRICKY: There are some compatibility issues and some - // places where we need to error out - $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.' - ); - } - // Suprisingly, spl_autoload_register supports the - // Class::staticMethod callback format, although call_user_func doesn't - if ($compat) { - $func = implode('::', $func); - } - } - spl_autoload_unregister($func); - } - spl_autoload_register($autoload); - foreach ($funcs as $func) { - spl_autoload_register($func); - } - } + } else { + // prepend flag exists, no need for shenanigans + spl_autoload_register($autoload, true, true); } } } diff --git a/library/HTMLPurifier/CSSDefinition.php b/library/HTMLPurifier/CSSDefinition.php index 21f1a5899..1bc419c53 100644 --- a/library/HTMLPurifier/CSSDefinition.php +++ b/library/HTMLPurifier/CSSDefinition.php @@ -13,7 +13,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition * Assoc array of attribute name to definition object. * @type HTMLPurifier_AttrDef[] */ - public $info = array(); + public $info = []; /** * Constructs the info array. The meat of this class. @@ -22,7 +22,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition protected function doSetup($config) { $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( - array('left', 'right', 'center', 'justify'), + ['left', 'right', 'center', 'justify'], false ); @@ -31,7 +31,7 @@ protected function doSetup($config) $this->info['border-right-style'] = $this->info['border-left-style'] = $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'none', 'hidden', 'dotted', @@ -42,42 +42,42 @@ protected function doSetup($config) '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'), + ['none', 'left', 'right', 'both'], false ); $this->info['float'] = new HTMLPurifier_AttrDef_Enum( - array('none', 'left', 'right'), + ['none', 'left', 'right'], false ); $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( - array('normal', 'italic', 'oblique'), + ['normal', 'italic', 'oblique'], false ); $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( - array('normal', 'small-caps'), + ['normal', 'small-caps'], false ); $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( - array( - new HTMLPurifier_AttrDef_Enum(array('none')), + [ + new HTMLPurifier_AttrDef_Enum(['none']), new HTMLPurifier_AttrDef_CSS_URI() - ) + ] ); $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( - array('inside', 'outside'), + ['inside', 'outside'], false ); $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'disc', 'circle', 'square', @@ -87,7 +87,7 @@ protected function doSetup($config) 'lower-alpha', 'upper-alpha', 'none' - ), + ], false ); $this->info['list-style-image'] = $uri_or_none; @@ -95,30 +95,46 @@ protected function doSetup($config) $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( - array('capitalize', 'uppercase', 'lowercase', 'none'), + ['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') + ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] ); $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( - array('scroll', 'fixed') + ['scroll', 'fixed'] ); $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); + $this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum( + [ + 'auto', + 'cover', + 'contain', + 'initial', + 'inherit', + ] + ), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_CSS_Length() + ] + ); + $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_Enum(['transparent']), new HTMLPurifier_AttrDef_CSS_Color() - ) + ] ); $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); @@ -130,32 +146,32 @@ protected function doSetup($config) $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_Enum(['thin', 'medium', 'thick']), new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative - ) + ] ); $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_Enum(['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_Enum(['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', @@ -165,20 +181,20 @@ protected function doSetup($config) '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_Enum(['normal']), new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true) - ) + ] ); $margin = @@ -186,11 +202,11 @@ protected function doSetup($config) $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')) - ) + new HTMLPurifier_AttrDef_Enum(['auto']) + ] ); $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); @@ -201,41 +217,41 @@ protected function doSetup($config) $this->info['padding-bottom'] = $this->info['padding-left'] = $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), 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() - ) + ] ); $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('auto', 'initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['auto', 'initial', 'inherit']) + ] ); $trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['initial', 'inherit']) + ] ); $trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit']) + ] ); $max = $config->get('CSS.MaxImgLength'); @@ -247,10 +263,10 @@ protected function doSetup($config) 'img', // For img tags: new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0', $max), - new HTMLPurifier_AttrDef_Enum(array('auto')) - ) + new HTMLPurifier_AttrDef_Enum(['auto']) + ] ), // For everyone else: $trusted_wh @@ -263,10 +279,10 @@ protected function doSetup($config) 'img', // For img tags: new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0', $max), - new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['initial', 'inherit']) + ] ), // For everyone else: $trusted_min_wh @@ -279,22 +295,39 @@ protected function doSetup($config) 'img', // For img tags: new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0', $max), - new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit']) + ] ), // For everyone else: $trusted_max_wh ); + // text-decoration and related shorthands $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); + $this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum( + ['none', 'underline', 'overline', 'line-through', 'initial', 'inherit'] + ); + + $this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum( + ['solid', 'double', 'dotted', 'dashed', 'wavy', 'initial', 'inherit'] + ); + + $this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + $this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([ + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(['auto', 'from-font', 'initial', 'inherit']) + ]); + $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); // this could use specialized code $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'normal', 'bold', 'bolder', @@ -308,7 +341,7 @@ protected function doSetup($config) '700', '800', '900' - ), + ], false ); @@ -324,21 +357,21 @@ protected function doSetup($config) $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( - array('collapse', 'separate') + ['collapse', 'separate'] ); $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( - array('top', 'bottom') + ['top', 'bottom'] ); $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( - array('auto', 'fixed') + ['auto', 'fixed'] ); $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_Enum( - array( + [ 'baseline', 'sub', 'super', @@ -347,11 +380,11 @@ protected function doSetup($config) '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); @@ -359,7 +392,7 @@ protected function doSetup($config) // These CSS properties don't work on many browsers, but we live // in THE FUTURE! $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( - array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line') + ['nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line'] ); if ($config->get('CSS.Proprietary')) { @@ -406,21 +439,21 @@ protected function doSetupProprietary($config) // more CSS3 $this->info['page-break-after'] = $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'auto', 'always', 'avoid', 'left', 'right' - ) + ] ); - $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid')); + $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(['auto', 'avoid']); $border_radius = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative - )); + ]); $this->info['border-top-left-radius'] = $this->info['border-top-right-radius'] = @@ -437,7 +470,7 @@ protected function doSetupProprietary($config) protected function doSetupTricky($config) { $this->info['display'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'inline', 'block', 'list-item', @@ -456,12 +489,12 @@ protected function doSetupTricky($config) 'table-cell', 'table-caption', 'none' - ) + ] ); $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( - array('visible', 'hidden', 'collapse') + ['visible', 'hidden', 'collapse'] ); - $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll')); + $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(['visible', 'hidden', 'auto', 'scroll']); $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); } @@ -471,23 +504,23 @@ protected function doSetupTricky($config) protected function doSetupTrusted($config) { $this->info['position'] = new HTMLPurifier_AttrDef_Enum( - array('static', 'relative', 'absolute', 'fixed') + ['static', 'relative', 'absolute', 'fixed'] ); $this->info['top'] = $this->info['left'] = $this->info['right'] = $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage(), - new HTMLPurifier_AttrDef_Enum(array('auto')), - ) + new HTMLPurifier_AttrDef_Enum(['auto']), + ] ); $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_Integer(), - new HTMLPurifier_AttrDef_Enum(array('auto')), - ) + new HTMLPurifier_AttrDef_Enum(['auto']), + ] ); } diff --git a/library/HTMLPurifier/ChildDef/List.php b/library/HTMLPurifier/ChildDef/List.php index 4fc70e0ef..3d584e727 100644 --- a/library/HTMLPurifier/ChildDef/List.php +++ b/library/HTMLPurifier/ChildDef/List.php @@ -22,6 +22,8 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef // XXX: This whole business with 'wrap' is all a bit unsatisfactory public $elements = array('li' => true, 'ul' => true, 'ol' => true); + public $whitespace; + /** * @param array $children * @param HTMLPurifier_Config $config diff --git a/library/HTMLPurifier/ChildDef/Table.php b/library/HTMLPurifier/ChildDef/Table.php index cb6b3e6cd..67c7e9535 100644 --- a/library/HTMLPurifier/ChildDef/Table.php +++ b/library/HTMLPurifier/ChildDef/Table.php @@ -164,7 +164,7 @@ public function validateChildren($children, $config, $context) } } - if (empty($content)) { + if (empty($content) && $thead === false && $tfoot === false) { return false; } diff --git a/library/HTMLPurifier/Config.php b/library/HTMLPurifier/Config.php index 4ecaa141a..797d26877 100644 --- a/library/HTMLPurifier/Config.php +++ b/library/HTMLPurifier/Config.php @@ -21,7 +21,7 @@ class HTMLPurifier_Config * HTML Purifier's version * @type string */ - public $version = '4.12.0'; + public $version = '4.15.0'; /** * Whether or not to automatically finalize @@ -803,7 +803,7 @@ public static function prepareArrayFromForm($array, $index = false, $allowed = t 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(); + $mq = $mq_fix && version_compare(PHP_VERSION, '7.4.0', '<') && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema); $ret = array(); diff --git a/library/HTMLPurifier/ConfigSchema/schema.ser b/library/HTMLPurifier/ConfigSchema/schema.ser index 47bd259b2..a5426c736 100644 --- a/library/HTMLPurifier/ConfigSchema/schema.ser +++ b/library/HTMLPurifier/ConfigSchema/schema.ser @@ -1 +1 @@ -O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:126:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:126:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:139:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:13:"Attr.ID.HTML5";i:-7;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:32:"AutoFormat.RemoveEmpty.Predicate";i:10;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:19:"CSS.AllowDuplicates";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:-5;s:22:"Core.AggressivelyFixLt";i:7;s:29:"Core.AggressivelyRemoveScript";i:7;s:28:"Core.AllowHostnameUnderscore";i:7;s:23:"Core.AllowParseManyTags";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:20:"Core.DisableExcludes";i:7;s:15:"Core.EnableIDNA";i:7;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:24:"Core.LegacyEntityDecoder";i:7;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedComments";i:8;s:26:"HTML.AllowedCommentsRegexp";i:-1;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeIframe";i:7;s:15:"HTML.SafeObject";i:7;s:18:"HTML.SafeScripting";i:8;s:11:"HTML.Strict";i:7;s:16:"HTML.TargetBlank";i:7;s:19:"HTML.TargetNoopener";i:7;s:21:"HTML.TargetNoreferrer";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:-1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;s:20:"URI.SafeIframeRegexp";i:-1;}} \ No newline at end of file +O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:127:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:10:"HTML.Forms";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:127:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:10:"HTML.Forms";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:140:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:13:"Attr.ID.HTML5";i:-7;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:32:"AutoFormat.RemoveEmpty.Predicate";i:10;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:19:"CSS.AllowDuplicates";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:-5;s:22:"Core.AggressivelyFixLt";i:7;s:29:"Core.AggressivelyRemoveScript";i:7;s:28:"Core.AllowHostnameUnderscore";i:7;s:23:"Core.AllowParseManyTags";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:20:"Core.DisableExcludes";i:7;s:15:"Core.EnableIDNA";i:7;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:24:"Core.LegacyEntityDecoder";i:7;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedComments";i:8;s:26:"HTML.AllowedCommentsRegexp";i:-1;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:10:"HTML.Forms";i:7;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeIframe";i:7;s:15:"HTML.SafeObject";i:7;s:18:"HTML.SafeScripting";i:8;s:11:"HTML.Strict";i:7;s:16:"HTML.TargetBlank";i:7;s:19:"HTML.TargetNoopener";i:7;s:21:"HTML.TargetNoreferrer";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:-1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;s:20:"URI.SafeIframeRegexp";i:-1;}} \ No newline at end of file diff --git a/library/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt b/library/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt new file mode 100644 index 000000000..4a432d89b --- /dev/null +++ b/library/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt @@ -0,0 +1,11 @@ +HTML.Forms +TYPE: bool +VERSION: 4.13.0 +DEFAULT: false +--DESCRIPTION-- +

+ Whether or not to permit form elements in the user input, regardless of + %HTML.Trusted value. Please be very careful when using this functionality, as + enabling forms in untrusted documents may allow for phishing attacks. +

+--# vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ElementDef.php b/library/HTMLPurifier/ElementDef.php index d5311cedc..57cfd2bb0 100644 --- a/library/HTMLPurifier/ElementDef.php +++ b/library/HTMLPurifier/ElementDef.php @@ -176,7 +176,7 @@ public function mergeIn($def) if (!empty($def->content_model)) { $this->content_model = - str_replace("#SUPER", $this->content_model, $def->content_model); + str_replace("#SUPER", (string)$this->content_model, $def->content_model); $this->child = false; } if (!empty($def->content_model_type)) { diff --git a/library/HTMLPurifier/Encoder.php b/library/HTMLPurifier/Encoder.php index 40a24266a..d4791cc1b 100644 --- a/library/HTMLPurifier/Encoder.php +++ b/library/HTMLPurifier/Encoder.php @@ -398,8 +398,8 @@ public static function convertToUTF8($str, $config, $context) // characters to their true byte-wise ASCII/UTF-8 equivalents. $str = strtr($str, self::testEncodingSupportsASCII($encoding)); return $str; - } elseif ($encoding === 'iso-8859-1') { - $str = utf8_encode($str); + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1'); return $str; } $bug = HTMLPurifier_Encoder::testIconvTruncateBug(); @@ -450,8 +450,8 @@ public static function convertFromUTF8($str, $config, $context) // Normal stuff $str = self::iconv('utf-8', $encoding . '//IGNORE', $str); return $str; - } elseif ($encoding === 'iso-8859-1') { - $str = utf8_decode($str); + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8'); return $str; } trigger_error('Encoding not supported', E_USER_ERROR); diff --git a/library/HTMLPurifier/HTMLModule.php b/library/HTMLPurifier/HTMLModule.php index 6d898f80c..9dbb98729 100644 --- a/library/HTMLPurifier/HTMLModule.php +++ b/library/HTMLPurifier/HTMLModule.php @@ -257,8 +257,9 @@ public function mergeInAttrIncludes(&$attr, $attr_includes) */ public function makeLookup($list) { + $args = func_get_args(); if (is_string($list)) { - $list = func_get_args(); + $list = $args; } $ret = array(); foreach ($list as $value) { diff --git a/library/HTMLPurifier/HTMLModule/CommonAttributes.php b/library/HTMLPurifier/HTMLModule/CommonAttributes.php index a96ab1bef..7220c14cc 100644 --- a/library/HTMLPurifier/HTMLModule/CommonAttributes.php +++ b/library/HTMLPurifier/HTMLModule/CommonAttributes.php @@ -17,6 +17,7 @@ class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule 'class' => 'Class', 'id' => 'ID', 'title' => 'CDATA', + 'contenteditable' => 'ContentEditable', ), 'Lang' => array(), 'I18N' => array( diff --git a/library/HTMLPurifier/HTMLModule/Forms.php b/library/HTMLPurifier/HTMLModule/Forms.php index 6f7ddbc05..eb0edcffd 100644 --- a/library/HTMLPurifier/HTMLModule/Forms.php +++ b/library/HTMLPurifier/HTMLModule/Forms.php @@ -28,6 +28,10 @@ class HTMLPurifier_HTMLModule_Forms extends HTMLPurifier_HTMLModule */ public function setup($config) { + if ($config->get('HTML.Forms')) { + $this->safe = true; + } + $form = $this->addElement( 'form', 'Form', diff --git a/library/HTMLPurifier/HTMLModule/Tidy.php b/library/HTMLPurifier/HTMLModule/Tidy.php index 08aa23247..76fd93a6c 100644 --- a/library/HTMLPurifier/HTMLModule/Tidy.php +++ b/library/HTMLPurifier/HTMLModule/Tidy.php @@ -146,10 +146,7 @@ public function populate($fixes) $type = "info_$type"; $e = $this; } - // PHP does some weird parsing when I do - // $e->$type[$attr], so I have to assign a ref. - $f =& $e->$type; - $f[$attr] = $fix; + $e->{$type}[$attr] = $fix; break; case 'tag_transform': $this->info_tag_transform[$params['element']] = $fix; @@ -224,6 +221,7 @@ public function getFixType($name) */ public function makeFixes() { + return array(); } } diff --git a/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php b/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php index 700a25dbc..9ee3ffcc9 100644 --- a/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php +++ b/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php @@ -168,9 +168,11 @@ public function makeFixes() // @vspace for img ------------------------------------------------ $r['img@vspace'] = new HTMLPurifier_AttrTransform_ImgSpace('vspace'); - // @width for hr, td, th ------------------------------------------ + // @width for table, hr, td, th, col ------------------------------------------ + $r['table@width'] = $r['td@width'] = $r['th@width'] = + $r['col@width'] = $r['hr@width'] = new HTMLPurifier_AttrTransform_Length('width'); return $r; diff --git a/library/HTMLPurifier/Injector/Linkify.php b/library/HTMLPurifier/Injector/Linkify.php index 74f83eaa7..3b6d70f6e 100644 --- a/library/HTMLPurifier/Injector/Linkify.php +++ b/library/HTMLPurifier/Injector/Linkify.php @@ -40,6 +40,9 @@ public function handleText(&$token) '/\\b((?:[a-z][\\w\\-]+:(?:\\/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}\\/)(?:[^\\s()<>]|\\((?:[^\\s()<>]|(?:\\([^\\s()<>]+\\)))*\\))+(?:\\((?:[^\\s()<>]|(?:\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:\'".,<>?\x{00ab}\x{00bb}\x{201c}\x{201d}\x{2018}\x{2019}]))/iu', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE); + if ($bits === false) { + return; + } $token = array(); diff --git a/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php b/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php index 9ee7aa84d..42d514447 100644 --- a/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php +++ b/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php @@ -31,6 +31,16 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In */ private $context; + /** + * @type SplObjectStorage + */ + private $markForDeletion; + + public function __construct() + { + $this->markForDeletion = new SplObjectStorage(); + } + public function prepare($config, $context) { $this->attrValidator = new HTMLPurifier_AttrValidator(); @@ -64,7 +74,7 @@ public function handleElement(&$token) if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') { // Mark closing span tag for deletion - $current->markForDeletion = true; + $this->markForDeletion->attach($current); // Delete open span tag $token = false; } @@ -75,7 +85,8 @@ public function handleElement(&$token) */ public function handleEnd(&$token) { - if ($token->markForDeletion) { + if ($this->markForDeletion->contains($token)) { + $this->markForDeletion->detach($token); $token = false; } } diff --git a/library/HTMLPurifier/Language/classes/en-x-test.php b/library/HTMLPurifier/Language/classes/en-x-test.php deleted file mode 100644 index 8828f5cde..000000000 --- a/library/HTMLPurifier/Language/classes/en-x-test.php +++ /dev/null @@ -1,9 +0,0 @@ - 'HTML Purifier X' -); - -$errorNames = array(); - -// vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Language/messages/en-x-testmini.php b/library/HTMLPurifier/Language/messages/en-x-testmini.php deleted file mode 100644 index e1e7db500..000000000 --- a/library/HTMLPurifier/Language/messages/en-x-testmini.php +++ /dev/null @@ -1,14 +0,0 @@ - 'HTML Purifier XNone' -); - -$errorNames = array(); - -// vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Length.php b/library/HTMLPurifier/Length.php index e70da55a9..b6ea12345 100644 --- a/library/HTMLPurifier/Length.php +++ b/library/HTMLPurifier/Length.php @@ -78,7 +78,7 @@ protected function validate() if ($this->n === '0' && $this->unit === false) { return true; } - if (!ctype_lower($this->unit)) { + if ($this->unit === false || !ctype_lower($this->unit)) { $this->unit = strtolower($this->unit); } if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) { diff --git a/library/HTMLPurifier/Lexer.php b/library/HTMLPurifier/Lexer.php index e9da3ed5e..c21f36491 100644 --- a/library/HTMLPurifier/Lexer.php +++ b/library/HTMLPurifier/Lexer.php @@ -48,6 +48,11 @@ class HTMLPurifier_Lexer */ public $tracksLineNumbers = false; + /** + * @type HTMLPurifier_EntityParser + */ + private $_entity_parser; + // -- STATIC ---------------------------------------------------------- /** @@ -306,8 +311,8 @@ public function normalize($html, $config, $context) { // normalize newlines to \n if ($config->get('Core.NormalizeNewlines')) { - $html = str_replace("\r\n", "\n", $html); - $html = str_replace("\r", "\n", $html); + $html = str_replace("\r\n", "\n", (string)$html); + $html = str_replace("\r", "\n", (string)$html); } if ($config->get('HTML.Trusted')) { diff --git a/library/HTMLPurifier/Lexer/DOMLex.php b/library/HTMLPurifier/Lexer/DOMLex.php index ca5f25b84..5e8104be9 100644 --- a/library/HTMLPurifier/Lexer/DOMLex.php +++ b/library/HTMLPurifier/Lexer/DOMLex.php @@ -104,7 +104,6 @@ public function tokenizeHTML($html, $config, $context) * To iterate is human, to recurse divine - L. Peter Deutsch * @param DOMNode $node DOMNode to be tokenized. * @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens. - * @return HTMLPurifier_Token of node appended to previously passed tokens. */ protected function tokenizeDOM($node, &$tokens, $config) { diff --git a/library/HTMLPurifier/Lexer/PH5P.php b/library/HTMLPurifier/Lexer/PH5P.php index 72476ddf3..1564f283d 100644 --- a/library/HTMLPurifier/Lexer/PH5P.php +++ b/library/HTMLPurifier/Lexer/PH5P.php @@ -4410,7 +4410,7 @@ private function insertElement($token, $append = true, $check = false) foreach ($token['attr'] as $attr) { if (!$el->hasAttribute($attr['name'])) { - $el->setAttribute($attr['name'], $attr['value']); + $el->setAttribute($attr['name'], (string)$attr['value']); } } diff --git a/library/HTMLPurifier/Printer/ConfigForm.php b/library/HTMLPurifier/Printer/ConfigForm.php index 33ae11397..4c3ce1758 100644 --- a/library/HTMLPurifier/Printer/ConfigForm.php +++ b/library/HTMLPurifier/Printer/ConfigForm.php @@ -32,6 +32,11 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer */ protected $compress = false; + /** + * @var HTMLPurifier_Config + */ + protected $genConfig; + /** * @param string $name Form element name for directives to be stuffed into * @param string $doc_url String documentation URL, will have fragment tagged on diff --git a/library/HTMLPurifier/PropertyListIterator.php b/library/HTMLPurifier/PropertyListIterator.php index 15b330ea3..f68fc8c30 100644 --- a/library/HTMLPurifier/PropertyListIterator.php +++ b/library/HTMLPurifier/PropertyListIterator.php @@ -29,6 +29,7 @@ public function __construct(Iterator $iterator, $filter = null) /** * @return bool */ + #[\ReturnTypeWillChange] public function accept() { $key = $this->getInnerIterator()->key(); diff --git a/library/HTMLPurifier/StringHash.php b/library/HTMLPurifier/StringHash.php index c07370197..c41ae3a76 100644 --- a/library/HTMLPurifier/StringHash.php +++ b/library/HTMLPurifier/StringHash.php @@ -20,6 +20,7 @@ class HTMLPurifier_StringHash extends ArrayObject * @param mixed $index * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($index) { $this->accessed[$index] = true; diff --git a/library/HTMLPurifier/URIFilter/HostBlacklist.php b/library/HTMLPurifier/URIFilter/HostBlacklist.php index a6645c17e..32197c0e6 100644 --- a/library/HTMLPurifier/URIFilter/HostBlacklist.php +++ b/library/HTMLPurifier/URIFilter/HostBlacklist.php @@ -35,7 +35,7 @@ public function prepare($config) public function filter(&$uri, $config, $context) { foreach ($this->blacklist as $blacklisted_host_fragment) { - if (strpos($uri->host, $blacklisted_host_fragment) !== false) { + if ($uri->host !== null && strpos($uri->host, $blacklisted_host_fragment) !== false) { return false; } } diff --git a/library/HTMLPurifier/URIFilter/Munge.php b/library/HTMLPurifier/URIFilter/Munge.php index 6e03315a1..e1393deb7 100644 --- a/library/HTMLPurifier/URIFilter/Munge.php +++ b/library/HTMLPurifier/URIFilter/Munge.php @@ -100,11 +100,11 @@ protected function makeReplace($uri, $config, $context) $string = $uri->toString(); // always available $this->replace['%s'] = $string; - $this->replace['%r'] = $context->get('EmbeddedURI', true); - $token = $context->get('CurrentToken', true); - $this->replace['%n'] = $token ? $token->name : null; - $this->replace['%m'] = $context->get('CurrentAttr', true); - $this->replace['%p'] = $context->get('CurrentCSSProperty', true); + $this->replace['%r'] = $context->get('EmbeddedURI', true) ?: ''; + $token = $context->get('CurrentToken', true) ?: ''; + $this->replace['%n'] = $token ? $token->name : ''; + $this->replace['%m'] = $context->get('CurrentAttr', true) ?: ''; + $this->replace['%p'] = $context->get('CurrentCSSProperty', true) ?: ''; // not always available if ($this->secretKey) { $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); diff --git a/library/HTMLPurifier/URIScheme/tel.php b/library/HTMLPurifier/URIScheme/tel.php index 8cd193352..1ea122269 100644 --- a/library/HTMLPurifier/URIScheme/tel.php +++ b/library/HTMLPurifier/URIScheme/tel.php @@ -37,7 +37,7 @@ public function doValidate(&$uri, $config, $context) // from phone number, EXCEPT for a leading plus sign. $uri->path = preg_replace('/(?!^\+)[^\dx]/', '', // Normalize e(x)tension to lower-case - str_replace('X', 'x', $uri->path)); + str_replace('X', 'x', rawurldecode($uri->path))); return true; } diff --git a/maintenance/add-vimline.php b/maintenance/add-vimline.php index d6a8eb202..69882c67e 100644 --- a/maintenance/add-vimline.php +++ b/maintenance/add-vimline.php @@ -34,7 +34,6 @@ postfix_is('.svg', $file) || postfix_is('.phpt', $file) || postfix_is('VERSION', $file) || - postfix_is('WHATSNEW', $file) || postfix_is('configdoc/usage.xml', $file) || postfix_is('library/HTMLPurifier.includes.php', $file) || postfix_is('library/HTMLPurifier.safe-includes.php', $file) || diff --git a/package.php b/package.php index bfef93622..a4fd2df9c 100644 --- a/package.php +++ b/package.php @@ -48,7 +48,6 @@ $pkg->addRelease(); -$pkg->setNotes(file_get_contents('WHATSNEW')); $pkg->setPackageType('php'); $pkg->setPhpDep('5.0.0'); diff --git a/release.config.js b/release.config.js new file mode 100644 index 000000000..dcf13c6bc --- /dev/null +++ b/release.config.js @@ -0,0 +1,33 @@ +module.exports = { + debug: true, + branch: 'master', + plugins: [ + '@semantic-release/commit-analyzer', + '@semantic-release/release-notes-generator', + [ + '@semantic-release/changelog', + { + 'changelogFile': 'NEWS' + } + ], + [ + '@semantic-release/exec', + { + 'prepareCmd': 'php update-for-release ${nextRelease.version}' + } + ], + [ + '@semantic-release/git', + { + 'assets': [ + 'VERSION', + 'NEWS', + 'Doxyfile', + ['library/**/*', '!library/standalone/**/*', '!library/HTMLPurifier.standalone.php'], + 'configdoc/**/*', + ], + } + ], + '@semantic-release/github' + ], +} diff --git a/smoketests/common.php b/smoketests/common.php index b2c2b4bb4..eb99ad5ec 100644 --- a/smoketests/common.php +++ b/smoketests/common.php @@ -2,6 +2,8 @@ header('Content-type: text/html; charset=UTF-8'); +require_once __DIR__.'/../vendor/autoload.php'; + if (!isset($_GET['standalone'])) { require_once '../library/HTMLPurifier.auto.php'; } else { diff --git a/smoketests/extractStyleBlocks.php b/smoketests/extractStyleBlocks.php index bb330b5f2..0dff98378 100644 --- a/smoketests/extractStyleBlocks.php +++ b/smoketests/extractStyleBlocks.php @@ -3,23 +3,6 @@ require_once 'common.php'; require_once 'HTMLPurifier/Filter/ExtractStyleBlocks.php'; -// need CSSTidy location -$csstidy_location = false; -if (file_exists('../conf/test-settings.php')) include '../conf/test-settings.php'; -if (file_exists('../test-settings.php')) include '../test-settings.php'; - -if (!$csstidy_location) { -?> -Error: CSSTidy library not -found, please install and configure test-settings.php -accordingly. - true, )); diff --git a/test-settings.sample.php b/test-settings.sample.php index 480b66279..5acc78422 100644 --- a/test-settings.sample.php +++ b/test-settings.sample.php @@ -17,20 +17,6 @@ exit; } -// ----------------------------------------------------------------------------- -// REQUIRED SETTINGS - -// Note on running SimpleTest: -// You want the Git copy of SimpleTest, found here: -// https://github.com/simpletest/simpletest/ -// -// If SimpleTest is borked with HTML Purifier, please contact me or -// the SimpleTest devs; I am a developer for SimpleTest so I should be -// able to quickly assess a fix. SimpleTest's problem is my problem! - -// Where is SimpleTest located? Remember to include a trailing slash! -$simpletest_location = '/path/to/simpletest/'; - // ----------------------------------------------------------------------------- // OPTIONAL SETTINGS @@ -50,9 +36,6 @@ // If PHPT isn't in your Path via PEAR, set that here: // set_include_path('/path/to/phpt/Core/src' . PATH_SEPARATOR . get_include_path()); -// Where is CSSTidy located? (Include trailing slash. Leave false to disable.) -$csstidy_location = false; - // For tests/multitest.php, which versions to test? $versions_to_test = array(); @@ -69,6 +52,6 @@ // If PEAR is enabled, what PEAR tests should be run? (Note: you will // need to ensure these libraries are installed) -$GLOBALS['HTMLPurifierTest']['Net_IDNA2'] = true; +$GLOBALS['HTMLPurifierTest']['Net_IDNA2'] = false; // vim: et sw=4 sts=4 diff --git a/test-settings.travis.php b/test-settings.travis.php deleted file mode 100644 index b1edce4aa..000000000 --- a/test-settings.travis.php +++ /dev/null @@ -1,72 +0,0 @@ -assertDef('min-width:50vw;'); $this->assertDef('min-width:-50vw;', false); $this->assertDef('text-decoration:underline;'); + $this->assertDef('text-decoration-line:overline;'); + $this->assertDef('text-decoration-style:dashed;'); + $this->assertDef('text-decoration-color:#F00;'); + $this->assertDef('text-decoration-thickness:5%;'); $this->assertDef('font-family:sans-serif;'); $this->assertDef("font-family:Gill, 'Times New Roman', sans-serif;"); $this->assertDef('font:12px serif;'); @@ -92,6 +96,9 @@ public function test() $this->assertDef('background-repeat:repeat-y;'); $this->assertDef('background-attachment:fixed;'); $this->assertDef('background-position:left 90%;'); + $this->assertDef('background-size:50%;'); + $this->assertDef('background-size:cover;'); + $this->assertDef('background-size:200px;'); $this->assertDef('border-spacing:1em;'); $this->assertDef('border-spacing:1em 2em;'); $this->assertDef('border-color: rgb(0, 0, 0) rgb(10,0,10)', 'border-color:rgb(0,0,0) rgb(10,0,10);'); diff --git a/tests/HTMLPurifier/AttrDef/HTML/ContentEditableTest.php b/tests/HTMLPurifier/AttrDef/HTML/ContentEditableTest.php new file mode 100644 index 000000000..3aa6ec1e5 --- /dev/null +++ b/tests/HTMLPurifier/AttrDef/HTML/ContentEditableTest.php @@ -0,0 +1,27 @@ +def = new HTMLPurifier_AttrDef_HTML_ContentEditable(); + } + + public function test() + { + $this->assertDef('', false); + $this->assertDef('true', false); + $this->assertDef('caret', false); + $this->assertDef('false'); + } + + public function testTrustedHtml() + { + $this->config->set('HTML.Trusted', true); + $this->assertDef(''); + $this->assertDef('true'); + $this->assertDef('false'); + $this->assertDef('caret', false); + } +} diff --git a/tests/HTMLPurifier/AttrDef/URITest.php b/tests/HTMLPurifier/AttrDef/URITest.php index f40021732..1309f3c20 100644 --- a/tests/HTMLPurifier/AttrDef/URITest.php +++ b/tests/HTMLPurifier/AttrDef/URITest.php @@ -23,6 +23,8 @@ public function testIntegration() $this->assertDef('nntp://news.example.com/324234'); $this->assertDef('mailto:bob@example.com'); $this->assertDef('tel:+15555555555'); + $this->assertDef('tel:+15555 555 555', 'tel:+15555555555'); + $this->assertDef('tel:+15555%20555%20555', 'tel:+15555555555'); } public function testIntegrationWithPercentEncoder() diff --git a/tests/HTMLPurifier/AttrTransform/NameSyncTest.php b/tests/HTMLPurifier/AttrTransform/NameSyncTest.php index 989b0ee84..d41ccc707 100644 --- a/tests/HTMLPurifier/AttrTransform/NameSyncTest.php +++ b/tests/HTMLPurifier/AttrTransform/NameSyncTest.php @@ -3,6 +3,11 @@ class HTMLPurifier_AttrTransform_NameSyncTest extends HTMLPurifier_AttrTransformHarness { + /** + * @type HTMLPurifier_IDAccumulator + */ + public $accumulator; + public function setUp() { parent::setUp(); diff --git a/tests/HTMLPurifier/AttrValidator_ErrorsTest.php b/tests/HTMLPurifier/AttrValidator_ErrorsTest.php index 98693afb6..709b3ba23 100644 --- a/tests/HTMLPurifier/AttrValidator_ErrorsTest.php +++ b/tests/HTMLPurifier/AttrValidator_ErrorsTest.php @@ -3,6 +3,11 @@ class HTMLPurifier_AttrValidator_ErrorsTest extends HTMLPurifier_ErrorsHarness { + /** + * @type HTMLPurifier_Language + */ + public $language; + public function setup() { parent::setup(); diff --git a/tests/HTMLPurifier/ChildDef/TableTest.php b/tests/HTMLPurifier/ChildDef/TableTest.php index 49e96b652..aba6b1dc9 100644 --- a/tests/HTMLPurifier/ChildDef/TableTest.php +++ b/tests/HTMLPurifier/ChildDef/TableTest.php @@ -44,6 +44,22 @@ public function testXhtml11Illegal() ); } + public function testTheadOnlyNotRemoved() + { + $this->assertResult( + 'a', + 'a' + ); + } + + public function testTbodyOnlyNotRemoved() + { + $this->assertResult( + 'a', + 'a' + ); + } + public function testTrOverflowAndClose() { $this->assertResult( diff --git a/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php b/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php index 43db45afb..5e01bb995 100644 --- a/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php +++ b/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php @@ -5,6 +5,12 @@ class HTMLPurifier_DefinitionCache_DecoratorHarness extends HTMLPurifier_DefinitionCacheHarness { + public $cache; + + public $mock; + + public $def; + public function setup() { $this->mock = new HTMLPurifier_DefinitionCacheMock(); diff --git a/tests/HTMLPurifier/DefinitionTestable.php b/tests/HTMLPurifier/DefinitionTestable.php index 312c57bb4..77020c616 100644 --- a/tests/HTMLPurifier/DefinitionTestable.php +++ b/tests/HTMLPurifier/DefinitionTestable.php @@ -1,7 +1,14 @@ EntityParser = new HTMLPurifier_EntityParser(); diff --git a/tests/HTMLPurifier/HTMLModule/FormsTest.php b/tests/HTMLPurifier/HTMLModule/FormsTest.php index 09b0d4d1e..ceab8c243 100644 --- a/tests/HTMLPurifier/HTMLModule/FormsTest.php +++ b/tests/HTMLPurifier/HTMLModule/FormsTest.php @@ -161,6 +161,13 @@ public function testLegacy() $this->assertResult('
'); } + public function testHTMLFormsConfigDirective() + { + $this->config->set('HTML.Trusted', false); + $this->config->set('HTML.Forms', true); + + $this->assertResult('
'); + } } // vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/LanguageFactoryTest.php b/tests/HTMLPurifier/LanguageFactoryTest.php index e1a73ac79..2cc9a793b 100644 --- a/tests/HTMLPurifier/LanguageFactoryTest.php +++ b/tests/HTMLPurifier/LanguageFactoryTest.php @@ -29,45 +29,6 @@ public function test() } - public function testFallback() - { - $this->config->set('Core.Language', 'en-x-test'); - $language = $this->factory->create($this->config, $this->context); - - $this->assertIsA($language, 'HTMLPurifier_Language_en_x_test'); - $this->assertIdentical($language->code, 'en-x-test'); - - $language->load(); - - // test overloaded message - $this->assertIdentical($language->getMessage('HTMLPurifier'), 'HTML Purifier X'); - - // test inherited message - $this->assertIdentical($language->getMessage('LanguageFactoryTest: Pizza'), 'Pizza'); - - } - - public function testFallbackWithNoClass() - { - $this->config->set('Core.Language', 'en-x-testmini'); - $language = $this->factory->create($this->config, $this->context); - $this->assertIsA($language, 'HTMLPurifier_Language'); - $this->assertIdentical($language->code, 'en-x-testmini'); - $language->load(); - $this->assertIdentical($language->getMessage('HTMLPurifier'), 'HTML Purifier XNone'); - $this->assertIdentical($language->getMessage('LanguageFactoryTest: Pizza'), 'Pizza'); - $this->assertIdentical($language->error, false); - } - - public function testNoSuchLanguage() - { - $this->config->set('Core.Language', 'en-x-testnone'); - $language = $this->factory->create($this->config, $this->context); - $this->assertIsA($language, 'HTMLPurifier_Language'); - $this->assertIdentical($language->code, 'en-x-testnone'); - $this->assertIdentical($language->error, true); - } - } // vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php b/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php index 0e5a8e200..f40987619 100644 --- a/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php +++ b/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php @@ -4,10 +4,13 @@ class HTMLPurifier_Strategy_MakeWellFormed_EndRewindInjector extends HTMLPurifie { public $name = 'EndRewindInjector'; public $needed = array('span'); + private $deleteElement = false; + public function handleElement(&$token) { - if (isset($token->_InjectorTest_EndRewindInjector_delete)) { + if ($this->deleteElement) { $token = false; + $this->deleteElement = false; } } public function handleText(&$token) @@ -23,7 +26,7 @@ public function handleEnd(&$token) $prev->name == 'span' ) { $token = false; - $prev->_InjectorTest_EndRewindInjector_delete = true; + $this->deleteElement = true; $this->rewindOffset(1); } } diff --git a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php index a2125522e..f8ebc4c72 100644 --- a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php +++ b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php @@ -258,6 +258,13 @@ public function testRemovePercentCSSWidthAndHeightOnImg() ); } + public function testContentEditableAttribute() + { + $this->assertResult( + '
', + '
' + ); + } } // vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php b/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php index ffbff0c5d..62a1cefd5 100644 --- a/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php +++ b/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php @@ -28,6 +28,12 @@ public function testPreserveNonBlacklistedHost() $this->assertFiltering('http://google.com'); } + public function testFragment() + { + $this->config->set('URI.HostBlacklist', 'example.com'); + $this->assertFiltering('#foo'); + } + } // vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php b/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php index 19b65b3b0..4a4c2363d 100644 --- a/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php +++ b/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php @@ -40,6 +40,8 @@ public function testPreserveAltScheme() public function testPreserveAltSchemeWithTel() { $this->assertFiltering('tel:+15555555555'); + $this->assertFiltering('tel:+15555 555 555'); + $this->assertFiltering('tel:+15555%20555%20555'); } public function testFilterIgnoreHTTPSpecialCase() diff --git a/tests/HTMLPurifier/URIFilterHarness.php b/tests/HTMLPurifier/URIFilterHarness.php index 4c8ad42e5..e86ba3b91 100644 --- a/tests/HTMLPurifier/URIFilterHarness.php +++ b/tests/HTMLPurifier/URIFilterHarness.php @@ -3,6 +3,11 @@ class HTMLPurifier_URIFilterHarness extends HTMLPurifier_URIHarness { + /** + * @type HTMLPurifier_URIFilter + */ + public $filter; + protected function assertFiltering($uri, $expect_uri = true) { $this->prepareURI($uri, $expect_uri); diff --git a/tests/HTMLPurifier/URIParserTest.php b/tests/HTMLPurifier/URIParserTest.php index 4bc21b760..6b9712b37 100644 --- a/tests/HTMLPurifier/URIParserTest.php +++ b/tests/HTMLPurifier/URIParserTest.php @@ -75,6 +75,10 @@ public function testTelURI() 'tel:+1 (555) 555-5555', 'tel', null, null, null, '+1 (555) 555-5555', null, null ); + $this->assertParsing( + 'tel:+1%20(555)%20555-5555', + 'tel', null, null, null, '+1%20(555)%20555-5555', null, null + ); } public function testIPv4Address() diff --git a/tests/HTMLPurifier/URISchemeTest.php b/tests/HTMLPurifier/URISchemeTest.php index cae6edd05..ade89cc83 100644 --- a/tests/HTMLPurifier/URISchemeTest.php +++ b/tests/HTMLPurifier/URISchemeTest.php @@ -179,6 +179,13 @@ public function test_tel_strip_punctuation() ); } + public function test_tel_with_url_encoding() + { + $this->assertValidation( + 'tel:+1%20(555)%20555-5555', 'tel:+15555555555' + ); + } + public function test_tel_regular() { $this->assertValidation( diff --git a/tests/common.php b/tests/common.php index 7b46ff7a4..db416ffa9 100644 --- a/tests/common.php +++ b/tests/common.php @@ -1,5 +1,7 @@ =')) { @@ -29,6 +27,7 @@ if ($break) break; case 'fstools': $test_dirs[] = 'FSTools'; + if ($break) break; case 'htmlt': $htmlt_dirs[] = 'HTMLPurifier/HTMLT'; if ($break) break; diff --git a/update-for-release b/update-for-release index 32709d25e..ec5ec03dd 100644 --- a/update-for-release +++ b/update-for-release @@ -23,24 +23,7 @@ $version = trim($argv[1]); // ...in VERSION file_put_contents('VERSION', $version); -// ...in NEWS -if ($is_dev = (strpos($version, 'dev') === false)) { - $date = date('Y-m-d'); - $news_c = str_replace( - $l = "$version, unknown release date", - "$version, released $date", - file_get_contents('NEWS'), - $c - ); - if (!$c) { - echo 'Could not update NEWS, missing ' . $l . PHP_EOL; - exit; - } elseif ($c > 1) { - echo 'More than one release declaration in NEWS replaced' . PHP_EOL; - exit; - } - file_put_contents('NEWS', $news_c); -} +$is_dev = strpos($version, 'dev') === false; // ...in Doxyfile $doxyfile_c = preg_replace( @@ -102,9 +85,22 @@ if (!$c) { } file_put_contents('library/HTMLPurifier/Config.php', $config_c); +$includes = file_get_contents('library/HTMLPurifier.includes.php'); +$includes = preg_replace( + '/@version .+?/', + "@version $version", + $includes, + 1, $c +); +if (!$c) { + echo 'Could not update HTMLPurifier.includes.php, missing @version docblock.' . PHP_EOL; + exit; +} +file_put_contents('HTMLPurifier.includes.php', $includes); + passthru('maintenance/flush.sh'); -if ($is_dev) echo "Review changes, write something in WHATSNEW and FOCUS, and then commit with log 'Release $version.'" . PHP_EOL; +if ($is_dev) echo "Review changes, and then commit with log 'Release $version.'" . PHP_EOL; else echo "Numbers updated to dev, no other modifications necessary!"; // vim: et sw=4 sts=4