0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2024-12-22 08:21:52 +00:00

[2.0.1] Add error messages for FixNesting

git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1249 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
Edward Z. Yang 2007-06-26 23:43:28 +00:00
parent 9a66394abb
commit a005da8a4c
5 changed files with 88 additions and 21 deletions

View File

@ -32,6 +32,11 @@ $messages = array(
'Strategy_MakeWellFormed: Tag closed by element end' => '$1.Compact tag started on line $1.Line closed by end of $CurrentToken.Serialized', 'Strategy_MakeWellFormed: Tag closed by element end' => '$1.Compact tag started on line $1.Line closed by end of $CurrentToken.Serialized',
'Strategy_MakeWellFormed: Tag closed by document end' => '$1.Compact tag started on line $1.Line closed by end of document', 'Strategy_MakeWellFormed: Tag closed by document end' => '$1.Compact tag started on line $1.Line closed by end of document',
'Strategy_FixNesting: Node removed' => '$CurrentToken.Compact node removed',
'Strategy_FixNesting: Node excluded' => '$CurrentToken.Compact node removed due to descendant exclusion by ancestor element',
'Strategy_FixNesting: Node reorganized' => 'Contents of $CurrentToken.Compact node reorganized to enforce its content model',
'Strategy_FixNesting: Node contents removed' => 'Contents of $CurrentToken.Compact node removed',
); );
$errorNames = array( $errorNames = array(

View File

@ -54,6 +54,9 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
$is_inline = $definition->info_parent_def->descendants_are_inline; $is_inline = $definition->info_parent_def->descendants_are_inline;
$context->register('IsInline', $is_inline); $context->register('IsInline', $is_inline);
// setup error collector
$e =& $context->get('ErrorCollector', true);
//####################################################################// //####################################################################//
// Loop initialization // Loop initialization
@ -67,6 +70,11 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
// processed, i.e. there won't be empty exclusions. // processed, i.e. there won't be empty exclusions.
$exclude_stack = array(); $exclude_stack = array();
// variable that contains the start token while we are processing
// nodes. This enables error reporting to do its job
$start_token = false;
$context->register('CurrentToken', $start_token);
//####################################################################// //####################################################################//
// Loop // Loop
@ -100,6 +108,8 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
// $i is index of start token // $i is index of start token
// $j is index of end token // $j is index of end token
$start_token = $tokens[$i]; // to make token available via CurrentToken
//################################################################// //################################################################//
// Gather information on parent // Gather information on parent
@ -200,6 +210,14 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
} elseif($result === false) { } elseif($result === false) {
// remove entire node // remove entire node
if ($e) {
if ($excluded) {
$e->send(E_ERROR, 'Strategy_FixNesting: Node excluded');
} else {
$e->send(E_ERROR, 'Strategy_FixNesting: Node removed');
}
}
// calculate length of inner tokens and current tokens // calculate length of inner tokens and current tokens
$length = $j - $i + 1; $length = $j - $i + 1;
@ -216,7 +234,7 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
// this is a rought heuristic that covers 100% of HTML's // this is a rought heuristic that covers 100% of HTML's
// cases and 99% of all other cases. A child definition // cases and 99% of all other cases. A child definition
// that would be tricked by this would be something like: // that would be tricked by this would be something like:
// ( | a b c) where it's all or nothing. Fortunantely, // ( | a b c) where it's all or nothing. Fortunately,
// our current implementation claims that that case would // our current implementation claims that that case would
// not allow empty, even if it did // not allow empty, even if it did
if (!$parent_def->child->allow_empty) { if (!$parent_def->child->allow_empty) {
@ -234,6 +252,14 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
// calculate length of inner tokens // calculate length of inner tokens
$length = $j - $i - 1; $length = $j - $i - 1;
if ($e) {
if (empty($result) && $length) {
$e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed');
} else {
$e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized');
}
}
// perform replacement // perform replacement
array_splice($tokens, $i + 1, $length, $result); array_splice($tokens, $i + 1, $length, $result);
@ -291,6 +317,7 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
// remove context variables // remove context variables
$context->destroy('IsInline'); $context->destroy('IsInline');
$context->destroy('CurrentToken');
//####################################################################// //####################################################################//
// Return // Return

View File

@ -0,0 +1,39 @@
<?php
require_once 'HTMLPurifier/Strategy/ErrorsHarness.php';
require_once 'HTMLPurifier/Strategy/FixNesting.php';
class HTMLPurifier_Strategy_FixNesting_ErrorsTest extends HTMLPurifier_Strategy_ErrorsHarness
{
function getStrategy() {
return new HTMLPurifier_Strategy_FixNesting();
}
function testNodeRemoved() {
$this->expectErrorCollection(E_ERROR, 'Strategy_FixNesting: Node removed');
$this->expectContext('CurrentToken', new HTMLPurifier_Token_Start('ul', array(), 1));
$this->invoke('<ul></ul>');
}
function testNodeExcluded() {
$this->expectErrorCollection(E_ERROR, 'Strategy_FixNesting: Node excluded');
$this->expectContext('CurrentToken', new HTMLPurifier_Token_Start('a', array(), 2));
$this->invoke("<a>\n<a></a></a>");
}
function testNodeReorganized() {
$this->expectErrorCollection(E_WARNING, 'Strategy_FixNesting: Node reorganized');
$this->expectContext('CurrentToken', new HTMLPurifier_Token_Start('span', array(), 1));
$this->invoke("<span>Valid<div>Invalid</div></span>");
}
function testNodeContentsRemoved() {
$this->expectErrorCollection(E_ERROR, 'Strategy_FixNesting: Node contents removed');
$this->expectContext('CurrentToken', new HTMLPurifier_Token_Start('span', array(), 1));
$this->invoke("<span><div></div></span>");
}
}
?>

View File

@ -3,11 +3,6 @@
require_once 'HTMLPurifier/Strategy/ErrorsHarness.php'; require_once 'HTMLPurifier/Strategy/ErrorsHarness.php';
require_once 'HTMLPurifier/Strategy/MakeWellFormed.php'; require_once 'HTMLPurifier/Strategy/MakeWellFormed.php';
/*
'Strategy_MakeWellFormed: Tag closed by element end' => '',
'Strategy_MakeWellFormed: Tag closed by document end' => '',
*/
class HTMLPurifier_Strategy_MakeWellFormed_ErrorsTest extends HTMLPurifier_Strategy_ErrorsHarness class HTMLPurifier_Strategy_MakeWellFormed_ErrorsTest extends HTMLPurifier_Strategy_ErrorsHarness
{ {

View File

@ -93,6 +93,7 @@ $test_files[] = 'HTMLPurifier/PercentEncoderTest.php';
$test_files[] = 'HTMLPurifier/Strategy/CompositeTest.php'; $test_files[] = 'HTMLPurifier/Strategy/CompositeTest.php';
$test_files[] = 'HTMLPurifier/Strategy/CoreTest.php'; $test_files[] = 'HTMLPurifier/Strategy/CoreTest.php';
$test_files[] = 'HTMLPurifier/Strategy/FixNestingTest.php'; $test_files[] = 'HTMLPurifier/Strategy/FixNestingTest.php';
$test_files[] = 'HTMLPurifier/Strategy/FixNesting_ErrorsTest.php';
$test_files[] = 'HTMLPurifier/Strategy/MakeWellFormedTest.php'; $test_files[] = 'HTMLPurifier/Strategy/MakeWellFormedTest.php';
$test_files[] = 'HTMLPurifier/Strategy/MakeWellFormed_ErrorsTest.php'; $test_files[] = 'HTMLPurifier/Strategy/MakeWellFormed_ErrorsTest.php';
$test_files[] = 'HTMLPurifier/Strategy/RemoveForeignElementsTest.php'; $test_files[] = 'HTMLPurifier/Strategy/RemoveForeignElementsTest.php';