mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-11-09 15:28:40 +00:00
[1.2.0]
- All important classes that use Context were migrated. Todo: Classes that currently use $config but not $context are AttrTransform (done in r493) and URIScheme+Registry (done in r500). There may be more classes, incl TagTransform (done in r497) that should have both $config and $context added. - Strategy unit tests now migrated to use HTMLPurifier_Harness git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@485 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
8f515b9cda
commit
2d6bf12fe0
1
NEWS
1
NEWS
@ -10,6 +10,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
|
||||
1.2.0, unknown projected release date
|
||||
. Switched to purify()-wide Context object registry
|
||||
. Refactored unit tests to minimize duplication
|
||||
|
||||
1.1.3, unknown projected release date
|
||||
(bugfix release, may be dropped if no major bugs are found before features)
|
||||
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Internal data-structure used in attribute validation to accumulate state.
|
||||
*
|
||||
* This is a data-structure that holds objects that accumulate state, like
|
||||
* HTMLPurifier_IDAccumulator. It's better than using globals!
|
||||
*
|
||||
* @note Many functions that accept this object have it as a mandatory
|
||||
* parameter, even when there is no use for it. Though this is
|
||||
* for the same reasons as why HTMLPurifier_Config is a mandatory
|
||||
* parameter, it is also because you cannot assign a default value
|
||||
* to a parameter passed by reference (passing by reference is essential
|
||||
* for context to work in PHP 4).
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrContext
|
||||
{
|
||||
/**
|
||||
* Contains an HTMLPurifier_IDAccumulator, which keeps track of used IDs.
|
||||
* @public
|
||||
*/
|
||||
var $id_accumulator;
|
||||
}
|
||||
|
||||
?>
|
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrContext.php';
|
||||
|
||||
/**
|
||||
* Base class for all validating attribute definitions.
|
||||
*
|
||||
|
@ -20,7 +20,9 @@ class HTMLPurifier_AttrDef_ID extends HTMLPurifier_AttrDef
|
||||
$id = trim($id); // trim it first
|
||||
|
||||
if ($id === '') return false;
|
||||
if (isset($context->id_accumulator->ids[$id])) return false;
|
||||
|
||||
$id_accumulator = $context->get('IDAccumulator');
|
||||
if (isset($id_accumulator->ids[$id])) return false;
|
||||
|
||||
// we purposely avoid using regex, hopefully this is faster
|
||||
|
||||
@ -35,7 +37,7 @@ class HTMLPurifier_AttrDef_ID extends HTMLPurifier_AttrDef
|
||||
$result = ($trim === '');
|
||||
}
|
||||
|
||||
if ($result) $context->id_accumulator->add($id);
|
||||
if ($result) $id_accumulator->add($id);
|
||||
|
||||
// if no change was made to the ID, return the result
|
||||
// else, return the new id if stripping whitespace made it
|
||||
|
@ -60,9 +60,8 @@ class HTMLPurifier_Generator
|
||||
* @param $tokens Array of HTMLPurifier_Token
|
||||
* @param $config HTMLPurifier_Config object
|
||||
* @return Generated HTML
|
||||
* @note Only unit tests may omit configuration: internals MUST pass config
|
||||
*/
|
||||
function generateFromTokens($tokens, $config = null) {
|
||||
function generateFromTokens($tokens, $config, &$context) {
|
||||
$html = '';
|
||||
if (!$config) $config = HTMLPurifier_Config::createDefault();
|
||||
$this->_clean_utf8 = $config->get('Core', 'CleanUTF8DuringGeneration');
|
||||
|
@ -3,8 +3,6 @@
|
||||
require_once 'HTMLPurifier/Strategy.php';
|
||||
require_once 'HTMLPurifier/HTMLDefinition.php';
|
||||
require_once 'HTMLPurifier/IDAccumulator.php';
|
||||
require_once 'HTMLPurifier/ConfigSchema.php';
|
||||
require_once 'HTMLPurifier/AttrContext.php';
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'IDBlacklist', array(), 'list',
|
||||
@ -21,14 +19,10 @@ class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy
|
||||
|
||||
$definition = $config->getHTMLDefinition();
|
||||
|
||||
// setup StrategyContext
|
||||
$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
|
||||
$attr_context->id_accumulator = new HTMLPurifier_IDAccumulator();
|
||||
$attr_context->id_accumulator->load($config->get('Attr', 'IDBlacklist'));
|
||||
// setup id_accumulator context
|
||||
$id_accumulator = new HTMLPurifier_IDAccumulator();
|
||||
$id_accumulator->load($config->get('Attr', 'IDBlacklist'));
|
||||
$context->register('IDAccumulator', $id_accumulator);
|
||||
|
||||
// create alias to global definition array, see also $defs
|
||||
// DEFINITION CALL
|
||||
@ -81,14 +75,14 @@ class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy
|
||||
} else {
|
||||
// validate according to the element's definition
|
||||
$result = $defs[$attr_key]->validate(
|
||||
$value, $config, $attr_context
|
||||
$value, $config, $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, $attr_context
|
||||
$value, $config, $context
|
||||
);
|
||||
} else {
|
||||
// system never heard of the attribute? DELETE!
|
||||
@ -123,6 +117,8 @@ class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy
|
||||
// could interfere with flyweight implementation
|
||||
$tokens[$key]->attributes = $attr;
|
||||
}
|
||||
$context->destroy('IDAccumulator');
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ class HTMLPurifier_AttrDef_CompositeTest extends HTMLPurifier_AttrDefHarness
|
||||
generate_mock_once('HTMLPurifier_AttrDef');
|
||||
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$context = new HTMLPurifier_AttrContext();
|
||||
$context = new HTMLPurifier_Context();
|
||||
|
||||
// first test: value properly validates on first definition
|
||||
// so second def is never called
|
||||
|
@ -9,8 +9,9 @@ class HTMLPurifier_AttrDef_IDTest extends HTMLPurifier_AttrDefHarness
|
||||
|
||||
function test() {
|
||||
|
||||
$this->context = new HTMLPurifier_AttrContext();
|
||||
$this->context->id_accumulator = new HTMLPurifier_IDAccumulator();
|
||||
$this->context = new HTMLPurifier_Context();
|
||||
$id_accumulator = new HTMLPurifier_IDAccumulator();
|
||||
$this->context->register('IDAccumulator', $id_accumulator);
|
||||
$this->def = new HTMLPurifier_AttrDef_ID();
|
||||
|
||||
// valid ID names
|
||||
|
@ -11,7 +11,7 @@ class HTMLPurifier_AttrDefHarness extends UnitTestCase
|
||||
function assertDef($string, $expect = true, $ini = false, $message = '%s') {
|
||||
// $expect can be a string or bool
|
||||
if (!$this->config) $this->config = HTMLPurifier_Config::createDefault();
|
||||
if (!$this->context) $this->context = new HTMLPurifier_AttrContext();
|
||||
if (!$this->context) $this->context = new HTMLPurifier_Context();
|
||||
if ($ini) $this->setUpAssertDef();
|
||||
$result = $this->def->validate($string, $this->config, $this->context);
|
||||
if ($expect === true) {
|
||||
|
@ -3,7 +3,9 @@
|
||||
require_once 'HTMLPurifier/Generator.php';
|
||||
require_once 'HTMLPurifier/EntityLookup.php';
|
||||
|
||||
class HTMLPurifier_GeneratorTest extends UnitTestCase
|
||||
require_once 'HTMLPurifier/Harness.php';
|
||||
|
||||
class HTMLPurifier_GeneratorTest extends HTMLPurifier_Harness
|
||||
{
|
||||
|
||||
var $gen;
|
||||
@ -15,11 +17,16 @@ class HTMLPurifier_GeneratorTest extends UnitTestCase
|
||||
$this->_entity_lookup = HTMLPurifier_EntityLookup::instance();
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
$this->obj = new HTMLPurifier_Generator();
|
||||
$this->func = null;
|
||||
$this->to_tokens = false;
|
||||
$this->to_html = false;
|
||||
}
|
||||
|
||||
function test_generateFromToken() {
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$config = array();
|
||||
$inputs = $expect = array();
|
||||
|
||||
$inputs[0] = new HTMLPurifier_Token_Text('Foobar.<>');
|
||||
$expect[0] = 'Foobar.<>';
|
||||
@ -53,7 +60,7 @@ class HTMLPurifier_GeneratorTest extends UnitTestCase
|
||||
$expect[7] = $theta_char;
|
||||
|
||||
foreach ($inputs as $i => $input) {
|
||||
$result = $this->gen->generateFromToken($input);
|
||||
$result = $this->obj->generateFromToken($input);
|
||||
$this->assertEqual($result, $expect[$i]);
|
||||
paintIf($result, $result != $expect[$i]);
|
||||
}
|
||||
@ -62,9 +69,7 @@ class HTMLPurifier_GeneratorTest extends UnitTestCase
|
||||
|
||||
function test_generateAttributes() {
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$config = array();
|
||||
$inputs = $expect = array();
|
||||
|
||||
$inputs[0] = array();
|
||||
$expect[0] = '';
|
||||
@ -83,10 +88,8 @@ class HTMLPurifier_GeneratorTest extends UnitTestCase
|
||||
$inputs[4] = array('title' => 'Theta is ' . $theta_char);
|
||||
$expect[4] = 'title="Theta is ' . $theta_char . '"';
|
||||
|
||||
$default_config = HTMLPurifier_Config::createDefault();
|
||||
foreach ($inputs as $i => $input) {
|
||||
if (!isset($config[$i])) $config[$i] = $default_config;
|
||||
$result = $this->gen->generateAttributes($input, $config[$i]);
|
||||
$result = $this->obj->generateAttributes($input);
|
||||
$this->assertEqual($result, $expect[$i]);
|
||||
paintIf($result, $result != $expect[$i]);
|
||||
}
|
||||
@ -95,34 +98,26 @@ class HTMLPurifier_GeneratorTest extends UnitTestCase
|
||||
|
||||
function test_generateFromTokens() {
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$config = array();
|
||||
$this->func = 'generateFromTokens';
|
||||
|
||||
$inputs[0] = array(
|
||||
new HTMLPurifier_Token_Start('b'),
|
||||
new HTMLPurifier_Token_Text('Foobar!'),
|
||||
new HTMLPurifier_Token_End('b')
|
||||
);
|
||||
$expect[0] = '<b>Foobar!</b>';
|
||||
|
||||
$inputs[1] = array();
|
||||
$expect[1] = '';
|
||||
|
||||
$default_config = HTMLPurifier_Config::createDefault();
|
||||
foreach ($inputs as $i => $input) {
|
||||
if (!isset($config[$i])) $config[$i] = $default_config;
|
||||
$result = $this->gen->generateFromTokens($input, $config[$i]);
|
||||
$this->assertEqual($expect[$i], $result);
|
||||
paintIf($result, $result != $expect[$i]);
|
||||
}
|
||||
$this->assertResult(
|
||||
array(
|
||||
new HTMLPurifier_Token_Start('b'),
|
||||
new HTMLPurifier_Token_Text('Foobar!'),
|
||||
new HTMLPurifier_Token_End('b')
|
||||
),
|
||||
'<b>Foobar!</b>'
|
||||
);
|
||||
|
||||
$this->assertResult(array(), '');
|
||||
|
||||
}
|
||||
|
||||
var $config;
|
||||
function assertGeneration($tokens, $expect) {
|
||||
$result = $this->gen->generateFromTokens($tokens, $this->config);
|
||||
$context = new HTMLPurifier_Context();
|
||||
$result = $this->gen->generateFromTokens(
|
||||
$tokens, $this->config, $context);
|
||||
// normalized newlines, this probably should be put somewhere else
|
||||
$result = str_replace("\r\n", "\n", $result);
|
||||
$result = str_replace("\r", "\n", $result);
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/Lexer/DirectLex.php';
|
||||
|
||||
/**
|
||||
* General-purpose test-harness that makes testing functions that require
|
||||
* configuration and context objects easier when those two parameters are
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
require_once('HTMLPurifier/Strategy.php');
|
||||
require_once('HTMLPurifier/Strategy/Composite.php');
|
||||
require_once('HTMLPurifier/Config.php');
|
||||
require_once 'HTMLPurifier/Strategy.php';
|
||||
require_once 'HTMLPurifier/Strategy/Composite.php';
|
||||
require_once 'HTMLPurifier/Config.php';
|
||||
|
||||
class HTMLPurifier_Strategy_Composite_Test
|
||||
extends HTMLPurifier_Strategy_Composite
|
||||
@ -22,13 +22,13 @@ class HTMLPurifier_Strategy_CompositeTest extends UnitTestCase
|
||||
|
||||
generate_mock_once('HTMLPurifier_Strategy');
|
||||
generate_mock_once('HTMLPurifier_Config');
|
||||
generate_mock_once('HTMLPurifier_Context');
|
||||
|
||||
// setup a bunch of mock strategies to inject into our composite test
|
||||
|
||||
$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
|
||||
|
||||
@ -42,7 +42,8 @@ class HTMLPurifier_Strategy_CompositeTest extends UnitTestCase
|
||||
$input_3 = 'Processed by 1 and 2';
|
||||
$input_4 = 'Processed by 1, 2 and 3'; // expected output
|
||||
|
||||
$config = new HTMLPurifier_ConfigMock();
|
||||
$config = new HTMLPurifier_ConfigMock();
|
||||
$context = new HTMLPurifier_ContextMock();
|
||||
|
||||
$params_1 = array($input_1, $config, $context);
|
||||
$params_2 = array($input_2, $config, $context);
|
||||
|
@ -3,36 +3,34 @@
|
||||
require_once 'HTMLPurifier/StrategyHarness.php';
|
||||
require_once 'HTMLPurifier/Strategy/Core.php';
|
||||
|
||||
class HTMLPurifier_Strategy_CoreTest
|
||||
extends HTMLPurifier_StrategyHarness
|
||||
class HTMLPurifier_Strategy_CoreTest extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_Core();
|
||||
}
|
||||
|
||||
function test() {
|
||||
$strategy = new HTMLPurifier_Strategy_Core();
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$config = array();
|
||||
$this->assertResult('');
|
||||
$this->assertResult(
|
||||
'<b>Make well formed.',
|
||||
'<b>Make well formed.</b>'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<b><div>Fix nesting.</div></b>',
|
||||
'<b>Fix nesting.</b>'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<asdf>Foreign element removal.</asdf>',
|
||||
'Foreign element removal.'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<foo><b><div>All three.</div></b>',
|
||||
'<b>All three.</b>'
|
||||
);
|
||||
|
||||
$config_escape = HTMLPurifier_Config::createDefault();
|
||||
$config_escape->set('Core', 'EscapeInvalidChildren', true);
|
||||
|
||||
$inputs[0] = '';
|
||||
$expect[0] = '';
|
||||
|
||||
$inputs[1] = '<b>Make well formed.';
|
||||
$expect[1] = '<b>Make well formed.</b>';
|
||||
|
||||
$inputs[2] = '<b><div>Fix nesting.</div></b>';
|
||||
$expect[2] = '<b>Fix nesting.</b>';
|
||||
|
||||
$inputs[3] = '<asdf>Foreign element removal.</asdf>';
|
||||
$expect[3] = 'Foreign element removal.';
|
||||
|
||||
$inputs[4] = '<foo><b><div>All three.</div></b>';
|
||||
$expect[4] = '<b>All three.</b>';
|
||||
|
||||
$this->assertStrategyWorks($strategy, $inputs, $expect, $config);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,89 +3,86 @@
|
||||
require_once 'HTMLPurifier/StrategyHarness.php';
|
||||
require_once 'HTMLPurifier/Strategy/FixNesting.php';
|
||||
|
||||
class HTMLPurifier_Strategy_FixNestingTest
|
||||
extends HTMLPurifier_StrategyHarness
|
||||
class HTMLPurifier_Strategy_FixNestingTest extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_FixNesting();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
$strategy = new HTMLPurifier_Strategy_FixNesting();
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$config = array();
|
||||
|
||||
$config_escape = HTMLPurifier_Config::createDefault();
|
||||
$config_escape->set('Core', 'EscapeInvalidChildren', true);
|
||||
|
||||
// next id = 4
|
||||
|
||||
// legal inline nesting
|
||||
$inputs[0] = '<b>Bold text</b>';
|
||||
$expect[0] = $inputs[0];
|
||||
// legal inline
|
||||
$this->assertResult('<b>Bold text</b>');
|
||||
|
||||
// legal inline and block
|
||||
// as the parent element is considered FLOW
|
||||
$inputs[1] = '<a href="about:blank">Blank</a><div>Block</div>';
|
||||
$expect[1] = $inputs[1];
|
||||
$this->assertResult('<a href="about:blank">Blank</a><div>Block</div>');
|
||||
|
||||
// illegal block in inline
|
||||
$inputs[2] = '<b><div>Illegal div.</div></b>';
|
||||
$expect[2] = '<b>Illegal div.</b>';
|
||||
$this->assertResult(
|
||||
'<b><div>Illegal div.</div></b>',
|
||||
'<b>Illegal div.</b>'
|
||||
);
|
||||
|
||||
// same test with different configuration (fragile)
|
||||
$inputs[13] = '<b><div>Illegal div.</div></b>';
|
||||
$expect[13] = '<b><div>Illegal div.</div></b>';
|
||||
$config[13] = $config_escape;
|
||||
$this->assertResult(
|
||||
'<b><div>Illegal div.</div></b>',
|
||||
'<b><div>Illegal div.</div></b>',
|
||||
array('Core.EscapeInvalidChildren' => true)
|
||||
);
|
||||
|
||||
// test of empty set that's required, resulting in removal of node
|
||||
$inputs[3] = '<ul></ul>';
|
||||
$expect[3] = '';
|
||||
$this->assertResult('<ul></ul>', '');
|
||||
|
||||
// test illegal text which gets removed
|
||||
$inputs[4] = '<ul>Illegal text<li>Legal item</li></ul>';
|
||||
$expect[4] = '<ul><li>Legal item</li></ul>';
|
||||
$this->assertResult(
|
||||
'<ul>Illegal text<li>Legal item</li></ul>',
|
||||
'<ul><li>Legal item</li></ul>'
|
||||
);
|
||||
|
||||
// test custom table definition
|
||||
|
||||
$inputs[5] = '<table><tr><td>Cell 1</td></tr></table>';
|
||||
$expect[5] = '<table><tr><td>Cell 1</td></tr></table>';
|
||||
|
||||
$inputs[6] = '<table></table>';
|
||||
$expect[6] = '';
|
||||
$this->assertResult(
|
||||
'<table><tr><td>Cell 1</td></tr></table>',
|
||||
'<table><tr><td>Cell 1</td></tr></table>'
|
||||
);
|
||||
$this->assertResult('<table></table>', '');
|
||||
|
||||
// breaks without the redundant checking code
|
||||
$inputs[7] = '<table><tr></tr></table>';
|
||||
$expect[7] = '';
|
||||
$this->assertResult('<table><tr></tr></table>', '');
|
||||
|
||||
// special case, prevents scrolling one back to find parent
|
||||
$inputs[8] = '<table><tr></tr><tr></tr></table>';
|
||||
$expect[8] = '';
|
||||
$this->assertResult('<table><tr></tr><tr></tr></table>', '');
|
||||
|
||||
// cascading rollbacks
|
||||
$inputs[9] = '<table><tbody><tr></tr><tr></tr></tbody><tr></tr><tr></tr></table>';
|
||||
$expect[9] = '';
|
||||
$this->assertResult(
|
||||
'<table><tbody><tr></tr><tr></tr></tbody><tr></tr><tr></tr></table>',
|
||||
''
|
||||
);
|
||||
|
||||
// rollbacks twice
|
||||
$inputs[10] = '<table></table><table></table>';
|
||||
$expect[10] = '';
|
||||
$this->assertResult('<table></table><table></table>', '');
|
||||
|
||||
// block in inline ins not allowed
|
||||
$inputs[11] = '<span><ins><div>Not allowed!</div></ins></span>';
|
||||
$expect[11] = '<span><ins>Not allowed!</ins></span>';
|
||||
$this->assertResult(
|
||||
'<span><ins><div>Not allowed!</div></ins></span>',
|
||||
'<span><ins>Not allowed!</ins></span>'
|
||||
);
|
||||
|
||||
// block in inline ins not allowed
|
||||
$inputs[14] = '<span><ins><div>Not allowed!</div></ins></span>';
|
||||
$expect[14] = '<span><ins><div>Not allowed!</div></ins></span>';
|
||||
$config[14] = $config_escape;
|
||||
$this->assertResult(
|
||||
'<span><ins><div>Not allowed!</div></ins></span>',
|
||||
'<span><ins><div>Not allowed!</div></ins></span>',
|
||||
array('Core.EscapeInvalidChildren' => true)
|
||||
);
|
||||
|
||||
// test exclusions
|
||||
$inputs[12] = '<a><span><a>Not allowed</a></span></a>';
|
||||
$expect[12] = '<a><span></span></a>';
|
||||
$this->assertResult(
|
||||
'<a><span><a>Not allowed</a></span></a>',
|
||||
'<a><span></span></a>'
|
||||
);
|
||||
|
||||
// next test is *15*
|
||||
|
||||
$this->assertStrategyWorks($strategy, $inputs, $expect, $config);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,53 +3,62 @@
|
||||
require_once 'HTMLPurifier/StrategyHarness.php';
|
||||
require_once 'HTMLPurifier/Strategy/MakeWellFormed.php';
|
||||
|
||||
class HTMLPurifier_Strategy_MakeWellFormedTest
|
||||
extends HTMLPurifier_StrategyHarness
|
||||
class HTMLPurifier_Strategy_MakeWellFormedTest extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_MakeWellFormed();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
$strategy = new HTMLPurifier_Strategy_MakeWellFormed();
|
||||
$this->assertResult('');
|
||||
$this->assertResult('This is <b>bold text</b>.');
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$this->assertResult(
|
||||
'<b>Unclosed tag, gasp!',
|
||||
'<b>Unclosed tag, gasp!</b>'
|
||||
);
|
||||
|
||||
$inputs[0] = '';
|
||||
$expect[0] = $inputs[0];
|
||||
$this->assertResult(
|
||||
'<b><i>Bold and italic?</b>',
|
||||
'<b><i>Bold and italic?</i></b>'
|
||||
);
|
||||
|
||||
$inputs[1] = 'This is <b>bold text</b>.';
|
||||
$expect[1] = $inputs[1];
|
||||
$this->assertResult(
|
||||
'Unused end tags... recycle!</b>',
|
||||
'Unused end tags... recycle!'
|
||||
);
|
||||
|
||||
$inputs[2] = '<b>Unclosed tag, gasp!';
|
||||
$expect[2] = '<b>Unclosed tag, gasp!</b>';
|
||||
$this->assertResult(
|
||||
'<br style="clear:both;">',
|
||||
'<br style="clear:both;" />'
|
||||
);
|
||||
|
||||
$inputs[3] = '<b><i>Bold and italic?</b>';
|
||||
$expect[3] = '<b><i>Bold and italic?</i></b>';
|
||||
|
||||
// CHANGE THIS BEHAVIOR!
|
||||
$inputs[4] = 'Unused end tags... recycle!</b>';
|
||||
$expect[4] = 'Unused end tags... recycle!';
|
||||
|
||||
$inputs[5] = '<br style="clear:both;">';
|
||||
$expect[5] = '<br style="clear:both;" />';
|
||||
|
||||
$inputs[6] = '<div style="clear:both;" />';
|
||||
$expect[6] = '<div style="clear:both;"></div>';
|
||||
$this->assertResult(
|
||||
'<div style="clear:both;" />',
|
||||
'<div style="clear:both;"></div>'
|
||||
);
|
||||
|
||||
// test automatic paragraph closing
|
||||
|
||||
$inputs[7] = '<p>Paragraph 1<p>Paragraph 2';
|
||||
$expect[7] = '<p>Paragraph 1</p><p>Paragraph 2</p>';
|
||||
$this->assertResult(
|
||||
'<p>Paragraph 1<p>Paragraph 2',
|
||||
'<p>Paragraph 1</p><p>Paragraph 2</p>'
|
||||
);
|
||||
|
||||
$inputs[8] = '<div><p>Paragraphs<p>In<p>A<p>Div</div>';
|
||||
$expect[8] = '<div><p>Paragraphs</p><p>In</p><p>A</p><p>Div</p></div>';
|
||||
$this->assertResult(
|
||||
'<div><p>Paragraphs<p>In<p>A<p>Div</div>',
|
||||
'<div><p>Paragraphs</p><p>In</p><p>A</p><p>Div</p></div>'
|
||||
);
|
||||
|
||||
// automatic list closing
|
||||
|
||||
$inputs[9] = '<ol><li>Item 1<li>Item 2</ol>';
|
||||
$expect[9] = '<ol><li>Item 1</li><li>Item 2</li></ol>';
|
||||
|
||||
$this->assertStrategyWorks($strategy, $inputs, $expect);
|
||||
$this->assertResult(
|
||||
'<ol><li>Item 1<li>Item 2</ol>',
|
||||
'<ol><li>Item 1</li><li>Item 2</li></ol>'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,39 +4,44 @@ require_once 'HTMLPurifier/StrategyHarness.php';
|
||||
require_once 'HTMLPurifier/Strategy/RemoveForeignElements.php';
|
||||
|
||||
class HTMLPurifier_Strategy_RemoveForeignElementsTest
|
||||
extends HTMLPurifier_StrategyHarness
|
||||
extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_RemoveForeignElements();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
$strategy = new HTMLPurifier_Strategy_RemoveForeignElements();
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$this->assertResult('');
|
||||
|
||||
$inputs[0] = '';
|
||||
$expect[0] = $inputs[0];
|
||||
$this->assertResult('This is <b>bold text</b>.');
|
||||
|
||||
$inputs[1] = 'This is <b>bold text</b>.';
|
||||
$expect[1] = $inputs[1];
|
||||
$this->assertResult(
|
||||
'<asdf>Bling</asdf><d href="bang">Bong</d><foobar />',
|
||||
'BlingBong'
|
||||
);
|
||||
|
||||
// [INVALID]
|
||||
$inputs[2] = '<asdf>Bling</asdf><d href="bang">Bong</d><foobar />';
|
||||
$expect[2] = 'BlingBong';
|
||||
|
||||
// test simple transform
|
||||
$inputs[3] = '<menu><li>Item 1</li></menu>';
|
||||
$expect[3] = '<ul><li>Item 1</li></ul>';
|
||||
$this->assertResult(
|
||||
'<menu><li>Item 1</li></menu>',
|
||||
'<ul><li>Item 1</li></ul>'
|
||||
);
|
||||
|
||||
// test center transform
|
||||
$inputs[4] = '<center>Look I am Centered!</center>';
|
||||
$expect[4] = '<div style="text-align:center;">Look I am Centered!</div>';
|
||||
$this->assertResult(
|
||||
'<center>Look I am Centered!</center>',
|
||||
'<div style="text-align:center;">Look I am Centered!</div>'
|
||||
);
|
||||
|
||||
// test font transform
|
||||
$inputs[5] = '<font color="red" face="Arial" size="6">Big Warning!</font>';
|
||||
$expect[5] = '<span style="color:red;font-family:Arial;font-size:xx-large;">Big Warning!</span>';
|
||||
$this->assertResult(
|
||||
'<font color="red" face="Arial" size="6">Big Warning!</font>',
|
||||
'<span style="color:red;font-family:Arial;font-size:xx-large;">Big'.
|
||||
' Warning!</span>'
|
||||
);
|
||||
|
||||
$this->assertStrategyWorks($strategy, $inputs, $expect);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,71 +8,83 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends
|
||||
HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function test() {
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_ValidateAttributes();
|
||||
}
|
||||
|
||||
$strategy = new HTMLPurifier_Strategy_ValidateAttributes();
|
||||
function test() {
|
||||
|
||||
// attribute order is VERY fragile, perhaps we should define
|
||||
// an ordering scheme!
|
||||
|
||||
$inputs = array();
|
||||
$expect = array();
|
||||
$config = array();
|
||||
|
||||
$inputs[0] = '';
|
||||
$expect[0] = '';
|
||||
$this->assertResult('');
|
||||
|
||||
// test ids
|
||||
$this->assertResult('<div id="valid">Preserve the ID.</div>');
|
||||
|
||||
$inputs[1] = '<div id="valid">Preserve the ID.</div>';
|
||||
$expect[1] = $inputs[1];
|
||||
|
||||
$inputs[2] = '<div id="0invalid">Kill the ID.</div>';
|
||||
$expect[2] = '<div>Kill the ID.</div>';
|
||||
$this->assertResult(
|
||||
'<div id="0invalid">Kill the ID.</div>',
|
||||
'<div>Kill the ID.</div>'
|
||||
);
|
||||
|
||||
// test id accumulator
|
||||
$inputs[3] = '<div id="valid">Valid</div><div id="valid">Invalid</div>';
|
||||
$expect[3] = '<div id="valid">Valid</div><div>Invalid</div>';
|
||||
$this->assertResult(
|
||||
'<div id="valid">Valid</div><div id="valid">Invalid</div>',
|
||||
'<div id="valid">Valid</div><div>Invalid</div>'
|
||||
);
|
||||
|
||||
$inputs[4] = '<span dir="up-to-down">Bad dir.</span>';
|
||||
$expect[4] = '<span>Bad dir.</span>';
|
||||
$this->assertResult(
|
||||
'<span dir="up-to-down">Bad dir.</span>',
|
||||
'<span>Bad dir.</span>'
|
||||
);
|
||||
|
||||
// test attribute case sensitivity
|
||||
$inputs[5] = '<div ID="valid">Convert ID to lowercase.</div>';
|
||||
$expect[5] = '<div id="valid">Convert ID to lowercase.</div>';
|
||||
// test attribute key case sensitivity
|
||||
$this->assertResult(
|
||||
'<div ID="valid">Convert ID to lowercase.</div>',
|
||||
'<div id="valid">Convert ID to lowercase.</div>'
|
||||
);
|
||||
|
||||
// test simple attribute substitution
|
||||
$inputs[6] = '<div id=" valid ">Trim whitespace.</div>';
|
||||
$expect[6] = '<div id="valid">Trim whitespace.</div>';
|
||||
$this->assertResult(
|
||||
'<div id=" valid ">Trim whitespace.</div>',
|
||||
'<div id="valid">Trim whitespace.</div>'
|
||||
);
|
||||
|
||||
// test configuration id blacklist
|
||||
$inputs[7] = '<div id="invalid">Invalid</div>';
|
||||
$expect[7] = '<div>Invalid</div>';
|
||||
$config[7] = HTMLPurifier_Config::createDefault();
|
||||
$config[7]->set('Attr', 'IDBlacklist', array('invalid'));
|
||||
$this->assertResult(
|
||||
'<div id="invalid">Invalid</div>',
|
||||
'<div>Invalid</div>',
|
||||
array('Attr.IDBlacklist' => array('invalid'))
|
||||
);
|
||||
|
||||
// test classes
|
||||
$inputs[8] = '<div class="valid">Valid</div>';
|
||||
$expect[8] = $inputs[8];
|
||||
$this->assertResult('<div class="valid">Valid</div>');
|
||||
|
||||
$inputs[9] = '<div class="valid 0invalid">Keep valid.</div>';
|
||||
$expect[9] = '<div class="valid">Keep valid.</div>';
|
||||
$this->assertResult(
|
||||
'<div class="valid 0invalid">Keep valid.</div>',
|
||||
'<div class="valid">Keep valid.</div>'
|
||||
);
|
||||
|
||||
// test title
|
||||
$inputs[10] = '<acronym title="PHP: Hypertext Preprocessor">PHP</acronym>';
|
||||
$expect[10] = $inputs[10];
|
||||
$this->assertResult(
|
||||
'<acronym title="PHP: Hypertext Preprocessor">PHP</acronym>'
|
||||
);
|
||||
|
||||
// test lang
|
||||
$inputs[11] = '<span lang="fr">La soupe.</span>';
|
||||
$expect[11] = '<span lang="fr" xml:lang="fr">La soupe.</span>';
|
||||
$this->assertResult(
|
||||
'<span lang="fr">La soupe.</span>',
|
||||
'<span lang="fr" xml:lang="fr">La soupe.</span>'
|
||||
);
|
||||
|
||||
// test align (won't work till CSS validation is implemented)
|
||||
$inputs[12] = '<h1 align="center">Centered Headline</h1>';
|
||||
$expect[12] = '<h1 style="text-align:center;">Centered Headline</h1>';
|
||||
// test align
|
||||
$this->assertResult(
|
||||
'<h1 align="center">Centered Headline</h1>',
|
||||
'<h1 style="text-align:center;">Centered Headline</h1>'
|
||||
);
|
||||
|
||||
// test table
|
||||
$inputs[13] =
|
||||
|
||||
$this->assertResult(
|
||||
'<table frame="above" rules="rows" summary="A test table" border="2" cellpadding="5%" cellspacing="3" width="100%">
|
||||
<col align="right" width="4*" />
|
||||
<col charoff="5" align="char" width="1*" />
|
||||
@ -87,44 +99,56 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends
|
||||
<tr>
|
||||
<td colspan="2">Taken off the market</td>
|
||||
</tr>
|
||||
</table>';
|
||||
|
||||
$expect[13] = $inputs[13];
|
||||
</table>'
|
||||
);
|
||||
|
||||
// test URI
|
||||
$inputs[14] = '<a href="http://www.google.com/">Google</a>';
|
||||
$expect[14] = $inputs[14];
|
||||
$this->assertResult('<a href="http://www.google.com/">Google</a>');
|
||||
|
||||
// test invalid URI
|
||||
$inputs[15] = '<a href="javascript:badstuff();">Google</a>';
|
||||
$expect[15] = '<a>Google</a>';
|
||||
$this->assertResult(
|
||||
'<a href="javascript:badstuff();">Google</a>',
|
||||
'<a>Google</a>'
|
||||
);
|
||||
|
||||
// test required attributes for img
|
||||
$inputs[16] = '<img />';
|
||||
$expect[16] = '<img src="" alt="Invalid image" />';
|
||||
$this->assertResult(
|
||||
'<img />',
|
||||
'<img src="" alt="Invalid image" />'
|
||||
);
|
||||
|
||||
$inputs[17] = '<img src="foobar.jpg" />';
|
||||
$expect[17] = '<img src="foobar.jpg" alt="foobar.jpg" />';
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" />',
|
||||
'<img src="foobar.jpg" alt="foobar.jpg" />'
|
||||
);
|
||||
|
||||
$inputs[18] = '<img alt="pretty picture" />';
|
||||
$expect[18] = '<img alt="pretty picture" src="" />';
|
||||
$this->assertResult(
|
||||
'<img alt="pretty picture" />',
|
||||
'<img alt="pretty picture" src="" />'
|
||||
);
|
||||
|
||||
// test required attributes for bdo
|
||||
$inputs[19] = '<bdo>Go left.</bdo>';
|
||||
$expect[19] = '<bdo dir="ltr">Go left.</bdo>';
|
||||
$this->assertResult(
|
||||
'<bdo>Go left.</bdo>',
|
||||
'<bdo dir="ltr">Go left.</bdo>'
|
||||
);
|
||||
|
||||
$inputs[20] = '<bdo dir="blahblah">Invalid value!</bdo>';
|
||||
$expect[20] = '<bdo dir="ltr">Invalid value!</bdo>';
|
||||
$this->assertResult(
|
||||
'<bdo dir="blahblah">Invalid value!</bdo>',
|
||||
'<bdo dir="ltr">Invalid value!</bdo>'
|
||||
);
|
||||
|
||||
// comparison check for test 20
|
||||
$inputs[21] = '<span dir="blahblah">Invalid value!</span>';
|
||||
$expect[21] = '<span>Invalid value!</span>';
|
||||
$this->assertResult(
|
||||
'<span dir="blahblah">Invalid value!</span>',
|
||||
'<span>Invalid value!</span>'
|
||||
);
|
||||
|
||||
// test col.span is non-zero
|
||||
$inputs[22] = '<col span="0" />';
|
||||
$expect[22] = '<col />';
|
||||
|
||||
$this->assertStrategyWorks($strategy, $inputs, $expect, $config);
|
||||
$this->assertResult(
|
||||
'<col span="0" />',
|
||||
'<col />'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,41 +1,14 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/Lexer/DirectLex.php';
|
||||
require_once 'HTMLPurifier/Harness.php';
|
||||
|
||||
class HTMLPurifier_StrategyHarness extends UnitTestCase
|
||||
class HTMLPurifier_StrategyHarness extends HTMLPurifier_Harness
|
||||
{
|
||||
|
||||
var $lex, $gen;
|
||||
|
||||
function HTMLPurifier_StrategyHarness() {
|
||||
$this->UnitTestCase();
|
||||
|
||||
// we can't use the DOM lexer since it does too much stuff
|
||||
// automatically, however, we should be able to use it
|
||||
// interchangeably if we wanted to...
|
||||
|
||||
if (true) {
|
||||
$this->lex = new HTMLPurifier_Lexer_DirectLex();
|
||||
} else {
|
||||
require_once 'HTMLPurifier/Lexer/DOMLex.php';
|
||||
$this->lex = new HTMLPurifier_Lexer_DOMLex();
|
||||
}
|
||||
|
||||
$this->gen = new HTMLPurifier_Generator();
|
||||
}
|
||||
|
||||
function assertStrategyWorks($strategy, $inputs, $expect, $config = array()) {
|
||||
$context = new HTMLPurifier_Context();
|
||||
foreach ($inputs as $i => $input) {
|
||||
if (!isset($config[$i])) {
|
||||
$config[$i] = HTMLPurifier_Config::createDefault();
|
||||
}
|
||||
$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]);
|
||||
}
|
||||
function setUp() {
|
||||
$this->func = 'execute';
|
||||
$this->to_tokens = true;
|
||||
$this->to_html = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user