From a96b5bf612b764de3b09826d8437eb99536667ff Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Thu, 28 Jun 2007 13:06:15 +0000 Subject: [PATCH] [2.1.0] Friendly error messages for when injector needs a tag that's not allowed added git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1265 48356398-32a2-884e-a903-53898d9a118a --- NEWS | 2 ++ library/HTMLPurifier/Injector.php | 34 ++++++++++++++++--- .../HTMLPurifier/Injector/AutoParagraph.php | 8 +++++ library/HTMLPurifier/Injector/Linkify.php | 6 +++- .../HTMLPurifier/Injector/PurifierLinkify.php | 9 +++-- .../HTMLPurifier/Strategy/MakeWellFormed.php | 9 +++-- .../Injector/AutoParagraphTest.php | 5 +++ tests/HTMLPurifier/Injector/LinkifyTest.php | 5 +++ .../Injector/PurifierLinkifyTest.php | 5 +++ 9 files changed, 73 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index c7360e20..d3e6ef8b 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier ! With %Core.AggressivelyFixLt, <3 and similar emoticons no longer trigger HTML removal in PHP5 (DOMLex). This directive is not necessary for PHP4 (DirectLex). +- AutoFormatters emit friendly error messages if tags or attributes they + need are not allowed 2.0.2, unknown release date (none) diff --git a/library/HTMLPurifier/Injector.php b/library/HTMLPurifier/Injector.php index 93dbf735..580366e6 100644 --- a/library/HTMLPurifier/Injector.php +++ b/library/HTMLPurifier/Injector.php @@ -8,6 +8,11 @@ class HTMLPurifier_Injector { + /** + * Advisory name of injector, this is for friendly error messages + */ + var $name; + /** * Amount of tokens the injector needs to skip + 1. Because * the decrement is the first thing that happens, this needs to @@ -40,16 +45,37 @@ class HTMLPurifier_Injector var $inputIndex; /** - * Prepares the injector by giving it the config and context objects, - * so that important variables can be extracted and not passed via - * parameter constantly. Remember: always instantiate a new injector - * when handling a set of HTML. + * Array of elements and attributes this injector creates and therefore + * need to be allowed by the definition. Takes form of + * array('element' => array('attr', 'attr2'), 'element2') + */ + var $needed = array(); + + /** + * Prepares the injector by giving it the config and context objects: + * this allows references to important variables to be made within + * the injector. This function also checks if the HTML environment + * will work with the Injector: if p tags are not allowed, the + * Auto-Paragraphing injector should not be enabled. + * @param $config Instance of HTMLPurifier_Config + * @param $context Instance of HTMLPurifier_Context + * @return Boolean false if success, string of missing needed element/attribute if failure */ function prepare($config, &$context) { $this->htmlDefinition = $config->getHTMLDefinition(); + // perform $needed checks + foreach ($this->needed as $element => $attributes) { + if (is_int($element)) $element = $attributes; + if (!isset($this->htmlDefinition->info[$element])) return $element; + if (!is_array($attributes)) continue; + foreach ($attributes as $name) { + if (!isset($this->htmlDefinition->info[$element]->attr[$name])) return "$element.$name"; + } + } $this->currentNesting =& $context->get('CurrentNesting'); $this->inputTokens =& $context->get('InputTokens'); $this->inputIndex =& $context->get('InputIndex'); + return false; } /** diff --git a/library/HTMLPurifier/Injector/AutoParagraph.php b/library/HTMLPurifier/Injector/AutoParagraph.php index 920cce92..82bbc725 100644 --- a/library/HTMLPurifier/Injector/AutoParagraph.php +++ b/library/HTMLPurifier/Injector/AutoParagraph.php @@ -15,6 +15,11 @@ HTMLPurifier_ConfigSchema::define( block elements in nodes that allow paragraph tags
  • There are double newlines in paragraph tags
  • +

    + p tags must be allowed for this directive to take effect. + We do not use br tags for paragraphing, as that is + semantically incorrect. +

    This directive has been available since 2.0.1.

    @@ -27,6 +32,9 @@ HTMLPurifier_ConfigSchema::define( class HTMLPurifier_Injector_AutoParagraph extends HTMLPurifier_Injector { + var $name = 'AutoParagraph'; + var $needed = array('p'); + function _pStart() { $par = new HTMLPurifier_Token_Start('p'); $par->armor['MakeWellFormed_TagClosedError'] = true; diff --git a/library/HTMLPurifier/Injector/Linkify.php b/library/HTMLPurifier/Injector/Linkify.php index 4269e7a4..bf7abfa9 100644 --- a/library/HTMLPurifier/Injector/Linkify.php +++ b/library/HTMLPurifier/Injector/Linkify.php @@ -6,7 +6,8 @@ HTMLPurifier_ConfigSchema::define( 'AutoFormat', 'Linkify', false, 'bool', '

    This directive turns on linkification, auto-linking http, ftp and - https URLs. This directive has been available since 2.0.1. + https URLs. a tags with the href attribute + must be allowed. This directive has been available since 2.0.1.

    '); @@ -16,6 +17,9 @@ HTMLPurifier_ConfigSchema::define( class HTMLPurifier_Injector_Linkify extends HTMLPurifier_Injector { + var $name = 'Linkify'; + var $needed = array('a' => array('href')); + function handleText(&$token) { if (!$this->allowsElement('a')) return; diff --git a/library/HTMLPurifier/Injector/PurifierLinkify.php b/library/HTMLPurifier/Injector/PurifierLinkify.php index 5b0dcce2..a7686297 100644 --- a/library/HTMLPurifier/Injector/PurifierLinkify.php +++ b/library/HTMLPurifier/Injector/PurifierLinkify.php @@ -6,8 +6,9 @@ HTMLPurifier_ConfigSchema::define( 'AutoFormat', 'PurifierLinkify', false, 'bool', '

    Internal auto-formatter that converts configuration directives in - syntax %Namespace.Directive to links. This directive has been available - since 2.0.1. + syntax %Namespace.Directive to links. a tags + with the href attribute must be allowed. + This directive has been available since 2.0.1.

    '); @@ -27,11 +28,13 @@ HTMLPurifier_ConfigSchema::define( class HTMLPurifier_Injector_PurifierLinkify extends HTMLPurifier_Injector { + var $name = 'PurifierLinkify'; var $docURL; + var $needed = array('a' => array('href')); function prepare($config, &$context) { - parent::prepare($config, $context); $this->docURL = $config->get('AutoFormatParam', 'PurifierLinkifyDocURL'); + return parent::prepare($config, $context); } function handleText(&$token) { diff --git a/library/HTMLPurifier/Strategy/MakeWellFormed.php b/library/HTMLPurifier/Strategy/MakeWellFormed.php index f78a59ed..f573d2fc 100644 --- a/library/HTMLPurifier/Strategy/MakeWellFormed.php +++ b/library/HTMLPurifier/Strategy/MakeWellFormed.php @@ -67,7 +67,8 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy unset($injectors['Custom']); // special case foreach ($injectors as $injector => $b) { $injector = "HTMLPurifier_Injector_$injector"; - if ($b) $this->injectors[] = new $injector; + if (!$b) continue; + $this->injectors[] = new $injector; } foreach ($custom_injectors as $injector) { if (is_string($injector)) { @@ -87,7 +88,11 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy // give the injectors references to the definition and context // variables for performance reasons foreach ($this->injectors as $i => $x) { - $this->injectors[$i]->prepare($config, $context); + $error = $this->injectors[$i]->prepare($config, $context); + if (!$error) continue; + list($injector) = array_splice($this->injectors, $i, 1); + $name = $injector->name; + trigger_error("Cannot enable $name injector because $error is not allowed", E_USER_WARNING); } // -- end INJECTOR -- diff --git a/tests/HTMLPurifier/Injector/AutoParagraphTest.php b/tests/HTMLPurifier/Injector/AutoParagraphTest.php index 8611fd9b..357fa526 100644 --- a/tests/HTMLPurifier/Injector/AutoParagraphTest.php +++ b/tests/HTMLPurifier/Injector/AutoParagraphTest.php @@ -249,5 +249,10 @@ Par2', ); } + function testNeeded() { + $this->expectError('Cannot enable AutoParagraph injector because p is not allowed'); + $this->assertResult('foobar', true, array('AutoFormat.AutoParagraph' => true, 'HTML.Allowed' => 'b')); + } + } diff --git a/tests/HTMLPurifier/Injector/LinkifyTest.php b/tests/HTMLPurifier/Injector/LinkifyTest.php index b91908ee..66a06956 100644 --- a/tests/HTMLPurifier/Injector/LinkifyTest.php +++ b/tests/HTMLPurifier/Injector/LinkifyTest.php @@ -34,5 +34,10 @@ class HTMLPurifier_Injector_LinkifyTest extends HTMLPurifier_InjectorHarness } + function testNeeded() { + $this->expectError('Cannot enable Linkify injector because a is not allowed'); + $this->assertResult('http://example.com/', true, array('AutoFormat.Linkify' => true, 'HTML.Allowed' => 'b')); + } + } diff --git a/tests/HTMLPurifier/Injector/PurifierLinkifyTest.php b/tests/HTMLPurifier/Injector/PurifierLinkifyTest.php index d538c489..e820d677 100644 --- a/tests/HTMLPurifier/Injector/PurifierLinkifyTest.php +++ b/tests/HTMLPurifier/Injector/PurifierLinkifyTest.php @@ -38,5 +38,10 @@ class HTMLPurifier_Injector_PurifierLinkifyTest extends HTMLPurifier_InjectorHar } + function testNeeded() { + $this->expectError('Cannot enable PurifierLinkify injector because a is not allowed'); + $this->assertResult('%Namespace.Directive', true, array('AutoFormat.PurifierLinkify' => true, 'HTML.Allowed' => 'b')); + } + }