diff --git a/docs/config.txt b/docs/config.txt index 800ea05d..0ac54c67 100644 --- a/docs/config.txt +++ b/docs/config.txt @@ -10,12 +10,9 @@ Directives are divided into namespaces, indicating the major portion of functionality they cover (although there may be overlaps. Please consult the documentation in ConfigDef for more information on these namespaces. -Since configuration is dependent on context, most of the internal classes -require a configuration object to be passed as a parameter. However, a few -make this optional: they will supply a default configuration object if none -are passed. These classes are: HTMLPurifier::*, Generator::generateFromTokens -and Lexer::tokenizeHTML. However, whenever a valid configuration object -is defined, that object should be used. +Since configuration is dependant on context, internal classes require a +configuration object to be passed as a parameter. (They also require a +Context object). In relation to HTMLDefinition and CSSDefinition, there is a special class of directives that influence the *construction* of the Definition object. diff --git a/library/HTMLPurifier.php b/library/HTMLPurifier.php index f02bf0c2..64028d6c 100644 --- a/library/HTMLPurifier.php +++ b/library/HTMLPurifier.php @@ -44,6 +44,7 @@ // they get included require_once 'HTMLPurifier/ConfigSchema.php'; require_once 'HTMLPurifier/Config.php'; +require_once 'HTMLPurifier/Context.php'; require_once 'HTMLPurifier/Lexer.php'; require_once 'HTMLPurifier/Generator.php'; @@ -95,16 +96,17 @@ class HTMLPurifier */ function purify($html, $config = null) { $config = $config ? $config : $this->config; - $html = $this->encoder->convertToUTF8($html, $config); + $context =& new HTMLPurifier_Context(); + $html = $this->encoder->convertToUTF8($html, $config, $context); $html = $this->generator->generateFromTokens( $this->strategy->execute( - $this->lexer->tokenizeHTML($html, $config), - $config + $this->lexer->tokenizeHTML($html, $config, $context), + $config, $context ), - $config + $config, $context ); - $html = $this->encoder->convertFromUTF8($html, $config); + $html = $this->encoder->convertFromUTF8($html, $config, $context); return $html; } diff --git a/library/HTMLPurifier/ChildDef.php b/library/HTMLPurifier/ChildDef.php index 793ec51a..19409b0d 100644 --- a/library/HTMLPurifier/ChildDef.php +++ b/library/HTMLPurifier/ChildDef.php @@ -38,15 +38,14 @@ class HTMLPurifier_ChildDef /** * Validates nodes according to definition and returns modification. * - * @warning $context is NOT HTMLPurifier_AttrContext * @param $tokens_of_children Array of HTMLPurifier_Token * @param $config HTMLPurifier_Config object - * @param $context String context indicating inline, block or unknown + * @param $context HTMLPurifier_Context object * @return bool true to leave nodes as is * @return bool false to remove parent node * @return array of replacement child tokens */ - function validateChildren($tokens_of_children, $config, $context) { + function validateChildren($tokens_of_children, $config, &$context) { trigger_error('Call to abstract function', E_USER_ERROR); } } @@ -91,7 +90,7 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef $reg = preg_replace('/([#a-zA-Z0-9_.-]+)/', '(,?\\0)', $reg); $this->_pcre_regex = $reg; } - function validateChildren($tokens_of_children, $config, $context) { + function validateChildren($tokens_of_children, $config, &$context) { $list_of_children = ''; $nesting = 0; // depth into the nest foreach ($tokens_of_children as $token) { @@ -145,7 +144,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef } var $allow_empty = false; var $type = 'required'; - function validateChildren($tokens_of_children, $config, $context) { + function validateChildren($tokens_of_children, $config, &$context) { // if there are no tokens, delete parent node if (empty($tokens_of_children)) return false; @@ -227,7 +226,7 @@ class HTMLPurifier_ChildDef_Optional extends HTMLPurifier_ChildDef_Required { var $allow_empty = true; var $type = 'optional'; - function validateChildren($tokens_of_children, $config, $context) { + function validateChildren($tokens_of_children, $config, &$context) { $result = parent::validateChildren($tokens_of_children, $config, $context); if ($result === false) return array(); return $result; @@ -246,7 +245,7 @@ class HTMLPurifier_ChildDef_Empty extends HTMLPurifier_ChildDef var $allow_empty = true; var $type = 'empty'; function HTMLPurifier_ChildDef_Empty() {} - function validateChildren($tokens_of_children, $config, $context) { + function validateChildren($tokens_of_children, $config, &$context) { return array(); } } @@ -281,8 +280,9 @@ class HTMLPurifier_ChildDef_Chameleon extends HTMLPurifier_ChildDef $this->block = new HTMLPurifier_ChildDef_Optional($block); } - function validateChildren($tokens_of_children, $config, $context) { - switch ($context) { + function validateChildren($tokens_of_children, $config, &$context) { + $parent_type = $context->get('ParentType'); + switch ($parent_type) { case 'unknown': case 'inline': $result = $this->inline->validateChildren( @@ -308,7 +308,7 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef var $allow_empty = false; var $type = 'table'; function HTMLPurifier_ChildDef_Table() {} - function validateChildren($tokens_of_children, $config, $context) { + function validateChildren($tokens_of_children, $config, &$context) { if (empty($tokens_of_children)) return false; // this ensures that the loop gets run one last time before closing diff --git a/library/HTMLPurifier/Encoder.php b/library/HTMLPurifier/Encoder.php index 9d7a35ef..ff4ea5af 100644 --- a/library/HTMLPurifier/Encoder.php +++ b/library/HTMLPurifier/Encoder.php @@ -266,7 +266,7 @@ class HTMLPurifier_Encoder /** * Converts a string to UTF-8 based on configuration. */ - function convertToUTF8($str, $config) { + function convertToUTF8($str, $config, &$context) { static $iconv = null; if ($iconv === null) $iconv = function_exists('iconv'); $encoding = $config->get('Core', 'Encoding'); @@ -283,7 +283,7 @@ class HTMLPurifier_Encoder * @note Currently, this is a lossy conversion, with unexpressable * characters being omitted. */ - function convertFromUTF8($str, $config) { + function convertFromUTF8($str, $config, &$context) { static $iconv = null; if ($iconv === null) $iconv = function_exists('iconv'); $encoding = $config->get('Core', 'Encoding'); diff --git a/library/HTMLPurifier/Lexer.php b/library/HTMLPurifier/Lexer.php index 962cb7bf..31d31d27 100644 --- a/library/HTMLPurifier/Lexer.php +++ b/library/HTMLPurifier/Lexer.php @@ -122,7 +122,7 @@ class HTMLPurifier_Lexer * @param $string String HTML. * @return HTMLPurifier_Token array representation of HTML. */ - function tokenizeHTML($string, $config = null) { + function tokenizeHTML($string, $config, &$context) { trigger_error('Call to abstract class', E_USER_ERROR); } @@ -196,7 +196,7 @@ class HTMLPurifier_Lexer * Takes a piece of HTML and normalizes it by converting entities, fixing * encoding, extracting bits, and other good stuff. */ - function normalize($html, $config) { + function normalize($html, $config, &$context) { // extract body from document if applicable if ($config->get('Core', 'AcceptFullDocuments')) { diff --git a/library/HTMLPurifier/Lexer/DOMLex.php b/library/HTMLPurifier/Lexer/DOMLex.php index fbdecb8f..57720457 100644 --- a/library/HTMLPurifier/Lexer/DOMLex.php +++ b/library/HTMLPurifier/Lexer/DOMLex.php @@ -38,10 +38,9 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer $this->factory = new HTMLPurifier_TokenFactory(); } - public function tokenizeHTML($string, $config = null) { - if (!$config) $config = HTMLPurifier_Config::createDefault(); + public function tokenizeHTML($string, $config, &$context) { - $string = $this->normalize($string, $config); + $string = $this->normalize($string, $config, $context); // preprocess string, essential for UTF-8 $string = diff --git a/library/HTMLPurifier/Lexer/DirectLex.php b/library/HTMLPurifier/Lexer/DirectLex.php index 4b9bff1e..30b56ba0 100644 --- a/library/HTMLPurifier/Lexer/DirectLex.php +++ b/library/HTMLPurifier/Lexer/DirectLex.php @@ -24,11 +24,9 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer */ var $_whitespace = "\x20\x09\x0D\x0A"; - function tokenizeHTML($html, $config = null) { + function tokenizeHTML($html, $config, &$context) { - if (!$config) $config = HTMLPurifier_Config::createDefault(); - - $html = $this->normalize($html, $config); + $html = $this->normalize($html, $config, $context); $cursor = 0; // our location in the text $inside_tag = false; // whether or not we're parsing the inside of a tag @@ -147,6 +145,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer if ($attribute_string) { $attributes = $this->parseAttributeString( $attribute_string + , $config, $context ); } else { $attributes = array(); @@ -181,7 +180,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer * @param $string Inside of tag excluding name. * @returns Assoc array of attributes. */ - function parseAttributeString($string) { + function parseAttributeString($string, $config, &$context) { $string = (string) $string; // quick typecast if ($string == '') return array(); // no attributes diff --git a/library/HTMLPurifier/Lexer/PEARSax3.php b/library/HTMLPurifier/Lexer/PEARSax3.php index 229b4636..ccd201a7 100644 --- a/library/HTMLPurifier/Lexer/PEARSax3.php +++ b/library/HTMLPurifier/Lexer/PEARSax3.php @@ -31,12 +31,11 @@ class HTMLPurifier_Lexer_PEARSax3 extends HTMLPurifier_Lexer */ var $tokens = array(); - function tokenizeHTML($string, $config = null) { + function tokenizeHTML($string, $config, &$context) { $this->tokens = array(); - if (!$config) $config = HTMLPurifier_Config::createDefault(); - $string = $this->normalize($string, $config); + $string = $this->normalize($string, $config, $context); $parser=& new XML_HTMLSax3(); $parser->set_object($this); diff --git a/library/HTMLPurifier/Strategy.php b/library/HTMLPurifier/Strategy.php index 5632eb86..746b0a2d 100644 --- a/library/HTMLPurifier/Strategy.php +++ b/library/HTMLPurifier/Strategy.php @@ -24,7 +24,7 @@ class HTMLPurifier_Strategy * @param $config Configuration options * @returns Processed array of token objects. */ - function execute($tokens, $config = null) { + function execute($tokens, $config, &$context) { trigger_error('Cannot call abstract function', E_USER_ERROR); } diff --git a/library/HTMLPurifier/Strategy/Composite.php b/library/HTMLPurifier/Strategy/Composite.php index 9e80e645..bd868747 100644 --- a/library/HTMLPurifier/Strategy/Composite.php +++ b/library/HTMLPurifier/Strategy/Composite.php @@ -18,9 +18,9 @@ class HTMLPurifier_Strategy_Composite extends HTMLPurifier_Strategy trigger_error('Attempt to instantiate abstract object', E_USER_ERROR); } - function execute($tokens, $config) { + function execute($tokens, $config, &$context) { foreach ($this->strategies as $strategy) { - $tokens = $strategy->execute($tokens, $config); + $tokens = $strategy->execute($tokens, $config, $context); } return $tokens; } diff --git a/library/HTMLPurifier/Strategy/FixNesting.php b/library/HTMLPurifier/Strategy/FixNesting.php index 18eb60b5..ca6f1a33 100644 --- a/library/HTMLPurifier/Strategy/FixNesting.php +++ b/library/HTMLPurifier/Strategy/FixNesting.php @@ -34,8 +34,7 @@ require_once 'HTMLPurifier/HTMLDefinition.php'; class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy { - function execute($tokens, $config) { - + function execute($tokens, $config, &$context) { //####################################################################// // Pre-processing @@ -49,6 +48,10 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy array_unshift($tokens, new HTMLPurifier_Token_Start($parent_name)); $tokens[] = new HTMLPurifier_Token_End($parent_name); + // setup the context variables + $parent_type = 'unknown'; // reference var that we alter + $context->register('ParentType', $parent_type); + //####################################################################// // Loop initialization @@ -109,10 +112,10 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy // calculate context if (isset($parent_def)) { - $context = $parent_def->type; + $parent_type = $parent_def->type; } else { // generally found in specialized elements like UL - $context = 'unknown'; + $parent_type = 'unknown'; } //################################################################// @@ -145,7 +148,7 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy // have DTD child def validate children $result = $child_def->validateChildren( - $child_tokens, $config,$context); + $child_tokens, $config, $context); // determine whether or not this element has any exclusions $excludes = $def->excludes; @@ -247,6 +250,9 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy array_shift($tokens); array_pop($tokens); + // remove context variables + $context->destroy('ParentType'); + //####################################################################// // Return diff --git a/library/HTMLPurifier/Strategy/MakeWellFormed.php b/library/HTMLPurifier/Strategy/MakeWellFormed.php index d82205bb..52243767 100644 --- a/library/HTMLPurifier/Strategy/MakeWellFormed.php +++ b/library/HTMLPurifier/Strategy/MakeWellFormed.php @@ -10,7 +10,7 @@ require_once 'HTMLPurifier/Generator.php'; class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy { - function execute($tokens, $config) { + function execute($tokens, $config, &$context) { $definition = $config->getHTMLDefinition(); $generator = new HTMLPurifier_Generator(); $result = array(); @@ -86,7 +86,7 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy if (empty($current_nesting)) { if ($escape_invalid_tags) { $result[] = new HTMLPurifier_Token_Text( - $generator->generateFromToken($token, $config) + $generator->generateFromToken($token, $config, $context) ); } continue; @@ -123,7 +123,7 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy if ($skipped_tags === false) { if ($escape_invalid_tags) { $result[] = new HTMLPurifier_Token_Text( - $generator->generateFromToken($token, $config) + $generator->generateFromToken($token, $config, $context) ); } continue; diff --git a/library/HTMLPurifier/Strategy/RemoveForeignElements.php b/library/HTMLPurifier/Strategy/RemoveForeignElements.php index 1d9f7ae5..69976b27 100644 --- a/library/HTMLPurifier/Strategy/RemoveForeignElements.php +++ b/library/HTMLPurifier/Strategy/RemoveForeignElements.php @@ -16,7 +16,7 @@ require_once 'HTMLPurifier/TagTransform.php'; class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy { - function execute($tokens, $config) { + function execute($tokens, $config, &$context) { $definition = $config->getHTMLDefinition(); $generator = new HTMLPurifier_Generator(); $result = array(); @@ -37,7 +37,7 @@ class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy } elseif ($escape_invalid_tags) { // invalid tag, generate HTML and insert in $token = new HTMLPurifier_Token_Text( - $generator->generateFromToken($token, $config) + $generator->generateFromToken($token, $config, $context) ); } else { continue; diff --git a/library/HTMLPurifier/Strategy/ValidateAttributes.php b/library/HTMLPurifier/Strategy/ValidateAttributes.php index 3d3dec91..c4cd02b8 100644 --- a/library/HTMLPurifier/Strategy/ValidateAttributes.php +++ b/library/HTMLPurifier/Strategy/ValidateAttributes.php @@ -17,18 +17,18 @@ HTMLPurifier_ConfigSchema::define( class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy { - function execute($tokens, $config) { + function execute($tokens, $config, &$context) { $definition = $config->getHTMLDefinition(); // setup StrategyContext - $context = new HTMLPurifier_AttrContext(); + $attr_context = new HTMLPurifier_AttrContext(); // setup ID accumulator and load it with blacklisted IDs // eventually, we'll have a dedicated context object to hold // all these accumulators and caches. For now, just an IDAccumulator - $context->id_accumulator = new HTMLPurifier_IDAccumulator(); - $context->id_accumulator->load($config->get('Attr', 'IDBlacklist')); + $attr_context->id_accumulator = new HTMLPurifier_IDAccumulator(); + $attr_context->id_accumulator->load($config->get('Attr', 'IDBlacklist')); // create alias to global definition array, see also $defs // DEFINITION CALL @@ -81,14 +81,14 @@ class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy } else { // validate according to the element's definition $result = $defs[$attr_key]->validate( - $value, $config, $context + $value, $config, $attr_context ); } } elseif ( isset($d_defs[$attr_key]) ) { // there is a global definition defined, validate according // to the global definition $result = $d_defs[$attr_key]->validate( - $value, $config, $context + $value, $config, $attr_context ); } else { // system never heard of the attribute? DELETE! diff --git a/tests/HTMLPurifier/ChildDefTest.php b/tests/HTMLPurifier/ChildDefTest.php index db00bd20..fed88ecf 100644 --- a/tests/HTMLPurifier/ChildDefTest.php +++ b/tests/HTMLPurifier/ChildDefTest.php @@ -1,122 +1,78 @@ lex = new HTMLPurifier_Lexer_DirectLex(); - $this->gen = new HTMLPurifier_Generator(); - parent::UnitTestCase(); - } - - function assertSeries($inputs, $expect, $config, $context = array()) { - foreach ($inputs as $i => $input) { - - if (!isset($context[$i])) { - $context[$i] = null; - } - if (!isset($config[$i])) { - $config[$i] = HTMLPurifier_Config::createDefault(); - } - - $tokens = $this->lex->tokenizeHTML($input, $config[$i]); - $result = $this->def->validateChildren($tokens, $config[$i], $context[$i]); - - if (is_bool($expect[$i])) { - $this->assertIdentical($expect[$i], $result, "Test $i: %s"); - } else { - $result_html = $this->gen->generateFromTokens($result, $config[$i]); - $this->assertIdentical($expect[$i], $result_html, "Test $i: %s"); - paintIf($result_html, $result_html != $expect[$i]); - } - } + function setUp() { + $this->obj = null; + $this->func = 'validateChildren'; + $this->to_tokens = true; + $this->to_html = true; } function test_custom() { - $this->def = new HTMLPurifier_ChildDef_Custom( - '(a, b?, c*, d+, (a, b)*)'); + $this->obj = new HTMLPurifier_ChildDef_Custom('(a,b?,c*,d+,(a,b)*)'); - $inputs = array(); - $expect = array(); - $config = array(); + $this->assertResult('', false); + $this->assertResult('', false); - $inputs[0] = ''; - $expect[0] = false; + $this->assertResult(''); + $this->assertResult('Dobfoo'. + 'foo'); - $inputs[1] = ''; - $expect[1] = true; - - $inputs[2] = 'Dobfoofoo'; - $expect[2] = true; - - $inputs[3] = ''; - $expect[3] = false; - - $this->assertSeries($inputs, $expect, $config); } function test_table() { - // currently inactive, awaiting augmentation - // the table definition - $this->def = new HTMLPurifier_ChildDef_Table(); + $this->obj = new HTMLPurifier_ChildDef_Table(); $inputs = $expect = $config = array(); - $inputs[0] = ''; - $expect[0] = false; + $this->assertResult('', false); // we're using empty tags to compact the tests: under real circumstances // there would be contents in them - $inputs[1] = ''; - $expect[1] = true; - - $inputs[2] = ''. - 'asdf'; - $expect[2] = true; - - $inputs[3] = ''; - $expect[3] = true; + $this->assertResult(''); + $this->assertResult(''. + 'asdf'); + $this->assertResult(''); // mixed up order - $inputs[4] = '1'; - $expect[4] = '1'; + $this->assertResult( + '1', + '1'); // duplicates of singles // - first caption serves // - trailing tfoots/theads get turned into tbodys - $inputs[5] = '11'; - $expect[5] = '11'; + $this->assertResult( + '11', + '11' + ); // errant text dropped (until bubbling is implemented) - $inputs[6] = 'foo'; - $expect[6] = false; + $this->assertResult('foo', false); // whitespace sticks to the previous element, last whitespace is // stationary - $inputs[7] = "\n \n \n "; - $expect[7] = true; - - $inputs[8] = "\n\t\n\t\t\n\t\t\t"; - $expect[8] = "\n\t\t\n\t\n\t\t\t"; - - $this->assertSeries($inputs, $expect, $config); + $this->assertResult("\n \n \n "); + $this->assertResult( + "\n\t\n\t\t\n\t\t\t", + "\n\t\t\n\t\n\t\t\t" + ); } - function test_parsing() { + function testParsing() { $def = new HTMLPurifier_ChildDef_Required('foobar | bang |gizmo'); $this->assertEqual($def->elements, @@ -132,92 +88,78 @@ class HTMLPurifier_ChildDefTest extends UnitTestCase 'href' => true ,'src' => true )); + } function test_required_pcdata_forbidden() { - $this->def = new HTMLPurifier_ChildDef_Required('dt | dd'); - $inputs = $expect = $config = array(); + $this->obj = new HTMLPurifier_ChildDef_Required('dt | dd'); - $inputs[0] = ''; - $expect[0] = false; - - $inputs[1] = '
Term
Text in an illegal location'. - '
Definition
Illegal tag'; - - $expect[1] = '
Term
Definition
'; - - $inputs[2] = 'How do you do!'; - $expect[2] = false; + $this->assertResult('', false); + $this->assertResult( + '
Term
Text in an illegal location'. + '
Definition
Illegal tag', + '
Term
Definition
'); + $this->assertResult('How do you do!', false); // whitespace shouldn't trigger it - $inputs[3] = "\n
Definition
"; - $expect[3] = true; + $this->assertResult("\n
Definition
"); - $inputs[4] ='
Definition
'; - $expect[4] = '
Definition
'; - - $inputs[5] = "\t "; - $expect[5] = false; - - $this->assertSeries($inputs, $expect, $config); + $this->assertResult( + '
Definition
', + '
Definition
' + ); + $this->assertResult("\t ", false); } function test_required_pcdata_allowed() { - $this->def = new HTMLPurifier_ChildDef_Required('#PCDATA | b'); - $inputs = $expect = $config = array(); + $this->obj = new HTMLPurifier_ChildDef_Required('#PCDATA | b'); - $inputs[0] = 'Bold text'; - $expect[0] = 'Bold text'; + $this->assertResult('Bold text', 'Bold text'); // with child escaping on - $inputs[1] = 'Bold text'; - $expect[1] = 'Bold text<img />'; - $config[1] = HTMLPurifier_Config::createDefault(); - $config[1]->set('Core', 'EscapeInvalidChildren', true); + $this->assertResult( + 'Bold text', + 'Bold text<img />', + array( + 'Core.EscapeInvalidChildren' => true + ) + ); - $this->assertSeries($inputs, $expect, $config); } function test_optional() { - $this->def = new HTMLPurifier_ChildDef_Optional('b | i'); - $inputs = $expect = $config = array(); + $this->obj = new HTMLPurifier_ChildDef_Optional('b | i'); - $inputs[0] = 'Bold text'; - $expect[0] = 'Bold text'; + $this->assertResult('Bold text', 'Bold text'); + $this->assertResult('Not allowed text', ''); - $inputs[1] = 'Not allowed text'; - $expect[1] = ''; - - $this->assertSeries($inputs, $expect, $config); } function test_chameleon() { - $this->def = new HTMLPurifier_ChildDef_Chameleon( - 'b | i', // allowed only when in inline context + $this->obj = new HTMLPurifier_ChildDef_Chameleon( + 'b | i', // allowed only when in inline context 'b | i | div' // allowed only when in block context ); - $inputs = $expect = $config = array(); - $context = array(); + $this->assertResult( + 'Allowed.', true, + array(), array('ParentType' => 'inline') + ); - $inputs[0] = 'Allowed.'; - $expect[0] = true; - $context[0] = 'inline'; + $this->assertResult( + '
Not allowed.
', '', + array(), array('ParentType' => 'inline') + ); - $inputs[1] = '
Not allowed.
'; - $expect[1] = ''; - $context[1] = 'inline'; - - $inputs[2] = '
Allowed.
'; - $expect[2] = true; - $context[2] = 'block'; - - $this->assertSeries($inputs, $expect, $config, $context); + $this->assertResult( + '
Allowed.
', true, + array(), array('ParentType' => 'block') + ); } diff --git a/tests/HTMLPurifier/EncoderTest.php b/tests/HTMLPurifier/EncoderTest.php index 2ada77b2..2e0eae8d 100644 --- a/tests/HTMLPurifier/EncoderTest.php +++ b/tests/HTMLPurifier/EncoderTest.php @@ -31,10 +31,11 @@ class HTMLPurifier_EncoderTest extends UnitTestCase function test_convertToUTF8() { $config = HTMLPurifier_Config::createDefault(); + $context = new HTMLPurifier_Context(); // UTF-8 means that we don't touch it $this->assertIdentical( - $this->Encoder->convertToUTF8("\xF6", $config), + $this->Encoder->convertToUTF8("\xF6", $config, $context), "\xF6" // this is invalid ); $this->assertNoErrors(); @@ -43,14 +44,14 @@ class HTMLPurifier_EncoderTest extends UnitTestCase // Now it gets converted $this->assertIdentical( - $this->Encoder->convertToUTF8("\xF6", $config), + $this->Encoder->convertToUTF8("\xF6", $config, $context), "\xC3\xB6" ); $config->set('Test', 'ForceNoIconv', true); $this->assertIdentical( - $this->Encoder->convertToUTF8("\xF6", $config), + $this->Encoder->convertToUTF8("\xF6", $config, $context), "\xC3\xB6" ); @@ -58,10 +59,11 @@ class HTMLPurifier_EncoderTest extends UnitTestCase function test_convertFromUTF8() { $config = HTMLPurifier_Config::createDefault(); + $context = new HTMLPurifier_Context(); // UTF-8 means that we don't touch it $this->assertIdentical( - $this->Encoder->convertFromUTF8("\xC3\xB6", $config), + $this->Encoder->convertFromUTF8("\xC3\xB6", $config, $context), "\xC3\xB6" ); @@ -69,14 +71,14 @@ class HTMLPurifier_EncoderTest extends UnitTestCase // Now it gets converted $this->assertIdentical( - $this->Encoder->convertFromUTF8("\xC3\xB6", $config), + $this->Encoder->convertFromUTF8("\xC3\xB6", $config, $context), "\xF6" ); $config->set('Test', 'ForceNoIconv', true); $this->assertIdentical( - $this->Encoder->convertFromUTF8("\xC3\xB6", $config), + $this->Encoder->convertFromUTF8("\xC3\xB6", $config, $context), "\xF6" ); diff --git a/tests/HTMLPurifier/Harness.php b/tests/HTMLPurifier/Harness.php new file mode 100644 index 00000000..69c242f5 --- /dev/null +++ b/tests/HTMLPurifier/Harness.php @@ -0,0 +1,107 @@ +lexer = new HTMLPurifier_Lexer_DirectLex(); + $this->generator = new HTMLPurifier_Generator(); + parent::UnitTestCase(); + } + + /** + * Asserts a specific result from a one parameter + config/context function + * @param $input Input parameter + * @param $expect Expectation + * @param $config_array Configuration array in form of + * Namespace.Directive => Value or an actual config + * object. + * @param $context_array Context array in form of Key => Value or an actual + * context object. + */ + function assertResult($input, $expect = true, + $config_array = array(), $context_array = array() + ) { + + // setup config object + $config = HTMLPurifier_Config::createDefault(); + foreach ($config_array as $key => $value) { + list($namespace, $directive) = explode('.', $key); + $config->set($namespace, $directive, $value); + } + + // setup context object + $context = new HTMLPurifier_Context(); + foreach ($context_array as $key => $value) { + $context->register($key, $value); + } + + if ($this->to_tokens && is_string($input)) { + $input = $this->lexer->tokenizeHTML($input, $config, $context); + } + + // call the function + $func = $this->func; + $result = $this->obj->$func($input, $config, $context); + + // test a bool result + if (is_bool($result)) { + $this->assertIdentical($expect, $result); + return; + } elseif (is_bool($expect)) { + $expect = $input; + } + + if ($this->to_html) { + $result = $this->generator-> + generateFromTokens($result, $config, $context); + if (is_array($expect)) { + $expect = $this->generator-> + generateFromTokens($expect, $config, $context); + } + } + + $this->assertEqual($expect, $result); + + } + +} + +?> diff --git a/tests/HTMLPurifier/Lexer/DirectLexTest.php b/tests/HTMLPurifier/Lexer/DirectLexTest.php index de35c1d1..4a2a0f16 100644 --- a/tests/HTMLPurifier/Lexer/DirectLexTest.php +++ b/tests/HTMLPurifier/Lexer/DirectLexTest.php @@ -53,9 +53,11 @@ class HTMLPurifier_Lexer_DirectLexTest extends UnitTestCase $input[10] = 'name="input" selected'; $expect[10] = array('name' => 'input', 'selected' => 'selected'); + $config = HTMLPurifier_Config::createDefault(); + $context = new HTMLPurifier_Context(); $size = count($input); for($i = 0; $i < $size; $i++) { - $result = $this->DirectLex->parseAttributeString($input[$i]); + $result = $this->DirectLex->parseAttributeString($input[$i], $config, $context); $this->assertEqual($expect[$i], $result, 'Test ' . $i . ': %s'); paintIf($result, $expect[$i] != $result); } diff --git a/tests/HTMLPurifier/LexerTest.php b/tests/HTMLPurifier/LexerTest.php index 1ddc8a67..a690466b 100644 --- a/tests/HTMLPurifier/LexerTest.php +++ b/tests/HTMLPurifier/LexerTest.php @@ -279,16 +279,17 @@ class HTMLPurifier_LexerTest extends UnitTestCase $expect[18] = array( new HTMLPurifier_Token_Empty('br', array('test' => 'x < 6')) ); $default_config = HTMLPurifier_Config::createDefault(); + $default_context = new HTMLPurifier_Context(); foreach($input as $i => $discard) { if (!isset($config[$i])) $config[$i] = $default_config; - $result = $this->DirectLex->tokenizeHTML($input[$i], $config[$i]); + $result = $this->DirectLex->tokenizeHTML($input[$i], $config[$i], $default_context); $this->assertEqual($expect[$i], $result, 'DirectLexTest '.$i.': %s'); paintIf($result, $expect[$i] != $result); if ($this->_has_pear) { // assert unless I say otherwise - $sax_result = $this->PEARSax3->tokenizeHTML($input[$i], $config[$i]); + $sax_result = $this->PEARSax3->tokenizeHTML($input[$i], $config[$i], $default_context); if (!isset($sax_expect[$i])) { // by default, assert with normal result $this->assertEqual($expect[$i], $sax_result, 'PEARSax3Test '.$i.': %s'); @@ -304,7 +305,7 @@ class HTMLPurifier_LexerTest extends UnitTestCase } if ($this->_has_dom) { - $dom_result = $this->DOMLex->tokenizeHTML($input[$i], $config[$i]); + $dom_result = $this->DOMLex->tokenizeHTML($input[$i], $config[$i], $default_context); // same structure as SAX if (!isset($dom_expect[$i])) { $this->assertEqual($expect[$i], $dom_result, 'DOMLexTest '.$i.': %s'); diff --git a/tests/HTMLPurifier/Strategy/CompositeTest.php b/tests/HTMLPurifier/Strategy/CompositeTest.php index b557b201..d626d011 100644 --- a/tests/HTMLPurifier/Strategy/CompositeTest.php +++ b/tests/HTMLPurifier/Strategy/CompositeTest.php @@ -28,6 +28,7 @@ class HTMLPurifier_Strategy_CompositeTest extends UnitTestCase $mock_1 = new HTMLPurifier_StrategyMock($this); $mock_2 = new HTMLPurifier_StrategyMock($this); $mock_3 = new HTMLPurifier_StrategyMock($this); + $context = new HTMLPurifier_Context(); // setup the object @@ -43,9 +44,9 @@ class HTMLPurifier_Strategy_CompositeTest extends UnitTestCase $config = new HTMLPurifier_ConfigMock(); - $params_1 = array($input_1, $config); - $params_2 = array($input_2, $config); - $params_3 = array($input_3, $config); + $params_1 = array($input_1, $config, $context); + $params_2 = array($input_2, $config, $context); + $params_3 = array($input_3, $config, $context); $mock_1->expectOnce('execute', $params_1); $mock_1->setReturnValue('execute', $input_2, $params_1); @@ -58,7 +59,7 @@ class HTMLPurifier_Strategy_CompositeTest extends UnitTestCase // perform test - $output = $composite->execute($input_1, $config); + $output = $composite->execute($input_1, $config, $context); $this->assertIdentical($input_4, $output); // tally the calls diff --git a/tests/HTMLPurifier/StrategyHarness.php b/tests/HTMLPurifier/StrategyHarness.php index a39daf36..3ca07753 100644 --- a/tests/HTMLPurifier/StrategyHarness.php +++ b/tests/HTMLPurifier/StrategyHarness.php @@ -25,12 +25,13 @@ class HTMLPurifier_StrategyHarness extends UnitTestCase } function assertStrategyWorks($strategy, $inputs, $expect, $config = array()) { + $context = new HTMLPurifier_Context(); foreach ($inputs as $i => $input) { - $tokens = $this->lex->tokenizeHTML($input); if (!isset($config[$i])) { $config[$i] = HTMLPurifier_Config::createDefault(); } - $result_tokens = $strategy->execute($tokens, $config[$i]); + $tokens = $this->lex->tokenizeHTML($input, $config[$i], $context); + $result_tokens = $strategy->execute($tokens, $config[$i], $context); $result = $this->gen->generateFromTokens($result_tokens, $config[$i]); $this->assertEqual($expect[$i], $result, "Test $i: %s"); paintIf($result, $result != $expect[$i]);