From 877ac800cdcc8a716c0962e55e308edf5f383a7e Mon Sep 17 00:00:00 2001 From: Daniel Ziegenberg Date: Tue, 27 Sep 2022 18:31:19 +0200 Subject: [PATCH] MDL-74823 lib: HTMLPurifier upgrade to 4.16.0 Signed-off-by: Daniel Ziegenberg --- lib/htmlpurifier/HTMLPurifier.php | 6 +++--- lib/htmlpurifier/HTMLPurifier.safe-includes.php | 1 + .../AttrDef/HTML/ContentEditable.php | 16 ++++++++++++++++ .../HTMLPurifier/AttrTransform/NameSync.php | 5 +++++ .../HTMLPurifier/AttrTransform/SafeParam.php | 5 +++++ lib/htmlpurifier/HTMLPurifier/AttrTypes.php | 1 + lib/htmlpurifier/HTMLPurifier/ChildDef/List.php | 2 ++ lib/htmlpurifier/HTMLPurifier/Config.php | 2 +- lib/htmlpurifier/HTMLPurifier/ElementDef.php | 2 +- lib/htmlpurifier/HTMLPurifier/Encoder.php | 8 ++++---- .../HTMLPurifier/HTMLModule/CommonAttributes.php | 1 + .../Injector/RemoveSpansWithoutAttributes.php | 15 +++++++++++++-- lib/htmlpurifier/HTMLPurifier/Length.php | 2 +- lib/htmlpurifier/HTMLPurifier/Lexer.php | 9 +++++++-- lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php | 2 +- .../HTMLPurifier/PropertyListIterator.php | 1 + lib/htmlpurifier/HTMLPurifier/StringHash.php | 1 + .../HTMLPurifier/URIFilter/HostBlacklist.php | 2 +- .../HTMLPurifier/URIFilter/Munge.php | 10 +++++----- lib/thirdpartylibs.xml | 2 +- lib/upgrade.txt | 2 +- 21 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/ContentEditable.php diff --git a/lib/htmlpurifier/HTMLPurifier.php b/lib/htmlpurifier/HTMLPurifier.php index 2177fc85172..26f061276f7 100644 --- a/lib/htmlpurifier/HTMLPurifier.php +++ b/lib/htmlpurifier/HTMLPurifier.php @@ -19,7 +19,7 @@ */ /* - HTML Purifier 4.14.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.14.0'; + public $version = '4.15.0'; /** * Constant with version of HTML Purifier. */ - const VERSION = '4.14.0'; + const VERSION = '4.15.0'; /** * Global configuration object. diff --git a/lib/htmlpurifier/HTMLPurifier.safe-includes.php b/lib/htmlpurifier/HTMLPurifier.safe-includes.php index a3261f8a327..94543f593de 100644 --- a/lib/htmlpurifier/HTMLPurifier.safe-includes.php +++ b/lib/htmlpurifier/HTMLPurifier.safe-includes.php @@ -101,6 +101,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php'; 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/lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/ContentEditable.php b/lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/ContentEditable.php new file mode 100644 index 00000000000..5b03d3e3785 --- /dev/null +++ b/lib/htmlpurifier/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/lib/htmlpurifier/HTMLPurifier/AttrTransform/NameSync.php b/lib/htmlpurifier/HTMLPurifier/AttrTransform/NameSync.php index 36079b786ff..5a1fdbbfcc8 100644 --- a/lib/htmlpurifier/HTMLPurifier/AttrTransform/NameSync.php +++ b/lib/htmlpurifier/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/lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeParam.php b/lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeParam.php index 1143b4b4930..1033106b387 100644 --- a/lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeParam.php +++ b/lib/htmlpurifier/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/lib/htmlpurifier/HTMLPurifier/AttrTypes.php b/lib/htmlpurifier/HTMLPurifier/AttrTypes.php index 3b70520b6ad..e4429e86d87 100644 --- a/lib/htmlpurifier/HTMLPurifier/AttrTypes.php +++ b/lib/htmlpurifier/HTMLPurifier/AttrTypes.php @@ -41,6 +41,7 @@ class HTMLPurifier_AttrTypes $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/lib/htmlpurifier/HTMLPurifier/ChildDef/List.php b/lib/htmlpurifier/HTMLPurifier/ChildDef/List.php index 4fc70e0efa7..3d584e72712 100644 --- a/lib/htmlpurifier/HTMLPurifier/ChildDef/List.php +++ b/lib/htmlpurifier/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/lib/htmlpurifier/HTMLPurifier/Config.php b/lib/htmlpurifier/HTMLPurifier/Config.php index 16a6b322b5e..797d2687792 100644 --- a/lib/htmlpurifier/HTMLPurifier/Config.php +++ b/lib/htmlpurifier/HTMLPurifier/Config.php @@ -21,7 +21,7 @@ class HTMLPurifier_Config * HTML Purifier's version * @type string */ - public $version = '4.14.0'; + public $version = '4.15.0'; /** * Whether or not to automatically finalize diff --git a/lib/htmlpurifier/HTMLPurifier/ElementDef.php b/lib/htmlpurifier/HTMLPurifier/ElementDef.php index d5311cedcf3..57cfd2bb080 100644 --- a/lib/htmlpurifier/HTMLPurifier/ElementDef.php +++ b/lib/htmlpurifier/HTMLPurifier/ElementDef.php @@ -176,7 +176,7 @@ class HTMLPurifier_ElementDef 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/lib/htmlpurifier/HTMLPurifier/Encoder.php b/lib/htmlpurifier/HTMLPurifier/Encoder.php index 40a24266a46..d4791cc1b61 100644 --- a/lib/htmlpurifier/HTMLPurifier/Encoder.php +++ b/lib/htmlpurifier/HTMLPurifier/Encoder.php @@ -398,8 +398,8 @@ class HTMLPurifier_Encoder // 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 @@ class HTMLPurifier_Encoder // 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/lib/htmlpurifier/HTMLPurifier/HTMLModule/CommonAttributes.php b/lib/htmlpurifier/HTMLPurifier/HTMLModule/CommonAttributes.php index a96ab1bef11..7220c14cc7c 100644 --- a/lib/htmlpurifier/HTMLPurifier/HTMLModule/CommonAttributes.php +++ b/lib/htmlpurifier/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/lib/htmlpurifier/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php b/lib/htmlpurifier/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php index 9ee7aa84d71..42d51444740 100644 --- a/lib/htmlpurifier/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php +++ b/lib/htmlpurifier/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 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In 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 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In */ public function handleEnd(&$token) { - if ($token->markForDeletion) { + if ($this->markForDeletion->contains($token)) { + $this->markForDeletion->detach($token); $token = false; } } diff --git a/lib/htmlpurifier/HTMLPurifier/Length.php b/lib/htmlpurifier/HTMLPurifier/Length.php index e70da55a923..b6ea12345da 100644 --- a/lib/htmlpurifier/HTMLPurifier/Length.php +++ b/lib/htmlpurifier/HTMLPurifier/Length.php @@ -78,7 +78,7 @@ class HTMLPurifier_Length 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/lib/htmlpurifier/HTMLPurifier/Lexer.php b/lib/htmlpurifier/HTMLPurifier/Lexer.php index e9da3ed5e94..c21f364919c 100644 --- a/lib/htmlpurifier/HTMLPurifier/Lexer.php +++ b/lib/htmlpurifier/HTMLPurifier/Lexer.php @@ -48,6 +48,11 @@ class HTMLPurifier_Lexer */ public $tracksLineNumbers = false; + /** + * @type HTMLPurifier_EntityParser + */ + private $_entity_parser; + // -- STATIC ---------------------------------------------------------- /** @@ -306,8 +311,8 @@ class HTMLPurifier_Lexer { // 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/lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php b/lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php index 72476ddf32b..1564f283dc0 100644 --- a/lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php +++ b/lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php @@ -4410,7 +4410,7 @@ class HTML5TreeConstructer 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/lib/htmlpurifier/HTMLPurifier/PropertyListIterator.php b/lib/htmlpurifier/HTMLPurifier/PropertyListIterator.php index 15b330ea308..f68fc8c30fc 100644 --- a/lib/htmlpurifier/HTMLPurifier/PropertyListIterator.php +++ b/lib/htmlpurifier/HTMLPurifier/PropertyListIterator.php @@ -29,6 +29,7 @@ class HTMLPurifier_PropertyListIterator extends FilterIterator /** * @return bool */ + #[\ReturnTypeWillChange] public function accept() { $key = $this->getInnerIterator()->key(); diff --git a/lib/htmlpurifier/HTMLPurifier/StringHash.php b/lib/htmlpurifier/HTMLPurifier/StringHash.php index c07370197a9..c41ae3a76d5 100644 --- a/lib/htmlpurifier/HTMLPurifier/StringHash.php +++ b/lib/htmlpurifier/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/lib/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php b/lib/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php index a6645c17ee6..32197c0e614 100644 --- a/lib/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php +++ b/lib/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php @@ -35,7 +35,7 @@ class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter 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/lib/htmlpurifier/HTMLPurifier/URIFilter/Munge.php b/lib/htmlpurifier/HTMLPurifier/URIFilter/Munge.php index 6e03315a17b..e1393deb739 100644 --- a/lib/htmlpurifier/HTMLPurifier/URIFilter/Munge.php +++ b/lib/htmlpurifier/HTMLPurifier/URIFilter/Munge.php @@ -100,11 +100,11 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter $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/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml index 2b48c8722ad..8f2b2b39484 100644 --- a/lib/thirdpartylibs.xml +++ b/lib/thirdpartylibs.xml @@ -73,7 +73,7 @@ htmlpurifier HTML Purifier Filters HTML. - 4.14.0 + 4.16.0 LGPL 2.1+ https://github.com/ezyang/htmlpurifier diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 900730f4559..92747543e9b 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -2,7 +2,7 @@ This files describes API changes in core libraries and APIs, information provided here is intended especially for developers. === 4.1 === -* HTMLPurifier has been upgraded to the latest version - 4.14.0 +* HTMLPurifier has been upgraded to the latest version - 4.16.0 * A process to deprecate capabilities by flagging them in the access.php by adding a $deprecatedcapabilities variable (an array). This array will list the deprecated capabilities and a possible replacement. Once we declare the capability as deprecated, a debugging message will be displayed (in DEBUG_DEVELOPPER mode only) when using the deprecated capability.