mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-13 17:43:58 +02:00
Release 2.1.2, merged in 1368 to HEAD.
git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/branches/strict@1404 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
@@ -67,6 +67,7 @@ class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
|
||||
$this->assertDef('border:1px solid #000;');
|
||||
$this->assertDef('border-bottom:2em double #FF00FA;');
|
||||
$this->assertDef('border-collapse:collapse;');
|
||||
$this->assertDef('border-collapse:separate;');
|
||||
$this->assertDef('caption-side:top;');
|
||||
$this->assertDef('vertical-align:middle;');
|
||||
$this->assertDef('vertical-align:12px;');
|
||||
@@ -79,6 +80,8 @@ class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
|
||||
$this->assertDef('background-repeat:repeat-y;');
|
||||
$this->assertDef('background-attachment:fixed;');
|
||||
$this->assertDef('background-position:left 90%;');
|
||||
$this->assertDef('border-spacing:1em;');
|
||||
$this->assertDef('border-spacing:1em 2em;');
|
||||
|
||||
// duplicates
|
||||
$this->assertDef('text-align:right;text-align:left;',
|
||||
|
@@ -11,18 +11,19 @@ class HTMLPurifier_AttrTransform_BdoDirTest extends HTMLPurifier_AttrTransformHa
|
||||
$this->obj = new HTMLPurifier_AttrTransform_BdoDir();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
function testAddDefaultDir() {
|
||||
$this->assertResult( array(), array('dir' => 'ltr') );
|
||||
|
||||
// leave existing dir alone
|
||||
}
|
||||
|
||||
function testPreserveExistingDir() {
|
||||
$this->assertResult( array('dir' => 'rtl') );
|
||||
|
||||
// use a different default
|
||||
}
|
||||
|
||||
function testAlternateDefault() {
|
||||
$this->config->set('Attr', 'DefaultTextDir', 'rtl');
|
||||
$this->assertResult(
|
||||
array(),
|
||||
array('dir' => 'rtl'),
|
||||
array('Attr.DefaultTextDir' => 'rtl')
|
||||
array('dir' => 'rtl')
|
||||
);
|
||||
|
||||
}
|
||||
|
@@ -3,6 +3,10 @@
|
||||
require_once 'HTMLPurifier/AttrTransform/BgColor.php';
|
||||
require_once 'HTMLPurifier/AttrTransformHarness.php';
|
||||
|
||||
// we currently rely on the CSS validator to fix any problems.
|
||||
// This means that this transform, strictly speaking, supports
|
||||
// a superset of the functionality.
|
||||
|
||||
class HTMLPurifier_AttrTransform_BgColorTest extends HTMLPurifier_AttrTransformHarness
|
||||
{
|
||||
|
||||
@@ -11,31 +15,31 @@ class HTMLPurifier_AttrTransform_BgColorTest extends HTMLPurifier_AttrTransformH
|
||||
$this->obj = new HTMLPurifier_AttrTransform_BgColor();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult( array() );
|
||||
|
||||
// we currently rely on the CSS validator to fix any problems.
|
||||
// This means that this transform, strictly speaking, supports
|
||||
// a superset of the functionality.
|
||||
|
||||
}
|
||||
|
||||
function testBasicTransform() {
|
||||
$this->assertResult(
|
||||
array('bgcolor' => '#000000'),
|
||||
array('style' => 'background-color:#000000;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testPrependNewCSS() {
|
||||
$this->assertResult(
|
||||
array('bgcolor' => '#000000', 'style' => 'font-weight:bold'),
|
||||
array('style' => 'background-color:#000000;font-weight:bold')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testLenientTreatmentOfInvalidInput() {
|
||||
// this may change when we natively support the datatype and
|
||||
// validate its contents before forwarding it on
|
||||
$this->assertResult(
|
||||
array('bgcolor' => '#F00'),
|
||||
array('style' => 'background-color:#F00;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,27 +11,29 @@ class HTMLPurifier_AttrTransform_BoolToCSSTest extends HTMLPurifier_AttrTransfor
|
||||
$this->obj = new HTMLPurifier_AttrTransform_BoolToCSS('foo', 'bar:3in;');
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult( array() );
|
||||
|
||||
}
|
||||
|
||||
function testBasicTransform() {
|
||||
$this->assertResult(
|
||||
array('foo' => 'foo'),
|
||||
array('style' => 'bar:3in;')
|
||||
);
|
||||
|
||||
// boolean attribute just has to be set: we don't care about
|
||||
// anything else
|
||||
}
|
||||
|
||||
function testIgnoreValueOfBooleanAttribute() {
|
||||
$this->assertResult(
|
||||
array('foo' => 'no'),
|
||||
array('style' => 'bar:3in;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testPrependCSS() {
|
||||
$this->assertResult(
|
||||
array('foo' => 'foo', 'style' => 'background-color:#F00;'),
|
||||
array('style' => 'bar:3in;background-color:#F00;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -12,27 +12,29 @@ class HTMLPurifier_AttrTransform_BorderTest extends HTMLPurifier_AttrTransformHa
|
||||
$this->obj = new HTMLPurifier_AttrTransform_Border();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult( array() );
|
||||
|
||||
}
|
||||
|
||||
function testBasicTransform() {
|
||||
$this->assertResult(
|
||||
array('border' => '1'),
|
||||
array('style' => 'border:1px solid;')
|
||||
);
|
||||
|
||||
// once again, no validation done here, we expect CSS validator
|
||||
// to catch it
|
||||
}
|
||||
|
||||
function testLenientTreatmentOfInvalidInput() {
|
||||
$this->assertResult(
|
||||
array('border' => '10%'),
|
||||
array('style' => 'border:10%px solid;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testPrependNewCSS() {
|
||||
$this->assertResult(
|
||||
array('border' => '23', 'style' => 'font-weight:bold;'),
|
||||
array('style' => 'border:23px solid;font-weight:bold;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,38 +6,44 @@ require_once 'HTMLPurifier/AttrTransformHarness.php';
|
||||
class HTMLPurifier_AttrTransform_EnumToCSSTest extends HTMLPurifier_AttrTransformHarness
|
||||
{
|
||||
|
||||
function testRegular() {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_AttrTransform_EnumToCSS('align', array(
|
||||
'left' => 'text-align:left;',
|
||||
'right' => 'text-align:right;'
|
||||
));
|
||||
|
||||
// leave empty arrays alone
|
||||
}
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult( array() );
|
||||
|
||||
// leave arrays without interesting stuff alone
|
||||
}
|
||||
|
||||
function testPreserveArraysWithoutInterestingAttributes() {
|
||||
$this->assertResult( array('style' => 'font-weight:bold;') );
|
||||
|
||||
// test each of the conversions
|
||||
|
||||
}
|
||||
|
||||
function testConvertAlignLeft() {
|
||||
$this->assertResult(
|
||||
array('align' => 'left'),
|
||||
array('style' => 'text-align:left;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testConvertAlignRight() {
|
||||
$this->assertResult(
|
||||
array('align' => 'right'),
|
||||
array('style' => 'text-align:right;')
|
||||
);
|
||||
|
||||
// drop garbage value
|
||||
}
|
||||
|
||||
function testRemoveInvalidAlign() {
|
||||
$this->assertResult(
|
||||
array('align' => 'invalid'),
|
||||
array()
|
||||
);
|
||||
|
||||
// test CSS munging
|
||||
}
|
||||
|
||||
function testPrependNewCSS() {
|
||||
$this->assertResult(
|
||||
array('align' => 'left', 'style' => 'font-weight:bold;'),
|
||||
array('style' => 'text-align:left;font-weight:bold;')
|
||||
@@ -46,31 +52,23 @@ class HTMLPurifier_AttrTransform_EnumToCSSTest extends HTMLPurifier_AttrTransfor
|
||||
}
|
||||
|
||||
function testCaseInsensitive() {
|
||||
|
||||
$this->obj = new HTMLPurifier_AttrTransform_EnumToCSS('align', array(
|
||||
'right' => 'text-align:right;'
|
||||
));
|
||||
|
||||
// test case insensitivity
|
||||
$this->assertResult(
|
||||
array('align' => 'RIGHT'),
|
||||
array('style' => 'text-align:right;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testCaseSensitive() {
|
||||
|
||||
$this->obj = new HTMLPurifier_AttrTransform_EnumToCSS('align', array(
|
||||
'right' => 'text-align:right;'
|
||||
), true);
|
||||
|
||||
// test case insensitivity
|
||||
$this->assertResult(
|
||||
array('align' => 'RIGHT'),
|
||||
array()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,39 +11,37 @@ class HTMLPurifier_AttrTransform_ImgRequiredTest extends HTMLPurifier_AttrTransf
|
||||
$this->obj = new HTMLPurifier_AttrTransform_ImgRequired();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
function testAddMissingAttr() {
|
||||
$this->config->set('Core', 'RemoveInvalidImg', false);
|
||||
$this->assertResult(
|
||||
array(),
|
||||
array('src' => '', 'alt' => 'Invalid image'),
|
||||
array(
|
||||
'Core.RemoveInvalidImg' => false
|
||||
)
|
||||
array('src' => '', 'alt' => 'Invalid image')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testAlternateDefaults() {
|
||||
$this->config->set('Attr', 'DefaultInvalidImage', 'blank.png');
|
||||
$this->config->set('Attr', 'DefaultInvalidImageAlt', 'Pawned!');
|
||||
$this->config->set('Core', 'RemoveInvalidImg', false);
|
||||
$this->assertResult(
|
||||
array(),
|
||||
array('src' => 'blank.png', 'alt' => 'Pawned!'),
|
||||
array(
|
||||
'Attr.DefaultInvalidImage' => 'blank.png',
|
||||
'Attr.DefaultInvalidImageAlt' => 'Pawned!',
|
||||
'Core.RemoveInvalidImg' => false
|
||||
)
|
||||
array('src' => 'blank.png', 'alt' => 'Pawned!')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testGenerateAlt() {
|
||||
$this->assertResult(
|
||||
array('src' => '/path/to/foobar.png'),
|
||||
array('src' => '/path/to/foobar.png', 'alt' => 'foobar.png')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testAddDefaultSrc() {
|
||||
$this->config->set('Core', 'RemoveInvalidImg', false);
|
||||
$this->assertResult(
|
||||
array('alt' => 'intrigue'),
|
||||
array('alt' => 'intrigue', 'src' => ''),
|
||||
array(
|
||||
'Core.RemoveInvalidImg' => false
|
||||
)
|
||||
array('alt' => 'intrigue', 'src' => '')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -9,33 +9,35 @@ class HTMLPurifier_AttrTransform_ImgSpaceTest extends HTMLPurifier_AttrTransform
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_AttrTransform_ImgSpace('vspace');
|
||||
}
|
||||
|
||||
function testVertical() {
|
||||
|
||||
$this->obj = new HTMLPurifier_AttrTransform_ImgSpace('vspace');
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult( array() );
|
||||
|
||||
}
|
||||
|
||||
function testVerticalBasicUsage() {
|
||||
$this->assertResult(
|
||||
array('vspace' => '1'),
|
||||
array('style' => 'margin-top:1px;margin-bottom:1px;')
|
||||
);
|
||||
|
||||
// no validation done here, we expect CSS validator to catch it
|
||||
}
|
||||
|
||||
function testLenientHandlingOfInvalidInput() {
|
||||
$this->assertResult(
|
||||
array('vspace' => '10%'),
|
||||
array('style' => 'margin-top:10%px;margin-bottom:10%px;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testPrependNewCSS() {
|
||||
$this->assertResult(
|
||||
array('vspace' => '23', 'style' => 'font-weight:bold;'),
|
||||
array('style' => 'margin-top:23px;margin-bottom:23px;font-weight:bold;')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testHorizontal() {
|
||||
function testHorizontalBasicUsage() {
|
||||
$this->obj = new HTMLPurifier_AttrTransform_ImgSpace('hspace');
|
||||
$this->assertResult(
|
||||
array('hspace' => '1'),
|
||||
@@ -43,7 +45,7 @@ class HTMLPurifier_AttrTransform_ImgSpaceTest extends HTMLPurifier_AttrTransform
|
||||
);
|
||||
}
|
||||
|
||||
function testInvalid() {
|
||||
function testInvalidConstructionParameter() {
|
||||
$this->expectError('ispace is not valid space attribute');
|
||||
$this->obj = new HTMLPurifier_AttrTransform_ImgSpace('ispace');
|
||||
$this->assertResult(
|
||||
|
@@ -13,35 +13,36 @@ class HTMLPurifier_AttrTransform_LangTest
|
||||
$this->obj = new HTMLPurifier_AttrTransform_Lang();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
// leave non-lang'ed elements alone
|
||||
$this->assertResult(array(), true);
|
||||
|
||||
// copy lang to xml:lang
|
||||
function testEmptyInput() {
|
||||
$this->assertResult(array());
|
||||
}
|
||||
|
||||
function testCopyLangToXMLLang() {
|
||||
$this->assertResult(
|
||||
array('lang' => 'en'),
|
||||
array('lang' => 'en', 'xml:lang' => 'en')
|
||||
);
|
||||
|
||||
// preserve attributes
|
||||
}
|
||||
|
||||
function testPreserveAttributes() {
|
||||
$this->assertResult(
|
||||
array('src' => 'vert.png', 'lang' => 'fr'),
|
||||
array('src' => 'vert.png', 'lang' => 'fr', 'xml:lang' => 'fr')
|
||||
);
|
||||
|
||||
// copy xml:lang to lang
|
||||
}
|
||||
|
||||
function testCopyXMLLangToLang() {
|
||||
$this->assertResult(
|
||||
array('xml:lang' => 'en'),
|
||||
array('xml:lang' => 'en', 'lang' => 'en')
|
||||
);
|
||||
|
||||
// both set, override lang with xml:lang
|
||||
}
|
||||
|
||||
function testXMLLangOverridesLang() {
|
||||
$this->assertResult(
|
||||
array('lang' => 'fr', 'xml:lang' => 'de'),
|
||||
array('lang' => 'de', 'xml:lang' => 'de')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,21 +11,32 @@ class HTMLPurifier_AttrTransform_LengthTest extends HTMLPurifier_AttrTransformHa
|
||||
$this->obj = new HTMLPurifier_AttrTransform_Length('width');
|
||||
}
|
||||
|
||||
function test() {
|
||||
function testEmptyInput() {
|
||||
$this->assertResult( array() );
|
||||
}
|
||||
|
||||
function testTransformPixel() {
|
||||
$this->assertResult(
|
||||
array('width' => '10'),
|
||||
array('style' => 'width:10px;')
|
||||
);
|
||||
}
|
||||
|
||||
function testTransformPercentage() {
|
||||
$this->assertResult(
|
||||
array('width' => '10%'),
|
||||
array('style' => 'width:10%;')
|
||||
);
|
||||
}
|
||||
|
||||
function testPrependNewCSS() {
|
||||
$this->assertResult(
|
||||
array('width' => '10%', 'style' => 'font-weight:bold'),
|
||||
array('style' => 'width:10%;font-weight:bold')
|
||||
);
|
||||
// this behavior might change
|
||||
}
|
||||
|
||||
function testLenientTreatmentOfInvalidInput() {
|
||||
$this->assertResult(
|
||||
array('width' => 'asdf'),
|
||||
array('style' => 'width:asdf;')
|
||||
|
@@ -11,12 +11,18 @@ class HTMLPurifier_AttrTransform_NameTest extends HTMLPurifier_AttrTransformHarn
|
||||
$this->obj = new HTMLPurifier_AttrTransform_Name();
|
||||
}
|
||||
|
||||
function test() {
|
||||
function testEmpty() {
|
||||
$this->assertResult( array() );
|
||||
}
|
||||
|
||||
function testTransformNameToID() {
|
||||
$this->assertResult(
|
||||
array('name' => 'free'),
|
||||
array('id' => 'free')
|
||||
);
|
||||
}
|
||||
|
||||
function testExistingIDOverridesName() {
|
||||
$this->assertResult(
|
||||
array('name' => 'tryit', 'id' => 'tobad'),
|
||||
array('id' => 'tobad')
|
||||
|
@@ -6,6 +6,7 @@ class HTMLPurifier_AttrTransformHarness extends HTMLPurifier_ComplexHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->func = 'transform';
|
||||
}
|
||||
|
||||
|
@@ -35,7 +35,7 @@ class HTMLPurifier_AttrValidator_ErrorsTest extends HTMLPurifier_ErrorsHarness
|
||||
$this->invoke($token);
|
||||
}
|
||||
|
||||
// to lazy to check for global post and global pre
|
||||
// too lazy to check for global post and global pre
|
||||
|
||||
function testAttributeRemoved() {
|
||||
$this->expectErrorCollection(E_ERROR, 'AttrValidator: Attribute removed');
|
||||
|
@@ -6,28 +6,36 @@ require_once 'HTMLPurifier/ChildDef/Chameleon.php';
|
||||
class HTMLPurifier_ChildDef_ChameleonTest extends HTMLPurifier_ChildDefHarness
|
||||
{
|
||||
|
||||
function test() {
|
||||
|
||||
var $isInline;
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_ChildDef_Chameleon(
|
||||
'b | i', // allowed only when in inline context
|
||||
'b | i | div' // allowed only when in block context
|
||||
);
|
||||
|
||||
$this->context->register('IsInline', $this->isInline);
|
||||
}
|
||||
|
||||
function testInlineAlwaysAllowed() {
|
||||
$this->isInline = true;
|
||||
$this->assertResult(
|
||||
'<b>Allowed.</b>', true,
|
||||
array(), array('IsInline' => true)
|
||||
'<b>Allowed.</b>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testBlockNotAllowedInInline() {
|
||||
$this->isInline = true;
|
||||
$this->assertResult(
|
||||
'<div>Not allowed.</div>', '',
|
||||
array(), array('IsInline' => true)
|
||||
'<div>Not allowed.</div>', ''
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testBlockAllowedInNonInline() {
|
||||
$this->isInline = false;
|
||||
$this->assertResult(
|
||||
'<div>Allowed.</div>', true,
|
||||
array(), array('IsInline' => false)
|
||||
'<div>Allowed.</div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,13 +6,17 @@ require_once 'HTMLPurifier/ChildDef/Optional.php';
|
||||
class HTMLPurifier_ChildDef_OptionalTest extends HTMLPurifier_ChildDefHarness
|
||||
{
|
||||
|
||||
function test() {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_ChildDef_Optional('b | i');
|
||||
|
||||
}
|
||||
|
||||
function testBasicUsage() {
|
||||
$this->assertResult('<b>Bold text</b><img />', '<b>Bold text</b>');
|
||||
}
|
||||
|
||||
function testRemoveForbiddenText() {
|
||||
$this->assertResult('Not allowed text', '');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,8 +6,7 @@ require_once 'HTMLPurifier/ChildDef/Required.php';
|
||||
class HTMLPurifier_ChildDef_RequiredTest extends HTMLPurifier_ChildDefHarness
|
||||
{
|
||||
|
||||
function testParsing() {
|
||||
|
||||
function testPrepareString() {
|
||||
$def = new HTMLPurifier_ChildDef_Required('foobar | bang |gizmo');
|
||||
$this->assertIdentical($def->elements,
|
||||
array(
|
||||
@@ -15,51 +14,61 @@ class HTMLPurifier_ChildDef_RequiredTest extends HTMLPurifier_ChildDefHarness
|
||||
,'bang' => true
|
||||
,'gizmo' => true
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
function testPrepareArray() {
|
||||
$def = new HTMLPurifier_ChildDef_Required(array('href', 'src'));
|
||||
$this->assertIdentical($def->elements,
|
||||
array(
|
||||
'href' => true
|
||||
,'src' => true
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
function testPCDATAForbidden() {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_ChildDef_Required('dt | dd');
|
||||
|
||||
}
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult('', false);
|
||||
}
|
||||
|
||||
function testRemoveIllegalTagsAndElements() {
|
||||
$this->assertResult(
|
||||
'<dt>Term</dt>Text in an illegal location'.
|
||||
'<dd>Definition</dd><b>Illegal tag</b>',
|
||||
'<dt>Term</dt><dd>Definition</dd>');
|
||||
$this->assertResult('How do you do!', false);
|
||||
|
||||
}
|
||||
|
||||
function testIgnoreWhitespace() {
|
||||
// whitespace shouldn't trigger it
|
||||
$this->assertResult("\n<dd>Definition</dd> ");
|
||||
|
||||
}
|
||||
|
||||
function testPreserveWhitespaceAfterRemoval() {
|
||||
$this->assertResult(
|
||||
'<dd>Definition</dd> <b></b> ',
|
||||
'<dd>Definition</dd> '
|
||||
);
|
||||
}
|
||||
|
||||
function testDeleteNodeIfOnlyWhitespace() {
|
||||
$this->assertResult("\t ", false);
|
||||
|
||||
}
|
||||
|
||||
function testPCDATAAllowed() {
|
||||
|
||||
$this->obj = new HTMLPurifier_ChildDef_Required('#PCDATA | b');
|
||||
|
||||
$this->assertResult('<b>Bold text</b><img />', '<b>Bold text</b>');
|
||||
|
||||
// with child escaping on
|
||||
$this->assertResult('Out <b>Bold text</b><img />', 'Out <b>Bold text</b>');
|
||||
}
|
||||
|
||||
function testPCDATAAllowedWithEscaping() {
|
||||
$this->obj = new HTMLPurifier_ChildDef_Required('#PCDATA | b');
|
||||
$this->config->set('Core', 'EscapeInvalidChildren', true);
|
||||
$this->assertResult(
|
||||
'<b>Bold text</b><img />',
|
||||
'<b>Bold text</b><img />',
|
||||
array(
|
||||
'Core.EscapeInvalidChildren' => true
|
||||
)
|
||||
'Out <b>Bold text</b><img />',
|
||||
'Out <b>Bold text</b><img />'
|
||||
);
|
||||
|
||||
}
|
||||
|
@@ -7,48 +7,77 @@ class HTMLPurifier_ChildDef_StrictBlockquoteTest
|
||||
extends HTMLPurifier_ChildDefHarness
|
||||
{
|
||||
|
||||
function test() {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_ChildDef_StrictBlockquote('div | p');
|
||||
|
||||
// assuming default wrap is p
|
||||
|
||||
}
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult('');
|
||||
}
|
||||
|
||||
function testPreserveValidP() {
|
||||
$this->assertResult('<p>Valid</p>');
|
||||
}
|
||||
|
||||
function testPreserveValidDiv() {
|
||||
$this->assertResult('<div>Still valid</div>');
|
||||
}
|
||||
|
||||
function testWrapTextWithP() {
|
||||
$this->assertResult('Needs wrap', '<p>Needs wrap</p>');
|
||||
}
|
||||
|
||||
function testNoWrapForWhitespaceOrValidElements() {
|
||||
$this->assertResult('<p>Do not wrap</p> <p>Whitespace</p>');
|
||||
}
|
||||
|
||||
function testWrapTextNextToValidElements() {
|
||||
$this->assertResult(
|
||||
'Wrap'. '<p>Do not wrap</p>',
|
||||
'<p>Wrap</p><p>Do not wrap</p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testWrapInlineElements() {
|
||||
$this->assertResult(
|
||||
'<p>Do not</p>'.'<b>Wrap</b>',
|
||||
'<p>Do not</p><p><b>Wrap</b></p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testWrapAndRemoveInvalidTags() {
|
||||
$this->assertResult(
|
||||
'<li>Not allowed</li>Paragraph.<p>Hmm.</p>',
|
||||
'<p>Not allowedParagraph.</p><p>Hmm.</p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testWrapComplicatedSring() {
|
||||
$this->assertResult(
|
||||
$var = 'He said<br />perhaps<br />we should <b>nuke</b> them.',
|
||||
"<p>$var</p>"
|
||||
);
|
||||
}
|
||||
|
||||
function testWrapAndRemoveInvalidTagsComplex() {
|
||||
$this->assertResult(
|
||||
'<foo>Bar</foo><bas /><b>People</b>Conniving.'. '<p>Fools!</p>',
|
||||
'<p>Bar'. '<b>People</b>Conniving.</p><p>Fools!</p>'
|
||||
);
|
||||
|
||||
$this->assertResult('Needs wrap', '<div>Needs wrap</div>',
|
||||
array('HTML.BlockWrapper' => 'div'));
|
||||
}
|
||||
|
||||
function testAlternateWrapper() {
|
||||
$this->config->set('HTML', 'BlockWrapper', 'div');
|
||||
$this->assertResult('Needs wrap', '<div>Needs wrap</div>');
|
||||
|
||||
}
|
||||
|
||||
function testError() {
|
||||
$this->expectError('Cannot use non-block element as block wrapper');
|
||||
$this->obj = new HTMLPurifier_ChildDef_StrictBlockquote('div | p');
|
||||
$this->assertResult('Needs wrap', '<p>Needs wrap</p>',
|
||||
array('HTML.BlockWrapper' => 'dav'));
|
||||
$this->swallowErrors();
|
||||
$this->config->set('HTML', 'BlockWrapper', 'dav');
|
||||
$this->assertResult('Needs wrap', '<p>Needs wrap</p>');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -3,46 +3,58 @@
|
||||
require_once 'HTMLPurifier/ChildDefHarness.php';
|
||||
require_once 'HTMLPurifier/ChildDef/Table.php';
|
||||
|
||||
// we're using empty tags to compact the tests: under real circumstances
|
||||
// there would be contents in them
|
||||
|
||||
class HTMLPurifier_ChildDef_TableTest extends HTMLPurifier_ChildDefHarness
|
||||
{
|
||||
|
||||
function test() {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_ChildDef_Table();
|
||||
|
||||
}
|
||||
|
||||
function testEmptyInput() {
|
||||
$this->assertResult('', false);
|
||||
|
||||
// we're using empty tags to compact the tests: under real circumstances
|
||||
// there would be contents in them
|
||||
|
||||
}
|
||||
|
||||
function testSingleRow() {
|
||||
$this->assertResult('<tr />');
|
||||
}
|
||||
|
||||
function testComplexContents() {
|
||||
$this->assertResult('<caption /><col /><thead /><tfoot /><tbody>'.
|
||||
'<tr><td>asdf</td></tr></tbody>');
|
||||
$this->assertResult('<col /><col /><col /><tr />');
|
||||
|
||||
// mixed up order
|
||||
}
|
||||
|
||||
function testReorderContents() {
|
||||
$this->assertResult(
|
||||
'<col /><colgroup /><tbody /><tfoot /><thead /><tr>1</tr><caption /><tr />',
|
||||
'<caption /><col /><colgroup /><thead /><tfoot /><tbody /><tr>1</tr><tr />');
|
||||
|
||||
// duplicates of singles
|
||||
// - first caption serves
|
||||
// - trailing tfoots/theads get turned into tbodys
|
||||
}
|
||||
|
||||
function testDuplicateProcessing() {
|
||||
$this->assertResult(
|
||||
'<caption>1</caption><caption /><tbody /><tbody /><tfoot>1</tfoot><tfoot />',
|
||||
'<caption>1</caption><tfoot>1</tfoot><tbody /><tbody /><tbody />'
|
||||
);
|
||||
|
||||
// errant text dropped (until bubbling is implemented)
|
||||
}
|
||||
|
||||
function testRemoveText() {
|
||||
$this->assertResult('foo', false);
|
||||
|
||||
// whitespace sticks to the previous element, last whitespace is
|
||||
// stationary
|
||||
$this->assertResult("\n <tr />\n <tr />\n ", true, array('Output.Newline' => "\n"));
|
||||
}
|
||||
|
||||
function testStickyWhitespaceOnTr() {
|
||||
$this->config->set('Output', 'Newline', "\n");
|
||||
$this->assertResult("\n <tr />\n <tr />\n ");
|
||||
}
|
||||
|
||||
function testStickyWhitespaceOnTSection() {
|
||||
$this->config->set('Output', 'Newline', "\n");
|
||||
$this->assertResult(
|
||||
"\n\t<tbody />\n\t\t<tfoot />\n\t\t\t",
|
||||
"\n\t\t<tfoot />\n\t<tbody />\n\t\t\t",
|
||||
array('Output.Newline' => "\n")
|
||||
"\n\t\t<tfoot />\n\t<tbody />\n\t\t\t"
|
||||
);
|
||||
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ class HTMLPurifier_ChildDefHarness extends HTMLPurifier_ComplexHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = null;
|
||||
$this->func = 'validateChildren';
|
||||
$this->to_tokens = true;
|
||||
|
@@ -67,41 +67,20 @@ class HTMLPurifier_ComplexHarness extends HTMLPurifier_Harness
|
||||
* @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
|
||||
if ($this->config) {
|
||||
$config = HTMLPurifier_Config::create($this->config);
|
||||
$config->autoFinalize = false;
|
||||
$config->loadArray($config_array);
|
||||
} else {
|
||||
$config = HTMLPurifier_Config::create($config_array);
|
||||
}
|
||||
|
||||
// setup context object. Note that we are operating on a copy of it!
|
||||
// When necessary, extend the test harness to allow post-tests
|
||||
// on the context object
|
||||
if (empty($this->context)) {
|
||||
$context = new HTMLPurifier_Context();
|
||||
$context->loadArray($context_array);
|
||||
} else {
|
||||
$context =& $this->context;
|
||||
}
|
||||
function assertResult($input, $expect = true) {
|
||||
|
||||
if ($this->to_tokens && is_string($input)) {
|
||||
// $func may cause $input to change, so "clone" another copy
|
||||
// to sacrifice
|
||||
$input = $this->lexer->tokenizeHTML($s = $input, $config, $context);
|
||||
$input_c = $this->lexer->tokenizeHTML($s, $config, $context);
|
||||
$input = $this->tokenize($temp = $input);
|
||||
$input_c = $this->tokenize($temp);
|
||||
} else {
|
||||
$input_c = $input;
|
||||
}
|
||||
|
||||
// call the function
|
||||
$func = $this->func;
|
||||
$result = $this->obj->$func($input_c, $config, $context);
|
||||
$result = $this->obj->$func($input_c, $this->config, $this->context);
|
||||
|
||||
// test a bool result
|
||||
if (is_bool($result)) {
|
||||
@@ -112,11 +91,9 @@ class HTMLPurifier_ComplexHarness extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
if ($this->to_html) {
|
||||
$result = $this->generator->
|
||||
generateFromTokens($result, $config, $context);
|
||||
$result = $this->generate($result);
|
||||
if (is_array($expect)) {
|
||||
$expect = $this->generator->
|
||||
generateFromTokens($expect, $config, $context);
|
||||
$expect = $this->generate($expect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +101,20 @@ class HTMLPurifier_ComplexHarness extends HTMLPurifier_Harness
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenize HTML into tokens, uses member variables for common variables
|
||||
*/
|
||||
function tokenize($html) {
|
||||
return $this->lexer->tokenizeHTML($html, $this->config, $this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate textual HTML from tokens
|
||||
*/
|
||||
function generate($tokens) {
|
||||
return $this->generator->generateFromTokens($tokens, $this->config, $this->context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -17,7 +17,7 @@ class HTMLPurifier_EntityLookupTest extends HTMLPurifier_Harness
|
||||
// special char
|
||||
$this->assertIdentical('"', $lookup->table['quot']);
|
||||
$this->assertIdentical('“', $lookup->table['ldquo']);
|
||||
$this->assertIdentical('<', $lookup->table['lt']); //expressed strangely
|
||||
$this->assertIdentical('<', $lookup->table['lt']); // expressed strangely in source file
|
||||
|
||||
// symbol char
|
||||
$this->assertIdentical('θ', $lookup->table['theta']);
|
||||
|
39
tests/HTMLPurifier/HTMLModule/ObjectTest.php
Normal file
39
tests/HTMLPurifier/HTMLModule/ObjectTest.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/HTMLModuleHarness.php';
|
||||
|
||||
class HTMLPurifier_HTMLModule_ObjectTest extends HTMLPurifier_HTMLModuleHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->config->set('HTML', 'Trusted', true);
|
||||
}
|
||||
|
||||
function testDefaultRemoval() {
|
||||
$this->config->set('HTML', 'Trusted', false);
|
||||
$this->assertResult(
|
||||
'<object></object>', ''
|
||||
);
|
||||
}
|
||||
|
||||
function testMinimal() {
|
||||
$this->assertResult('<object></object>');
|
||||
}
|
||||
|
||||
function testStandardUseCase() {
|
||||
$this->assertResult(
|
||||
'<object type="video/x-ms-wmv" data="http://domain.com/video.wmv" width="320" height="256">
|
||||
<param name="src" value="http://domain.com/video.wmv" />
|
||||
<param name="autostart" value="false" />
|
||||
<param name="controller" value="true" />
|
||||
<param name="pluginurl" value="http://www.microsoft.com/Windows/MediaPlayer/" />
|
||||
<a href="http://www.microsoft.com/Windows/MediaPlayer/">Windows Media player required</a>
|
||||
</object>'
|
||||
);
|
||||
}
|
||||
|
||||
// more test-cases?
|
||||
|
||||
}
|
||||
|
@@ -5,47 +5,51 @@ require_once 'HTMLPurifier/HTMLModuleHarness.php';
|
||||
class HTMLPurifier_HTMLModule_ScriptingTest extends HTMLPurifier_HTMLModuleHarness
|
||||
{
|
||||
|
||||
function test() {
|
||||
|
||||
// default (remove everything)
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->config->set('HTML', 'Trusted', true);
|
||||
$this->config->set('Core', 'CommentScriptContents', false);
|
||||
}
|
||||
|
||||
function testDefaultRemoval() {
|
||||
$this->config->set('HTML', 'Trusted', false);
|
||||
$this->assertResult(
|
||||
'<script type="text/javascript">foo();</script>', ''
|
||||
);
|
||||
|
||||
// enabled
|
||||
}
|
||||
|
||||
function testPreserve() {
|
||||
$this->assertResult(
|
||||
'<script type="text/javascript">foo();</script>', true,
|
||||
array('HTML.Trusted' => true)
|
||||
'<script type="text/javascript">foo();</script>'
|
||||
);
|
||||
|
||||
// CDATA
|
||||
}
|
||||
|
||||
function testCDATAEnclosure() {
|
||||
$this->assertResult(
|
||||
'//<![CDATA[
|
||||
'<script type="text/javascript">//<![CDATA[
|
||||
alert("<This is compatible with XHTML>");
|
||||
//]]> ', true,
|
||||
array('HTML.Trusted' => true)
|
||||
//]]></script>'
|
||||
);
|
||||
|
||||
// max
|
||||
}
|
||||
|
||||
function testAllAttributes() {
|
||||
$this->assertResult(
|
||||
'<script
|
||||
defer="defer"
|
||||
src="test.js"
|
||||
type="text/javascript"
|
||||
>PCDATA</script>', true,
|
||||
array('HTML.Trusted' => true, 'Core.CommentScriptContents' => false)
|
||||
>PCDATA</script>'
|
||||
);
|
||||
|
||||
// unsupported
|
||||
}
|
||||
|
||||
function testUnsupportedAttributes() {
|
||||
$this->assertResult(
|
||||
'<script
|
||||
type="text/javascript"
|
||||
charset="utf-8"
|
||||
>PCDATA</script>',
|
||||
'<script type="text/javascript">PCDATA</script>',
|
||||
array('HTML.Trusted' => true, 'Core.CommentScriptContents' => false)
|
||||
'<script type="text/javascript">PCDATA</script>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,29 +8,35 @@ class HTMLPurifier_Injector_AutoParagraphTest extends HTMLPurifier_InjectorHarne
|
||||
|
||||
function setup() {
|
||||
parent::setup();
|
||||
$this->config = array('AutoFormat.AutoParagraph' => true);
|
||||
$this->config->set('AutoFormat', 'AutoParagraph', true);
|
||||
}
|
||||
|
||||
function test() {
|
||||
function testSingleParagraph() {
|
||||
$this->assertResult(
|
||||
'Foobar',
|
||||
'<p>Foobar</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testSingleMultiLineParagraph() {
|
||||
$this->assertResult(
|
||||
'Par 1
|
||||
Par 1 still',
|
||||
'<p>Par 1
|
||||
Par 1 still</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testTwoParagraphs() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
|
||||
Par2',
|
||||
'<p>Par1</p><p>Par2</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testTwoParagraphsWithLotsOfSpace() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
|
||||
@@ -39,15 +45,18 @@ Par2',
|
||||
Par2',
|
||||
'<p>Par1</p><p>Par2</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testTwoParagraphsWithInlineElements() {
|
||||
$this->assertResult(
|
||||
'<b>Par1</b>
|
||||
|
||||
<i>Par2</i>',
|
||||
'<p><b>Par1</b></p><p><i>Par2</i></p>'
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
function testSingleParagraphThatLooksLikeTwo() {
|
||||
$this->assertResult(
|
||||
'<b>Par1
|
||||
|
||||
@@ -56,29 +65,40 @@ Par2</b>',
|
||||
|
||||
Par2</b></p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testAddParagraphAdjacentToParagraph() {
|
||||
$this->assertResult(
|
||||
'Par1<p>Par2</p>',
|
||||
'<p>Par1</p><p>Par2</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphUnclosedInlineElement() {
|
||||
$this->assertResult(
|
||||
'<b>Par1',
|
||||
'<p><b>Par1</b></p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testPreservePreTags() {
|
||||
$this->assertResult(
|
||||
'<pre>Par1
|
||||
|
||||
Par1</pre>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testIgnoreTrailingWhitespace() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
|
||||
',
|
||||
'<p>Par1</p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testDoNotParagraphBlockElements() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
|
||||
@@ -87,19 +107,25 @@ Par1</pre>'
|
||||
Par3',
|
||||
'<p>Par1</p><div>Par2</div><p>Par3</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphTextAndInlineNodes() {
|
||||
$this->assertResult(
|
||||
'Par<b>1</b>',
|
||||
'<p>Par<b>1</b></p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testIgnoreLeadingWhitespace() {
|
||||
$this->assertResult(
|
||||
'
|
||||
|
||||
Par',
|
||||
'<p>Par</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testIgnoreSurroundingWhitespace() {
|
||||
$this->assertResult(
|
||||
'
|
||||
|
||||
@@ -108,69 +134,90 @@ Par
|
||||
',
|
||||
'<p>Par</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphInsideBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div>Par1
|
||||
|
||||
Par2</div>',
|
||||
'<div><p>Par1</p><p>Par2</p></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphInlineNodeInsideBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div><b>Par1</b>
|
||||
|
||||
Par2</div>',
|
||||
'<div><p><b>Par1</b></p><p>Par2</p></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testNoParagraphWhenOnlyOneInsideBlockNode() {
|
||||
$this->assertResult('<div>Par1</div>');
|
||||
|
||||
}
|
||||
|
||||
function testParagraphTwoInlineNodesInsideBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div><b>Par1</b>
|
||||
|
||||
<i>Par2</i></div>',
|
||||
'<div><p><b>Par1</b></p><p><i>Par2</i></p></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testPreserveInlineNodesInPreTag() {
|
||||
$this->assertResult(
|
||||
'<pre><b>Par1</b>
|
||||
|
||||
<i>Par2</i></pre>',
|
||||
true
|
||||
<i>Par2</i></pre>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testSplitUpInternalsOfPTagInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div><p>Foo
|
||||
|
||||
Bar</p></div>',
|
||||
'<div><p>Foo</p><p>Bar</p></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testSplitUpInlineNodesInPTagInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div><p><b>Foo</b>
|
||||
|
||||
<i>Bar</i></p></div>',
|
||||
'<div><p><b>Foo</b></p><p><i>Bar</i></p></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testNoParagraphSingleInlineNodeInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div><b>Foo</b></div>',
|
||||
'<div><b>Foo</b></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphInBlockquote() {
|
||||
$this->assertResult(
|
||||
'<blockquote>Par1
|
||||
|
||||
Par2</blockquote>',
|
||||
'<blockquote><p>Par1</p><p>Par2</p></blockquote>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testNoParagraphBetweenListItem() {
|
||||
$this->assertResult(
|
||||
'<ul><li>Foo</li>
|
||||
|
||||
<li>Bar</li></ul>', true
|
||||
<li>Bar</li></ul>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphSingleElementWithSurroundingSpace() {
|
||||
$this->assertResult(
|
||||
'<div>
|
||||
|
||||
@@ -179,7 +226,9 @@ Bar
|
||||
</div>',
|
||||
'<div><p>Bar</p></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testIgnoreExtraSpaceWithLeadingInlineNode() {
|
||||
$this->assertResult(
|
||||
'<b>Par1</b>a
|
||||
|
||||
@@ -188,99 +237,124 @@ Bar
|
||||
Par2',
|
||||
'<p><b>Par1</b>a</p><p>Par2</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testAbsorbExtraEndingPTag() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
|
||||
Par2</p>',
|
||||
'<p>Par1</p><p>Par2</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testAbsorbExtraEndingDivTag() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
|
||||
Par2</div>',
|
||||
'<p>Par1</p><p>Par2</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testDoNotParagraphSingleSurroundingSpaceInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div>
|
||||
Par1
|
||||
</div>', true
|
||||
</div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testBlockNodeTextDelimeterInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div>Par1
|
||||
|
||||
<div>Par2</div></div>',
|
||||
'<div><p>Par1</p><div>Par2</div></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testBlockNodeTextDelimeterWithoutDoublespaceInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div>Par1
|
||||
<div>Par2</div></div>',
|
||||
'<div><p>Par1
|
||||
</p><div>Par2</div></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testBlockNodeTextDelimeterWithoutDoublespace() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
<div>Par2</div>',
|
||||
'<p>Par1
|
||||
</p><div>Par2</div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testTwoParagraphsOfTextAndInlineNode() {
|
||||
$this->assertResult(
|
||||
'Par1
|
||||
|
||||
<b>Par2</b>',
|
||||
'<p>Par1</p><p><b>Par2</b></p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testLeadingInlineNodeParagraph() {
|
||||
$this->assertResult(
|
||||
'<img /> Foo',
|
||||
'<p><img /> Foo</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testTrailingInlineNodeParagraph() {
|
||||
$this->assertResult(
|
||||
'<li>Foo <a>bar</a></li>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testTwoInlineNodeParagraph() {
|
||||
$this->assertResult(
|
||||
'<li><b>baz</b><a>bar</a></li>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testNoParagraphTrailingBlockNodeInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div><div>asdf</div><b>asdf</b></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphTrailingBlockNodeWithDoublespaceInBlockNode() {
|
||||
$this->assertResult(
|
||||
'<div><div>asdf</div>
|
||||
|
||||
<b>asdf</b></div>',
|
||||
'<div><div>asdf</div><p><b>asdf</b></p></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testParagraphTwoInlineNodesAndWhitespaceNode() {
|
||||
$this->assertResult(
|
||||
'<b>One</b> <i>Two</i>',
|
||||
'<p><b>One</b> <i>Two</i></p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testInlineRootNode() {
|
||||
function testNoParagraphWithInlineRootNode() {
|
||||
$this->config->set('HTML', 'Parent', 'span');
|
||||
$this->assertResult(
|
||||
'Par
|
||||
|
||||
Par2',
|
||||
true,
|
||||
array('AutoFormat.AutoParagraph' => true, 'HTML.Parent' => 'span')
|
||||
Par2'
|
||||
);
|
||||
}
|
||||
|
||||
function testNeeded() {
|
||||
function testErrorNeeded() {
|
||||
$this->config->set('HTML', 'Allowed', 'b');
|
||||
$this->expectError('Cannot enable AutoParagraph injector because p is not allowed');
|
||||
$this->assertResult('<b>foobar</b>', true, array('AutoFormat.AutoParagraph' => true, 'HTML.Allowed' => 'b'));
|
||||
$this->assertResult('<b>foobar</b>');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,35 +8,40 @@ class HTMLPurifier_Injector_LinkifyTest extends HTMLPurifier_InjectorHarness
|
||||
|
||||
function setup() {
|
||||
parent::setup();
|
||||
$this->config = array('AutoFormat.Linkify' => true);
|
||||
$this->config->set('AutoFormat', 'Linkify', true);
|
||||
}
|
||||
|
||||
function testLinkify() {
|
||||
|
||||
function testLinkifyURLInRootNode() {
|
||||
$this->assertResult(
|
||||
'http://example.com',
|
||||
'<a href="http://example.com">http://example.com</a>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testLinkifyURLInInlineNode() {
|
||||
$this->assertResult(
|
||||
'<b>http://example.com</b>',
|
||||
'<b><a href="http://example.com">http://example.com</a></b>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testBasicUsageCase() {
|
||||
$this->assertResult(
|
||||
'This URL http://example.com is what you need',
|
||||
'This URL <a href="http://example.com">http://example.com</a> is what you need'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testIgnoreURLInATag() {
|
||||
$this->assertResult(
|
||||
'<a>http://example.com/</a>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testNeeded() {
|
||||
$this->config->set('HTML', 'Allowed', 'b');
|
||||
$this->expectError('Cannot enable Linkify injector because a is not allowed');
|
||||
$this->assertResult('http://example.com/', true, array('AutoFormat.Linkify' => true, 'HTML.Allowed' => 'b'));
|
||||
$this->assertResult('http://example.com/');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,39 +8,53 @@ class HTMLPurifier_Injector_PurifierLinkifyTest extends HTMLPurifier_InjectorHar
|
||||
|
||||
function setup() {
|
||||
parent::setup();
|
||||
$this->config = array(
|
||||
'AutoFormat.PurifierLinkify' => true,
|
||||
'AutoFormatParam.PurifierLinkifyDocURL' => '#%s'
|
||||
);
|
||||
$this->config->set('AutoFormat', 'PurifierLinkify', true);
|
||||
$this->config->set('AutoFormatParam', 'PurifierLinkifyDocURL', '#%s');
|
||||
}
|
||||
|
||||
function testLinkify() {
|
||||
|
||||
function testNoTriggerCharacer() {
|
||||
$this->assertResult('Foobar');
|
||||
}
|
||||
|
||||
function testTriggerCharacterInIrrelevantContext() {
|
||||
$this->assertResult('20% off!');
|
||||
}
|
||||
|
||||
function testPreserveNamespace() {
|
||||
$this->assertResult('%Core namespace (not recognized)');
|
||||
}
|
||||
|
||||
function testLinkifyBasic() {
|
||||
$this->assertResult(
|
||||
'%Namespace.Directive',
|
||||
'<a href="#Namespace.Directive">%Namespace.Directive</a>'
|
||||
);
|
||||
}
|
||||
|
||||
function testLinkifyWithAdjacentTextNodes() {
|
||||
$this->assertResult(
|
||||
'This %Namespace.Directive thing',
|
||||
'This <a href="#Namespace.Directive">%Namespace.Directive</a> thing'
|
||||
);
|
||||
}
|
||||
|
||||
function testLinkifyInBlock() {
|
||||
$this->assertResult(
|
||||
'<div>This %Namespace.Directive thing</div>',
|
||||
'<div>This <a href="#Namespace.Directive">%Namespace.Directive</a> thing</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testPreserveInATag() {
|
||||
$this->assertResult(
|
||||
'<a>%Namespace.Directive</a>'
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
function testNeeded() {
|
||||
$this->config->set('HTML', 'Allowed', 'b');
|
||||
$this->expectError('Cannot enable PurifierLinkify injector because a is not allowed');
|
||||
$this->assertResult('%Namespace.Directive', true, array('AutoFormat.PurifierLinkify' => true, 'HTML.Allowed' => 'b'));
|
||||
$this->assertResult('%Namespace.Directive');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,70 +5,98 @@ require_once 'HTMLPurifier/Lexer/DirectLex.php';
|
||||
class HTMLPurifier_LexerTest extends HTMLPurifier_Harness
|
||||
{
|
||||
|
||||
var $Lexer;
|
||||
var $DirectLex, $PEARSax3, $DOMLex;
|
||||
var $_entity_lookup;
|
||||
var $_has_pear = false;
|
||||
var $_has_dom = false;
|
||||
|
||||
function setUp() {
|
||||
$this->Lexer = new HTMLPurifier_Lexer();
|
||||
|
||||
$this->DirectLex = new HTMLPurifier_Lexer_DirectLex();
|
||||
|
||||
if ( $GLOBALS['HTMLPurifierTest']['PEAR'] &&
|
||||
((error_reporting() & E_STRICT) != E_STRICT)
|
||||
function HTMLPurifier_LexerTest() {
|
||||
parent::HTMLPurifier_Harness();
|
||||
// E_STRICT = 2048, int used for PHP4 compat: this check disables
|
||||
// PEAR if PHP 5 strict mode is on, since the class is not strict safe
|
||||
if (
|
||||
$GLOBALS['HTMLPurifierTest']['PEAR'] &&
|
||||
((error_reporting() & 2048) != 2048) // ought to be a better way
|
||||
) {
|
||||
$this->_has_pear = true;
|
||||
require_once 'HTMLPurifier/Lexer/PEARSax3.php';
|
||||
$this->PEARSax3 = new HTMLPurifier_Lexer_PEARSax3();
|
||||
$this->_has_pear = true;
|
||||
}
|
||||
|
||||
$this->_has_dom = version_compare(PHP_VERSION, '5', '>=');
|
||||
if ($this->_has_dom) {
|
||||
require_once 'HTMLPurifier/Lexer/DOMLex.php';
|
||||
$this->DOMLex = new HTMLPurifier_Lexer_DOMLex();
|
||||
if ($GLOBALS['HTMLPurifierTest']['PH5P']) {
|
||||
require_once 'HTMLPurifier/Lexer/PH5P.php';
|
||||
}
|
||||
|
||||
$this->_entity_lookup = HTMLPurifier_EntityLookup::instance();
|
||||
|
||||
}
|
||||
|
||||
// HTMLPurifier_Lexer::create() --------------------------------------------
|
||||
|
||||
function test_create() {
|
||||
$config = HTMLPurifier_Config::create(array('Core.MaintainLineNumbers' => true));
|
||||
$lexer = HTMLPurifier_Lexer::create($config);
|
||||
$this->config->set('Core', 'MaintainLineNumbers', true);
|
||||
$lexer = HTMLPurifier_Lexer::create($this->config);
|
||||
$this->assertIsA($lexer, 'HTMLPurifier_Lexer_DirectLex');
|
||||
}
|
||||
|
||||
// HTMLPurifier_Lexer->parseData() -----------------------------------------
|
||||
|
||||
function assertParseData($input, $expect = true) {
|
||||
if ($expect === true) $expect = $input;
|
||||
$lexer = new HTMLPurifier_Lexer();
|
||||
$this->assertIdentical($expect, $lexer->parseData($input));
|
||||
}
|
||||
|
||||
function test_parseData_plainText() {
|
||||
$this->assertParseData('asdf');
|
||||
}
|
||||
|
||||
function test_parseData_ampersandEntity() {
|
||||
$this->assertParseData('&', '&');
|
||||
}
|
||||
|
||||
function test_parseData_quotEntity() {
|
||||
$this->assertParseData('"', '"');
|
||||
}
|
||||
|
||||
function test_parseData_aposNumericEntity() {
|
||||
$this->assertParseData(''', "'");
|
||||
}
|
||||
|
||||
function test_parseData_aposCompactNumericEntity() {
|
||||
$this->assertParseData(''', "'");
|
||||
}
|
||||
|
||||
function test_parseData_adjacentAmpersandEntities() {
|
||||
$this->assertParseData('&&&', '&&&');
|
||||
}
|
||||
|
||||
function test_parseData_trailingUnescapedAmpersand() {
|
||||
$this->assertParseData('&&', '&&');
|
||||
}
|
||||
|
||||
function test_parseData_internalUnescapedAmpersand() {
|
||||
$this->assertParseData('Procter & Gamble');
|
||||
}
|
||||
|
||||
function test_parseData_improperEntityFaultToleranceTest() {
|
||||
$this->assertParseData('-');
|
||||
}
|
||||
|
||||
// HTMLPurifier_Lexer->extractBody() ---------------------------------------
|
||||
|
||||
function assertExtractBody($text, $extract = true) {
|
||||
$result = $this->Lexer->extractBody($text);
|
||||
$lexer = new HTMLPurifier_Lexer();
|
||||
$result = $lexer->extractBody($text);
|
||||
if ($extract === true) $extract = $text;
|
||||
$this->assertIdentical($extract, $result);
|
||||
}
|
||||
|
||||
function test_parseData() {
|
||||
$HP =& $this->Lexer;
|
||||
|
||||
$this->assertIdentical('asdf', $HP->parseData('asdf'));
|
||||
$this->assertIdentical('&', $HP->parseData('&'));
|
||||
$this->assertIdentical('"', $HP->parseData('"'));
|
||||
$this->assertIdentical("'", $HP->parseData('''));
|
||||
$this->assertIdentical("'", $HP->parseData('''));
|
||||
$this->assertIdentical('&&&', $HP->parseData('&&&'));
|
||||
$this->assertIdentical('&&', $HP->parseData('&&')); // [INVALID]
|
||||
$this->assertIdentical('Procter & Gamble',
|
||||
$HP->parseData('Procter & Gamble')); // [INVALID]
|
||||
|
||||
// This is not special, thus not converted. Test of fault tolerance,
|
||||
// realistically speaking, this should never happen
|
||||
$this->assertIdentical('-', $HP->parseData('-'));
|
||||
function test_extractBody_noBodyTags() {
|
||||
$this->assertExtractBody('<b>Bold</b>');
|
||||
}
|
||||
|
||||
|
||||
function test_extractBody() {
|
||||
$this->assertExtractBody('<b>Bold</b>');
|
||||
function test_extractBody_lowercaseBodyTags() {
|
||||
$this->assertExtractBody('<html><body><b>Bold</b></body></html>', '<b>Bold</b>');
|
||||
}
|
||||
|
||||
function test_extractBody_uppercaseBodyTags() {
|
||||
$this->assertExtractBody('<HTML><BODY><B>Bold</B></BODY></HTML>', '<B>Bold</B>');
|
||||
}
|
||||
|
||||
function test_extractBody_realisticUseCase() {
|
||||
$this->assertExtractBody(
|
||||
'<?xml version="1.0"
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
@@ -96,303 +124,404 @@ class HTMLPurifier_LexerTest extends HTMLPurifier_Harness
|
||||
</div>
|
||||
</form>
|
||||
');
|
||||
$this->assertExtractBody('<html><body bgcolor="#F00"><b>Bold</b></body></html>', '<b>Bold</b>');
|
||||
$this->assertExtractBody('<body>asdf'); // not closed, don't accept
|
||||
|
||||
}
|
||||
|
||||
function test_tokenizeHTML() {
|
||||
|
||||
$input = array();
|
||||
$expect = array();
|
||||
$sax_expect = array();
|
||||
$config = array();
|
||||
|
||||
$input[0] = '';
|
||||
$expect[0] = array();
|
||||
|
||||
$input[1] = 'This is regular text.';
|
||||
$expect[1] = array(
|
||||
new HTMLPurifier_Token_Text('This is regular text.')
|
||||
);
|
||||
|
||||
$input[2] = 'This is <b>bold</b> text';
|
||||
$expect[2] = array(
|
||||
new HTMLPurifier_Token_Text('This is ')
|
||||
,new HTMLPurifier_Token_Start('b', array())
|
||||
,new HTMLPurifier_Token_Text('bold')
|
||||
,new HTMLPurifier_Token_End('b')
|
||||
,new HTMLPurifier_Token_Text(' text')
|
||||
);
|
||||
|
||||
$input[3] = '<DIV>Totally rad dude. <b>asdf</b></div>';
|
||||
$expect[3] = array(
|
||||
new HTMLPurifier_Token_Start('DIV', array())
|
||||
,new HTMLPurifier_Token_Text('Totally rad dude. ')
|
||||
,new HTMLPurifier_Token_Start('b', array())
|
||||
,new HTMLPurifier_Token_Text('asdf')
|
||||
,new HTMLPurifier_Token_End('b')
|
||||
,new HTMLPurifier_Token_End('div')
|
||||
);
|
||||
|
||||
// [XML-INVALID]
|
||||
$input[4] = '<asdf></asdf><d></d><poOloka><poolasdf><ds></asdf></ASDF>';
|
||||
$expect[4] = array(
|
||||
new HTMLPurifier_Token_Start('asdf')
|
||||
,new HTMLPurifier_Token_End('asdf')
|
||||
,new HTMLPurifier_Token_Start('d')
|
||||
,new HTMLPurifier_Token_End('d')
|
||||
,new HTMLPurifier_Token_Start('poOloka')
|
||||
,new HTMLPurifier_Token_Start('poolasdf')
|
||||
,new HTMLPurifier_Token_Start('ds')
|
||||
,new HTMLPurifier_Token_End('asdf')
|
||||
,new HTMLPurifier_Token_End('ASDF')
|
||||
);
|
||||
// DOM is different because it condenses empty tags into REAL empty ones
|
||||
// as well as makes it well-formed
|
||||
$dom_expect[4] = array(
|
||||
new HTMLPurifier_Token_Empty('asdf')
|
||||
,new HTMLPurifier_Token_Empty('d')
|
||||
,new HTMLPurifier_Token_Start('pooloka')
|
||||
,new HTMLPurifier_Token_Start('poolasdf')
|
||||
,new HTMLPurifier_Token_Empty('ds')
|
||||
,new HTMLPurifier_Token_End('poolasdf')
|
||||
,new HTMLPurifier_Token_End('pooloka')
|
||||
);
|
||||
|
||||
$input[5] = '<a'."\t".'href="foobar.php"'."\n".'title="foo!">Link to <b id="asdf">foobar</b></a>';
|
||||
$expect[5] = array(
|
||||
new HTMLPurifier_Token_Start('a',array('href'=>'foobar.php','title'=>'foo!'))
|
||||
,new HTMLPurifier_Token_Text('Link to ')
|
||||
,new HTMLPurifier_Token_Start('b',array('id'=>'asdf'))
|
||||
,new HTMLPurifier_Token_Text('foobar')
|
||||
,new HTMLPurifier_Token_End('b')
|
||||
,new HTMLPurifier_Token_End('a')
|
||||
);
|
||||
|
||||
$input[6] = '<br />';
|
||||
$expect[6] = array(
|
||||
new HTMLPurifier_Token_Empty('br')
|
||||
);
|
||||
|
||||
// [SGML-INVALID] [RECOVERABLE]
|
||||
$input[7] = '<!-- Comment --> <!-- not so well formed --->';
|
||||
$expect[7] = array(
|
||||
new HTMLPurifier_Token_Comment(' Comment ')
|
||||
,new HTMLPurifier_Token_Text(' ')
|
||||
,new HTMLPurifier_Token_Comment(' not so well formed -')
|
||||
);
|
||||
$sax_expect[7] = false; // we need to figure out proper comment output
|
||||
|
||||
// [SGML-INVALID]
|
||||
$input[8] = '<a href=""';
|
||||
$expect[8] = array(
|
||||
new HTMLPurifier_Token_Text('<a href=""')
|
||||
);
|
||||
// SAX parses it into a tag
|
||||
$sax_expect[8] = array(
|
||||
new HTMLPurifier_Token_Start('a', array('href'=>''))
|
||||
);
|
||||
// DOM parses it into an empty tag
|
||||
$dom_expect[8] = array(
|
||||
new HTMLPurifier_Token_Empty('a', array('href'=>''))
|
||||
);
|
||||
|
||||
$input[9] = '<b>';
|
||||
$expect[9] = array(
|
||||
new HTMLPurifier_Token_Text('<b>')
|
||||
);
|
||||
$sax_expect[9] = array(
|
||||
new HTMLPurifier_Token_Text('<')
|
||||
,new HTMLPurifier_Token_Text('b')
|
||||
,new HTMLPurifier_Token_Text('>')
|
||||
);
|
||||
// note that SAX can clump text nodes together. We won't be
|
||||
// too picky though
|
||||
|
||||
// [SGML-INVALID]
|
||||
$input[10] = '<a "=>';
|
||||
// We barf on this, aim for no attributes
|
||||
$expect[10] = array(
|
||||
new HTMLPurifier_Token_Start('a', array('"' => ''))
|
||||
);
|
||||
// DOM correctly has no attributes, but also closes the tag
|
||||
$dom_expect[10] = array(
|
||||
new HTMLPurifier_Token_Empty('a')
|
||||
);
|
||||
// SAX barfs on this
|
||||
$sax_expect[10] = array(
|
||||
new HTMLPurifier_Token_Start('a', array('"' => ''))
|
||||
);
|
||||
|
||||
// [INVALID] [RECOVERABLE]
|
||||
$input[11] = '"';
|
||||
$expect[11] = array( new HTMLPurifier_Token_Text('"') );
|
||||
|
||||
// compare with this valid one:
|
||||
$input[12] = '"';
|
||||
$expect[12] = array( new HTMLPurifier_Token_Text('"') );
|
||||
$sax_expect[12] = false; // choked!
|
||||
|
||||
// CDATA sections!
|
||||
$input[13] = '<![CDATA[You <b>can't</b> get me!]]>';
|
||||
$expect[13] = array( new HTMLPurifier_Token_Text(
|
||||
'You <b>can't</b> get me!' // raw
|
||||
) );
|
||||
$sax_expect[13] = array( // SAX has a seperate call for each entity
|
||||
new HTMLPurifier_Token_Text('You '),
|
||||
new HTMLPurifier_Token_Text('<'),
|
||||
new HTMLPurifier_Token_Text('b'),
|
||||
new HTMLPurifier_Token_Text('>'),
|
||||
new HTMLPurifier_Token_Text('can'),
|
||||
new HTMLPurifier_Token_Text('&'),
|
||||
new HTMLPurifier_Token_Text('#39;t'),
|
||||
new HTMLPurifier_Token_Text('<'),
|
||||
new HTMLPurifier_Token_Text('/b'),
|
||||
new HTMLPurifier_Token_Text('>'),
|
||||
new HTMLPurifier_Token_Text(' get me!')
|
||||
);
|
||||
|
||||
$char_theta = $this->_entity_lookup->table['theta'];
|
||||
$char_rarr = $this->_entity_lookup->table['rarr'];
|
||||
|
||||
// test entity replacement
|
||||
$input[14] = 'θ';
|
||||
$expect[14] = array( new HTMLPurifier_Token_Text($char_theta) );
|
||||
|
||||
// test that entities aren't replaced in CDATA sections
|
||||
$input[15] = 'θ <![CDATA[→]]>';
|
||||
$expect[15] = array( new HTMLPurifier_Token_Text($char_theta . ' →') );
|
||||
$sax_expect[15] = array(
|
||||
new HTMLPurifier_Token_Text($char_theta . ' '),
|
||||
new HTMLPurifier_Token_Text('&'),
|
||||
new HTMLPurifier_Token_Text('rarr;')
|
||||
);
|
||||
|
||||
// test entity resolution in attributes
|
||||
$input[16] = '<a href="index.php?title=foo&id=bar">Link</a>';
|
||||
$expect[16] = array(
|
||||
new HTMLPurifier_Token_Start('a',array('href' => 'index.php?title=foo&id=bar'))
|
||||
,new HTMLPurifier_Token_Text('Link')
|
||||
,new HTMLPurifier_Token_End('a')
|
||||
);
|
||||
|
||||
// test that UTF-8 is preserved
|
||||
$char_hearts = $this->_entity_lookup->table['hearts'];
|
||||
$input[17] = $char_hearts;
|
||||
$expect[17] = array( new HTMLPurifier_Token_Text($char_hearts) );
|
||||
|
||||
// test weird characters in attributes
|
||||
$input[18] = '<br test="x < 6" />';
|
||||
$expect[18] = array( new HTMLPurifier_Token_Empty('br', array('test' => 'x < 6')) );
|
||||
|
||||
// test emoticon protection
|
||||
$input[19] = '<b>Whoa! <3 That\'s not good >.></b>';
|
||||
$expect[19] = array(
|
||||
new HTMLPurifier_Token_Start('b'),
|
||||
new HTMLPurifier_Token_Text('Whoa! '),
|
||||
new HTMLPurifier_Token_Text('<3 That\'s not good >'),
|
||||
new HTMLPurifier_Token_Text('.>'),
|
||||
new HTMLPurifier_Token_End('b'),
|
||||
);
|
||||
$dom_expect[19] = array(
|
||||
new HTMLPurifier_Token_Start('b'),
|
||||
new HTMLPurifier_Token_Text('Whoa! <3 That\'s not good >.>'),
|
||||
new HTMLPurifier_Token_End('b'),
|
||||
);
|
||||
$sax_expect[19] = false; // SAX drops the < character
|
||||
$config[19] = HTMLPurifier_Config::create(array('Core.AggressivelyFixLt' => true));
|
||||
|
||||
// test comment parsing with funky characters inside
|
||||
$input[20] = '<!-- This >< comment --><br />';
|
||||
$expect[20] = array(
|
||||
new HTMLPurifier_Token_Comment(' This >< comment '),
|
||||
new HTMLPurifier_Token_Empty('br')
|
||||
);
|
||||
$sax_expect[20] = false;
|
||||
$config[20] = HTMLPurifier_Config::create(array('Core.AggressivelyFixLt' => true));
|
||||
|
||||
// test comment parsing of missing end
|
||||
$input[21] = '<!-- This >< comment';
|
||||
$expect[21] = array(
|
||||
new HTMLPurifier_Token_Comment(' This >< comment')
|
||||
);
|
||||
$sax_expect[21] = false;
|
||||
$dom_expect[21] = false;
|
||||
$config[21] = HTMLPurifier_Config::create(array('Core.AggressivelyFixLt' => true));
|
||||
|
||||
// test CDATA tags
|
||||
$input[22] = '<script>alert("<foo>");</script>';
|
||||
$expect[22] = array(
|
||||
new HTMLPurifier_Token_Start('script')
|
||||
,new HTMLPurifier_Token_Text('alert("<foo>");')
|
||||
,new HTMLPurifier_Token_End('script')
|
||||
);
|
||||
$config[22] = HTMLPurifier_Config::create(array('HTML.Trusted' => true));
|
||||
$sax_expect[22] = false;
|
||||
|
||||
// test escaping
|
||||
$input[23] = '<!-- This comment < < & -->';
|
||||
$expect[23] = array(
|
||||
new HTMLPurifier_Token_Comment(' This comment < < & ') );
|
||||
$sax_expect[23] = false; $config[23] =
|
||||
HTMLPurifier_Config::create(array('Core.AggressivelyFixLt' =>
|
||||
true));
|
||||
|
||||
// more DirectLex edge-cases
|
||||
$input[24] = '<a href="><>">';
|
||||
$expect[24] = array(
|
||||
new HTMLPurifier_Token_Start('a', array('href' => '')),
|
||||
new HTMLPurifier_Token_Text('<">')
|
||||
);
|
||||
$sax_expect[24] = false;
|
||||
$dom_expect[24] = array(
|
||||
new HTMLPurifier_Token_Empty('a', array('href' => '><>'))
|
||||
);
|
||||
|
||||
$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], $default_context);
|
||||
$this->assertIdentical($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], $default_context);
|
||||
if (!isset($sax_expect[$i])) {
|
||||
// by default, assert with normal result
|
||||
$this->assertIdentical($expect[$i], $sax_result, 'PEARSax3Test '.$i.': %s');
|
||||
paintIf($sax_result, $expect[$i] != $sax_result);
|
||||
} elseif ($sax_expect[$i] === false) {
|
||||
// assertions were turned off, optionally dump
|
||||
// paintIf($sax_expect, $i == NUMBER);
|
||||
} else {
|
||||
// match with a custom SAX result array
|
||||
$this->assertIdentical($sax_expect[$i], $sax_result, 'PEARSax3Test (custom) '.$i.': %s');
|
||||
paintIf($sax_result, $sax_expect[$i] != $sax_result);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_has_dom) {
|
||||
$dom_result = $this->DOMLex->tokenizeHTML($input[$i], $config[$i], $default_context);
|
||||
// same structure as SAX
|
||||
if (!isset($dom_expect[$i])) {
|
||||
$this->assertIdentical($expect[$i], $dom_result, 'DOMLexTest '.$i.': %s');
|
||||
paintIf($dom_result, $expect[$i] != $dom_result);
|
||||
} elseif ($dom_expect[$i] === false) {
|
||||
// paintIf($dom_result, $i == NUMBER);
|
||||
} else {
|
||||
$this->assertIdentical($dom_expect[$i], $dom_result, 'DOMLexTest (custom) '.$i.': %s');
|
||||
paintIf($dom_result, $dom_expect[$i] != $dom_result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_extractBody_bodyWithAttributes() {
|
||||
$this->assertExtractBody('<html><body bgcolor="#F00"><b>Bold</b></body></html>', '<b>Bold</b>');
|
||||
}
|
||||
|
||||
function test_extractBody_preserveUnclosedBody() {
|
||||
$this->assertExtractBody('<body>asdf'); // not closed, don't accept
|
||||
}
|
||||
|
||||
// HTMLPurifier_Lexer->tokenizeHTML() --------------------------------------
|
||||
|
||||
function assertTokenization($input, $expect, $alt_expect = array()) {
|
||||
$lexers = array();
|
||||
$lexers['DirectLex'] = new HTMLPurifier_Lexer_DirectLex();
|
||||
if ($this->_has_pear) $lexers['PEARSax3'] = new HTMLPurifier_Lexer_PEARSax3();
|
||||
if (version_compare(PHP_VERSION, "5", ">=") && class_exists('DOMDocument')) {
|
||||
$lexers['DOMLex'] = new HTMLPurifier_Lexer_DOMLex();
|
||||
$lexers['PH5P'] = new HTMLPurifier_Lexer_PH5P();
|
||||
}
|
||||
foreach ($lexers as $name => $lexer) {
|
||||
$result = $lexer->tokenizeHTML($input, $this->config, $this->context);
|
||||
if (isset($alt_expect[$name])) {
|
||||
if ($alt_expect[$name] === false) continue;
|
||||
$t_expect = $alt_expect[$name];
|
||||
$this->assertIdentical($result, $alt_expect[$name], "$name: %s");
|
||||
} else {
|
||||
$t_expect = $expect;
|
||||
$this->assertIdentical($result, $expect, "$name: %s");
|
||||
}
|
||||
if ($t_expect != $result) {
|
||||
printTokens($result);
|
||||
//var_dump($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_emptyInput() {
|
||||
$this->assertTokenization('', array());
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_plainText() {
|
||||
$this->assertTokenization(
|
||||
'This is regular text.',
|
||||
array(
|
||||
new HTMLPurifier_Token_Text('This is regular text.')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_textAndTags() {
|
||||
$this->assertTokenization(
|
||||
'This is <b>bold</b> text',
|
||||
array(
|
||||
new HTMLPurifier_Token_Text('This is '),
|
||||
new HTMLPurifier_Token_Start('b', array()),
|
||||
new HTMLPurifier_Token_Text('bold'),
|
||||
new HTMLPurifier_Token_End('b'),
|
||||
new HTMLPurifier_Token_Text(' text'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_normalizeCase() {
|
||||
$this->assertTokenization(
|
||||
'<DIV>Totally rad dude. <b>asdf</b></div>',
|
||||
array(
|
||||
new HTMLPurifier_Token_Start('DIV', array()),
|
||||
new HTMLPurifier_Token_Text('Totally rad dude. '),
|
||||
new HTMLPurifier_Token_Start('b', array()),
|
||||
new HTMLPurifier_Token_Text('asdf'),
|
||||
new HTMLPurifier_Token_End('b'),
|
||||
new HTMLPurifier_Token_End('div'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_notWellFormed() {
|
||||
$this->assertTokenization(
|
||||
'<asdf></asdf><d></d><poOloka><poolasdf><ds></asdf></ASDF>',
|
||||
array(
|
||||
new HTMLPurifier_Token_Start('asdf'),
|
||||
new HTMLPurifier_Token_End('asdf'),
|
||||
new HTMLPurifier_Token_Start('d'),
|
||||
new HTMLPurifier_Token_End('d'),
|
||||
new HTMLPurifier_Token_Start('poOloka'),
|
||||
new HTMLPurifier_Token_Start('poolasdf'),
|
||||
new HTMLPurifier_Token_Start('ds'),
|
||||
new HTMLPurifier_Token_End('asdf'),
|
||||
new HTMLPurifier_Token_End('ASDF'),
|
||||
),
|
||||
array(
|
||||
'DOMLex' => $alt = array(
|
||||
new HTMLPurifier_Token_Empty('asdf'),
|
||||
new HTMLPurifier_Token_Empty('d'),
|
||||
new HTMLPurifier_Token_Start('pooloka'),
|
||||
new HTMLPurifier_Token_Start('poolasdf'),
|
||||
new HTMLPurifier_Token_Empty('ds'),
|
||||
new HTMLPurifier_Token_End('poolasdf'),
|
||||
new HTMLPurifier_Token_End('pooloka'),
|
||||
),
|
||||
'PH5P' => $alt,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_whitespaceInTag() {
|
||||
$this->assertTokenization(
|
||||
'<a'."\t".'href="foobar.php"'."\n".'title="foo!">Link to <b id="asdf">foobar</b></a>',
|
||||
array(
|
||||
new HTMLPurifier_Token_Start('a',array('href'=>'foobar.php','title'=>'foo!')),
|
||||
new HTMLPurifier_Token_Text('Link to '),
|
||||
new HTMLPurifier_Token_Start('b',array('id'=>'asdf')),
|
||||
new HTMLPurifier_Token_Text('foobar'),
|
||||
new HTMLPurifier_Token_End('b'),
|
||||
new HTMLPurifier_Token_End('a'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_emptyTag() {
|
||||
$this->assertTokenization(
|
||||
'<br />',
|
||||
array( new HTMLPurifier_Token_Empty('br') )
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_comment() {
|
||||
$this->assertTokenization(
|
||||
'<!-- Comment -->',
|
||||
array( new HTMLPurifier_Token_Comment(' Comment ') ),
|
||||
array(
|
||||
'PEARSax3' => array( new HTMLPurifier_Token_Comment('-- Comment --') ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_malformedComment() {
|
||||
$this->assertTokenization(
|
||||
'<!-- not so well formed --->',
|
||||
array( new HTMLPurifier_Token_Comment(' not so well formed -') ),
|
||||
array(
|
||||
'PEARSax3' => array( new HTMLPurifier_Token_Comment('-- not so well formed ---') ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_unterminatedTag() {
|
||||
$this->assertTokenization(
|
||||
'<a href=""',
|
||||
array( new HTMLPurifier_Token_Text('<a href=""') ),
|
||||
array(
|
||||
// I like our behavior better, but it's non-standard
|
||||
'DOMLex' => array( new HTMLPurifier_Token_Empty('a', array('href'=>'')) ),
|
||||
'PEARSax3' => array( new HTMLPurifier_Token_Start('a', array('href'=>'')) ),
|
||||
'PH5P' => false, // total barfing, grabs scaffolding too
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_specialEntities() {
|
||||
$this->assertTokenization(
|
||||
'<b>',
|
||||
array(
|
||||
new HTMLPurifier_Token_Text('<b>')
|
||||
),
|
||||
array(
|
||||
// some parsers will separate entities out
|
||||
'PEARSax3' => $split = array(
|
||||
new HTMLPurifier_Token_Text('<'),
|
||||
new HTMLPurifier_Token_Text('b'),
|
||||
new HTMLPurifier_Token_Text('>'),
|
||||
),
|
||||
'PH5P' => $split,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_earlyQuote() {
|
||||
$this->assertTokenization(
|
||||
'<a "=>',
|
||||
array( new HTMLPurifier_Token_Empty('a') ),
|
||||
array(
|
||||
// we barf on this input
|
||||
'DirectLex' => $tokens = array(
|
||||
new HTMLPurifier_Token_Start('a', array('"' => ''))
|
||||
),
|
||||
'PEARSax3' => $tokens,
|
||||
'PH5P' => array(
|
||||
new HTMLPurifier_Token_Empty('a', array('"' => ''))
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_unescapedQuote() {
|
||||
$this->assertTokenization(
|
||||
'"',
|
||||
array( new HTMLPurifier_Token_Text('"') )
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_escapedQuote() {
|
||||
$this->assertTokenization(
|
||||
'"',
|
||||
array( new HTMLPurifier_Token_Text('"') ),
|
||||
array(
|
||||
'PEARSax3' => false, // PEAR barfs on this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_cdata() {
|
||||
$this->assertTokenization(
|
||||
'<![CDATA[You <b>can't</b> get me!]]>',
|
||||
array( new HTMLPurifier_Token_Text('You <b>can't</b> get me!') ),
|
||||
array(
|
||||
// PEAR splits up all of the CDATA
|
||||
'PEARSax3' => $split = array(
|
||||
new HTMLPurifier_Token_Text('You '),
|
||||
new HTMLPurifier_Token_Text('<'),
|
||||
new HTMLPurifier_Token_Text('b'),
|
||||
new HTMLPurifier_Token_Text('>'),
|
||||
new HTMLPurifier_Token_Text('can'),
|
||||
new HTMLPurifier_Token_Text('&'),
|
||||
new HTMLPurifier_Token_Text('#39;t'),
|
||||
new HTMLPurifier_Token_Text('<'),
|
||||
new HTMLPurifier_Token_Text('/b'),
|
||||
new HTMLPurifier_Token_Text('>'),
|
||||
new HTMLPurifier_Token_Text(' get me!'),
|
||||
),
|
||||
'PH5P' => $split,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_characterEntity() {
|
||||
$this->assertTokenization(
|
||||
'θ',
|
||||
array( new HTMLPurifier_Token_Text("\xCE\xB8") )
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_characterEntityInCDATA() {
|
||||
$this->assertTokenization(
|
||||
'<![CDATA[→]]>',
|
||||
array( new HTMLPurifier_Token_Text("→") ),
|
||||
array(
|
||||
'PEARSax3' => $split = array(
|
||||
new HTMLPurifier_Token_Text('&'),
|
||||
new HTMLPurifier_Token_Text('rarr;'),
|
||||
),
|
||||
'PH5P' => $split,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_entityInAttribute() {
|
||||
$this->assertTokenization(
|
||||
'<a href="index.php?title=foo&id=bar">Link</a>',
|
||||
array(
|
||||
new HTMLPurifier_Token_Start('a',array('href' => 'index.php?title=foo&id=bar')),
|
||||
new HTMLPurifier_Token_Text('Link'),
|
||||
new HTMLPurifier_Token_End('a'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_preserveUTF8() {
|
||||
$this->assertTokenization(
|
||||
"\xCE\xB8",
|
||||
array( new HTMLPurifier_Token_Text("\xCE\xB8") )
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_specialEntityInAttribute() {
|
||||
$this->assertTokenization(
|
||||
'<br test="x < 6" />',
|
||||
array( new HTMLPurifier_Token_Empty('br', array('test' => 'x < 6')) )
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_emoticonProtection() {
|
||||
$this->config->set('Core', 'AggressivelyFixLt', true);
|
||||
$this->assertTokenization(
|
||||
'<b>Whoa! <3 That\'s not good >.></b>',
|
||||
array(
|
||||
new HTMLPurifier_Token_Start('b'),
|
||||
new HTMLPurifier_Token_Text('Whoa! '),
|
||||
new HTMLPurifier_Token_Text('<3 That\'s not good >'),
|
||||
new HTMLPurifier_Token_Text('.>'),
|
||||
new HTMLPurifier_Token_End('b')
|
||||
),
|
||||
array(
|
||||
// text is absorbed together
|
||||
'DOMLex' => array(
|
||||
new HTMLPurifier_Token_Start('b'),
|
||||
new HTMLPurifier_Token_Text('Whoa! <3 That\'s not good >.>'),
|
||||
new HTMLPurifier_Token_End('b'),
|
||||
),
|
||||
'PEARSax3' => false, // totally mangled
|
||||
'PH5P' => array( // interesting grouping
|
||||
new HTMLPurifier_Token_Start('b'),
|
||||
new HTMLPurifier_Token_Text('Whoa! '),
|
||||
new HTMLPurifier_Token_Text('<'),
|
||||
new HTMLPurifier_Token_Text('3 That\'s not good >.>'),
|
||||
new HTMLPurifier_Token_End('b'),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_commentWithFunkyChars() {
|
||||
$this->assertTokenization(
|
||||
'<!-- This >< comment --><br />',
|
||||
array(
|
||||
new HTMLPurifier_Token_Comment(' This >< comment '),
|
||||
new HTMLPurifier_Token_Empty('br'),
|
||||
),
|
||||
array(
|
||||
'PEARSax3' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_unterminatedComment() {
|
||||
$this->assertTokenization(
|
||||
'<!-- This >< comment',
|
||||
array( new HTMLPurifier_Token_Comment(' This >< comment') ),
|
||||
array(
|
||||
'DOMLex' => false,
|
||||
'PEARSax3' => false,
|
||||
'PH5P' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_scriptCDATAContents() {
|
||||
$this->config->set('HTML', 'Trusted', true);
|
||||
$this->assertTokenization(
|
||||
'Foo: <script>alert("<foo>");</script>',
|
||||
array(
|
||||
new HTMLPurifier_Token_Text('Foo: '),
|
||||
new HTMLPurifier_Token_Start('script'),
|
||||
new HTMLPurifier_Token_Text('alert("<foo>");'),
|
||||
new HTMLPurifier_Token_End('script'),
|
||||
),
|
||||
array(
|
||||
'PEARSax3' => false,
|
||||
// PH5P, for some reason, bubbles the script to <head>
|
||||
'PH5P' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_entitiesInComment() {
|
||||
$this->config->set('Core', 'AggressivelyFixLt', true);
|
||||
$this->assertTokenization(
|
||||
'<!-- This comment < < & -->',
|
||||
array( new HTMLPurifier_Token_Comment(' This comment < < & ') ),
|
||||
array(
|
||||
'PEARSax3' => false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_attributeWithSpecialCharacters() {
|
||||
$this->assertTokenization(
|
||||
'<a href="><>">',
|
||||
array( new HTMLPurifier_Token_Empty('a', array('href' => '><>')) ),
|
||||
array(
|
||||
'DirectLex' => array(
|
||||
new HTMLPurifier_Token_Start('a', array('href' => '')),
|
||||
new HTMLPurifier_Token_Text('<">'),
|
||||
),
|
||||
'PEARSax3' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_emptyTagWithSlashInAttribute() {
|
||||
$this->assertTokenization(
|
||||
'<param name="src" value="http://example.com/video.wmv" />',
|
||||
array( new HTMLPurifier_Token_Empty('param', array('name' => 'src', 'value' => 'http://example.com/video.wmv')) )
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
function test_tokenizeHTML_() {
|
||||
$this->assertTokenization(
|
||||
,
|
||||
array(
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@ class HTMLPurifier_SimpleTest_Reporter extends HTMLReporter
|
||||
?>><?php echo $file ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<input type="checkbox" name="standalone" title="Standalone version?" <?php if(isset($_GET['standalone'])) {echo 'checked="checked" ';} ?>/>
|
||||
<input type="submit" value="Go">
|
||||
</form>
|
||||
<?php
|
||||
|
@@ -11,26 +11,36 @@ class HTMLPurifier_Strategy_CoreTest extends HTMLPurifier_StrategyHarness
|
||||
$this->obj = new HTMLPurifier_Strategy_Core();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
function testBlankInput() {
|
||||
$this->assertResult('');
|
||||
}
|
||||
|
||||
function testMakeWellFormed() {
|
||||
$this->assertResult(
|
||||
'<b>Make well formed.',
|
||||
'<b>Make well formed.</b>'
|
||||
);
|
||||
}
|
||||
|
||||
function testFixNesting() {
|
||||
$this->assertResult(
|
||||
'<b><div>Fix nesting.</div></b>',
|
||||
'<b></b><div>Fix nesting.</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testRemoveForeignElements() {
|
||||
$this->assertResult(
|
||||
'<asdf>Foreign element removal.</asdf>',
|
||||
'Foreign element removal.'
|
||||
);
|
||||
}
|
||||
|
||||
function testFirstThree() {
|
||||
$this->assertResult(
|
||||
'<foo><b><div>All three.</div></b>',
|
||||
'<b></b><div>All three.</div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,79 +11,81 @@ class HTMLPurifier_Strategy_FixNestingTest extends HTMLPurifier_StrategyHarness
|
||||
$this->obj = new HTMLPurifier_Strategy_FixNesting();
|
||||
}
|
||||
|
||||
function testBlockAndInlineIntegration() {
|
||||
|
||||
// legal inline
|
||||
function testPreserveInlineInRoot() {
|
||||
$this->assertResult('<b>Bold text</b>');
|
||||
|
||||
// legal inline and block (default parent element is FLOW)
|
||||
}
|
||||
|
||||
function testPreserveInlineAndBlockInRoot() {
|
||||
$this->assertResult('<a href="about:blank">Blank</a><div>Block</div>');
|
||||
|
||||
// illegal block in inline
|
||||
}
|
||||
|
||||
function testRemoveBlockInInline() {
|
||||
$this->assertResult(
|
||||
'<b><div>Illegal div.</div></b>',
|
||||
'<b>Illegal div.</b>'
|
||||
);
|
||||
|
||||
// same test with different configuration (fragile)
|
||||
$this->assertResult(
|
||||
'<b><div>Illegal div.</div></b>',
|
||||
'<b><div>Illegal div.</div></b>',
|
||||
array('Core.EscapeInvalidChildren' => true)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testNodeRemovalIntegration() {
|
||||
|
||||
// test of empty set that's required, resulting in removal of node
|
||||
function testEscapeBlockInInline() {
|
||||
$this->config->set('Core', 'EscapeInvalidChildren', true);
|
||||
$this->assertResult(
|
||||
'<b><div>Illegal div.</div></b>',
|
||||
'<b><div>Illegal div.</div></b>'
|
||||
);
|
||||
}
|
||||
|
||||
function testRemoveNodeWithMissingRequiredElements() {
|
||||
$this->assertResult('<ul></ul>', '');
|
||||
|
||||
// test illegal text which gets removed
|
||||
}
|
||||
|
||||
function testRemoveIllegalPCDATA() {
|
||||
$this->assertResult(
|
||||
'<ul>Illegal text<li>Legal item</li></ul>',
|
||||
'<ul><li>Legal item</li></ul>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testTableIntegration() {
|
||||
// test custom table definition
|
||||
$this->assertResult(
|
||||
'<table><tr><td>Cell 1</td></tr></table>'
|
||||
);
|
||||
function testCustomTableDefinition() {
|
||||
$this->assertResult('<table><tr><td>Cell 1</td></tr></table>');
|
||||
}
|
||||
|
||||
function testRemoveEmptyTable() {
|
||||
$this->assertResult('<table></table>', '');
|
||||
}
|
||||
|
||||
function testChameleonIntegration() {
|
||||
|
||||
// block in inline ins not allowed
|
||||
function testChameleonRemoveBlockInNodeInInline() {
|
||||
$this->assertResult(
|
||||
'<span><ins><div>Not allowed!</div></ins></span>',
|
||||
'<span><ins>Not allowed!</ins></span>'
|
||||
);
|
||||
|
||||
// test block element that has inline content
|
||||
}
|
||||
|
||||
function testChameleonRemoveBlockInBlockNodeWithInlineContent() {
|
||||
$this->assertResult(
|
||||
'<h1><ins><div>Not allowed!</div></ins></h1>',
|
||||
'<h1><ins>Not allowed!</ins></h1>'
|
||||
);
|
||||
|
||||
// stacked ins/del
|
||||
}
|
||||
|
||||
function testNestedChameleonRemoveBlockInNodeWithInlineContent() {
|
||||
$this->assertResult(
|
||||
'<h1><ins><del><div>Not allowed!</div></del></ins></h1>',
|
||||
'<h1><ins><del>Not allowed!</del></ins></h1>'
|
||||
);
|
||||
}
|
||||
|
||||
function testNestedChameleonPreserveBlockInBlock() {
|
||||
$this->assertResult(
|
||||
'<div><ins><del><div>Allowed!</div></del></ins></div>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testChameleonEscapeInvalidBlockInInline() {
|
||||
$this->config->set('Core', 'EscapeInvalidChildren', true);
|
||||
$this->assertResult( // alt config
|
||||
'<span><ins><div>Not allowed!</div></ins></span>',
|
||||
'<span><ins><div>Not allowed!</div></ins></span>',
|
||||
array('Core.EscapeInvalidChildren' => true)
|
||||
'<span><ins><div>Not allowed!</div></ins></span>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testExclusionsIntegration() {
|
||||
@@ -93,41 +95,37 @@ class HTMLPurifier_Strategy_FixNestingTest extends HTMLPurifier_StrategyHarness
|
||||
'<a><span></span></a>'
|
||||
);
|
||||
}
|
||||
|
||||
function testCustomParentIntegration() {
|
||||
// test inline parent
|
||||
$this->assertResult(
|
||||
'<b>Bold</b>', true, array('HTML.Parent' => 'span')
|
||||
);
|
||||
$this->assertResult(
|
||||
'<div>Reject</div>', 'Reject', array('HTML.Parent' => 'span')
|
||||
);
|
||||
}
|
||||
|
||||
function testError() {
|
||||
// test fallback to div
|
||||
$this->expectError('Cannot use unrecognized element as parent.');
|
||||
$this->assertResult(
|
||||
'<div>Accept</div>', true, array('HTML.Parent' => 'obviously-impossible')
|
||||
);
|
||||
$this->swallowErrors();
|
||||
|
||||
|
||||
function testPreserveInlineNodeInInlineRootNode() {
|
||||
$this->config->set('HTML', 'Parent', 'span');
|
||||
$this->assertResult('<b>Bold</b>');
|
||||
}
|
||||
|
||||
function testDoubleCheckIntegration() {
|
||||
// breaks without the redundant checking code
|
||||
function testRemoveBlockNodeInInlineRootNode() {
|
||||
$this->config->set('HTML', 'Parent', 'span');
|
||||
$this->assertResult('<div>Reject</div>', 'Reject');
|
||||
}
|
||||
|
||||
function testInvalidParentError() {
|
||||
// test fallback to div
|
||||
$this->config->set('HTML', 'Parent', 'obviously-impossible');
|
||||
$this->expectError('Cannot use unrecognized element as parent');
|
||||
$this->assertResult('<div>Accept</div>');
|
||||
}
|
||||
|
||||
function testCascadingRemovalOfNodesMissingRequiredChildren() {
|
||||
$this->assertResult('<table><tr></tr></table>', '');
|
||||
|
||||
// special case, prevents scrolling one back to find parent
|
||||
}
|
||||
|
||||
function testCascadingRemovalSpecialCaseCannotScrollOneBack() {
|
||||
$this->assertResult('<table><tr></tr><tr></tr></table>', '');
|
||||
|
||||
// cascading rollbacks
|
||||
$this->assertResult(
|
||||
'<table><tbody><tr></tr><tr></tr></tbody><tr></tr><tr></tr></table>',
|
||||
''
|
||||
);
|
||||
|
||||
// rollbacks twice
|
||||
}
|
||||
|
||||
function testLotsOfCascadingRemovalOfNodes() {
|
||||
$this->assertResult('<table><tbody><tr></tr><tr></tr></tbody><tr></tr><tr></tr></table>', '');
|
||||
}
|
||||
|
||||
function testAdjacentRemovalOfNodeMissingRequiredChildren() {
|
||||
$this->assertResult('<table></table><table></table>', '');
|
||||
}
|
||||
|
||||
|
@@ -9,113 +9,77 @@ class HTMLPurifier_Strategy_MakeWellFormedTest extends HTMLPurifier_StrategyHarn
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_MakeWellFormed();
|
||||
$this->config = array();
|
||||
}
|
||||
|
||||
function testNormalIntegration() {
|
||||
function testEmptyInput() {
|
||||
$this->assertResult('');
|
||||
}
|
||||
|
||||
function testWellFormedInput() {
|
||||
$this->assertResult('This is <b>bold text</b>.');
|
||||
}
|
||||
|
||||
function testUnclosedTagIntegration() {
|
||||
function testUnclosedTagTerminatedByDocumentEnd() {
|
||||
$this->assertResult(
|
||||
'<b>Unclosed tag, gasp!',
|
||||
'<b>Unclosed tag, gasp!</b>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testUnclosedTagTerminatedByParentNodeEnd() {
|
||||
$this->assertResult(
|
||||
'<b><i>Bold and italic?</b>',
|
||||
'<b><i>Bold and italic?</i></b>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testRemoveStrayClosingTag() {
|
||||
$this->assertResult(
|
||||
'Unused end tags... recycle!</b>',
|
||||
'Unused end tags... recycle!'
|
||||
);
|
||||
}
|
||||
|
||||
function testEmptyTagDetectionIntegration() {
|
||||
function testConvertStartToEmpty() {
|
||||
$this->assertResult(
|
||||
'<br style="clear:both;">',
|
||||
'<br style="clear:both;" />'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testConvertEmptyToStart() {
|
||||
$this->assertResult(
|
||||
'<div style="clear:both;" />',
|
||||
'<div style="clear:both;"></div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testAutoClose() {
|
||||
// paragraph
|
||||
|
||||
function testAutoCloseParagraph() {
|
||||
$this->assertResult(
|
||||
'<p>Paragraph 1<p>Paragraph 2',
|
||||
'<p>Paragraph 1</p><p>Paragraph 2</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testAutoCloseParagraphInsideDiv() {
|
||||
$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>'
|
||||
);
|
||||
|
||||
// list
|
||||
|
||||
}
|
||||
|
||||
function testAutoCloseListItem() {
|
||||
$this->assertResult(
|
||||
'<ol><li>Item 1<li>Item 2</ol>',
|
||||
'<ol><li>Item 1</li><li>Item 2</li></ol>'
|
||||
);
|
||||
|
||||
// colgroup
|
||||
|
||||
}
|
||||
|
||||
function testAutoCloseColgroup() {
|
||||
$this->assertResult(
|
||||
'<table><colgroup><col /><tr></tr></table>',
|
||||
'<table><colgroup><col /></colgroup><tr></tr></table>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testMultipleInjectors() {
|
||||
|
||||
$this->config = array('AutoFormat.AutoParagraph' => true, 'AutoFormat.Linkify' => true);
|
||||
|
||||
$this->assertResult(
|
||||
'Foobar',
|
||||
'<p>Foobar</p>'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'http://example.com',
|
||||
'<p><a href="http://example.com">http://example.com</a></p>'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'<b>http://example.com</b>',
|
||||
'<p><b><a href="http://example.com">http://example.com</a></b></p>'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'<b>http://example.com',
|
||||
'<p><b><a href="http://example.com">http://example.com</a></b></p>'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'http://example.com
|
||||
|
||||
http://dev.example.com',
|
||||
'<p><a href="http://example.com">http://example.com</a></p><p><a href="http://dev.example.com">http://dev.example.com</a></p>'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'http://example.com <div>http://example.com</div>',
|
||||
'<p><a href="http://example.com">http://example.com</a> </p><div><a href="http://example.com">http://example.com</a></div>'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'This URL http://example.com is what you need',
|
||||
'<p>This URL <a href="http://example.com">http://example.com</a> is what you need</p>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
65
tests/HTMLPurifier/Strategy/MakeWellFormed_InjectorTest.php
Normal file
65
tests/HTMLPurifier/Strategy/MakeWellFormed_InjectorTest.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/StrategyHarness.php';
|
||||
require_once 'HTMLPurifier/Strategy/MakeWellFormed.php';
|
||||
|
||||
class HTMLPurifier_Strategy_MakeWellFormed_InjectorTest extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_MakeWellFormed();
|
||||
$this->config->set('AutoFormat', 'AutoParagraph', true);
|
||||
$this->config->set('AutoFormat', 'Linkify', true);
|
||||
}
|
||||
|
||||
function testOnlyAutoParagraph() {
|
||||
$this->assertResult(
|
||||
'Foobar',
|
||||
'<p>Foobar</p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testParagraphWrappingOnlyLink() {
|
||||
$this->assertResult(
|
||||
'http://example.com',
|
||||
'<p><a href="http://example.com">http://example.com</a></p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testParagraphWrappingNodeContainingLink() {
|
||||
$this->assertResult(
|
||||
'<b>http://example.com</b>',
|
||||
'<p><b><a href="http://example.com">http://example.com</a></b></p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testParagraphWrappingPoorlyFormedNodeContainingLink() {
|
||||
$this->assertResult(
|
||||
'<b>http://example.com',
|
||||
'<p><b><a href="http://example.com">http://example.com</a></b></p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testTwoParagraphsContainingOnlyOneLink() {
|
||||
$this->assertResult(
|
||||
"http://example.com\n\nhttp://dev.example.com",
|
||||
'<p><a href="http://example.com">http://example.com</a></p><p><a href="http://dev.example.com">http://dev.example.com</a></p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testParagraphNextToDivWithLinks() {
|
||||
$this->assertResult(
|
||||
'http://example.com <div>http://example.com</div>',
|
||||
'<p><a href="http://example.com">http://example.com</a> </p><div><a href="http://example.com">http://example.com</a></div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testRealisticLinkInSentence() {
|
||||
$this->assertResult(
|
||||
'This URL http://example.com is what you need',
|
||||
'<p>This URL <a href="http://example.com">http://example.com</a> is what you need</p>'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -3,8 +3,7 @@
|
||||
require_once 'HTMLPurifier/StrategyHarness.php';
|
||||
require_once 'HTMLPurifier/Strategy/RemoveForeignElements.php';
|
||||
|
||||
class HTMLPurifier_Strategy_RemoveForeignElementsTest
|
||||
extends HTMLPurifier_StrategyHarness
|
||||
class HTMLPurifier_Strategy_RemoveForeignElementsTest extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
@@ -12,96 +11,75 @@ class HTMLPurifier_Strategy_RemoveForeignElementsTest
|
||||
$this->obj = new HTMLPurifier_Strategy_RemoveForeignElements();
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
$this->config = array('HTML.Doctype' => 'XHTML 1.0 Strict');
|
||||
|
||||
function testBlankInput() {
|
||||
$this->assertResult('');
|
||||
|
||||
}
|
||||
|
||||
function testPreserveRecognizedElements() {
|
||||
$this->assertResult('This is <b>bold text</b>.');
|
||||
|
||||
}
|
||||
|
||||
function testRemoveForeignElements() {
|
||||
$this->assertResult(
|
||||
'<asdf>Bling</asdf><d href="bang">Bong</d><foobar />',
|
||||
'BlingBong'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testRemoveScriptAndContents() {
|
||||
$this->assertResult(
|
||||
'<script>alert();</script>',
|
||||
''
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testRemoveStyleAndContents() {
|
||||
$this->assertResult(
|
||||
'<style>.foo {blink;}</style>',
|
||||
''
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testRemoveOnlyScriptTagsLegacy() {
|
||||
$this->config->set('Core', 'RemoveScriptContents', false);
|
||||
$this->assertResult(
|
||||
'<script>alert();</script>',
|
||||
'alert();',
|
||||
array('Core.RemoveScriptContents' => false)
|
||||
'alert();'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testRemoveOnlyScriptTags() {
|
||||
$this->config->set('Core', 'HiddenElements', array());
|
||||
$this->assertResult(
|
||||
'<script>alert();</script>',
|
||||
'alert();',
|
||||
array('Core.HiddenElements' => array())
|
||||
'alert();'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'<menu><li>Item 1</li></menu>',
|
||||
'<ul><li>Item 1</li></ul>'
|
||||
);
|
||||
|
||||
// test center transform
|
||||
$this->assertResult(
|
||||
'<center>Look I am Centered!</center>',
|
||||
'<div style="text-align:center;">Look I am Centered!</div>'
|
||||
);
|
||||
|
||||
// test font transform
|
||||
$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>'
|
||||
);
|
||||
|
||||
// test removal of invalid img tag
|
||||
$this->assertResult(
|
||||
'<img />',
|
||||
''
|
||||
);
|
||||
|
||||
// test preservation of valid img tag
|
||||
}
|
||||
|
||||
function testRemoveInvalidImg() {
|
||||
$this->assertResult('<img />', '');
|
||||
}
|
||||
|
||||
function testPreserveValidImg() {
|
||||
$this->assertResult('<img src="foobar.gif" alt="foobar.gif" />');
|
||||
|
||||
// test preservation of invalid img tag when removal is disabled
|
||||
$this->assertResult(
|
||||
'<img />',
|
||||
true,
|
||||
array(
|
||||
'Core.RemoveInvalidImg' => false
|
||||
)
|
||||
);
|
||||
|
||||
// test transform to unallowed element
|
||||
$this->assertResult(
|
||||
'<font color="red" face="Arial" size="6">Big Warning!</font>',
|
||||
'Big Warning!',
|
||||
array('HTML.Allowed' => 'div')
|
||||
);
|
||||
|
||||
// text-ify commented script contents ( the trailing comment gets
|
||||
// removed during generation )
|
||||
}
|
||||
|
||||
function testPreserveInvalidImgWhenRemovalIsDisabled() {
|
||||
$this->config->set('Core', 'RemoveInvalidImg', false);
|
||||
$this->assertResult('<img />');
|
||||
}
|
||||
|
||||
function testTextifyCommentedScriptContents() {
|
||||
$this->config->set('HTML', 'Trusted', true);
|
||||
$this->config->set('Output', 'CommentScriptContents', false); // simplify output
|
||||
$this->assertResult(
|
||||
'<script type="text/javascript"><!--
|
||||
alert(<b>bold</b>);
|
||||
// --></script>',
|
||||
'<script type="text/javascript">
|
||||
alert(<b>bold</b>);
|
||||
// </script>',
|
||||
array('HTML.Trusted' => true, 'Output.CommentScriptContents' => false)
|
||||
// </script>'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/StrategyHarness.php';
|
||||
require_once 'HTMLPurifier/Strategy/RemoveForeignElements.php';
|
||||
|
||||
class HTMLPurifier_Strategy_RemoveForeignElements_TidyTest
|
||||
extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_RemoveForeignElements();
|
||||
$this->config->set('HTML', 'TidyLevel', 'heavy');
|
||||
}
|
||||
|
||||
function testCenterTransform() {
|
||||
$this->assertResult(
|
||||
'<center>Look I am Centered!</center>',
|
||||
'<div style="text-align:center;">Look I am Centered!</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testFontTransform() {
|
||||
$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>'
|
||||
);
|
||||
}
|
||||
|
||||
function testTransformToForbiddenElement() {
|
||||
$this->config->set('HTML', 'Allowed', 'div');
|
||||
$this->assertResult(
|
||||
'<font color="red" face="Arial" size="6">Big Warning!</font>',
|
||||
'Big Warning!'
|
||||
);
|
||||
}
|
||||
|
||||
function testMenuTransform() {
|
||||
$this->assertResult(
|
||||
'<menu><li>Item 1</li></menu>',
|
||||
'<ul><li>Item 1</li></ul>'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once('HTMLPurifier/Config.php');
|
||||
require_once('HTMLPurifier/StrategyHarness.php');
|
||||
require_once('HTMLPurifier/Strategy/ValidateAttributes.php');
|
||||
|
||||
@@ -11,126 +10,99 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_ValidateAttributes();
|
||||
$this->config = array('HTML.Doctype' => 'XHTML 1.0 Strict');
|
||||
}
|
||||
|
||||
function testEmpty() {
|
||||
function testEmptyInput() {
|
||||
$this->assertResult('');
|
||||
}
|
||||
|
||||
function testIDs() {
|
||||
function testRemoveIDByDefault() {
|
||||
$this->assertResult(
|
||||
'<div id="valid">Kill the ID.</div>',
|
||||
'<div>Kill the ID.</div>'
|
||||
);
|
||||
|
||||
$this->assertResult('<div id="valid">Preserve the ID.</div>', true,
|
||||
array('HTML.EnableAttrID' => true));
|
||||
|
||||
$this->assertResult(
|
||||
'<div id="0invalid">Kill the ID.</div>',
|
||||
'<div>Kill the ID.</div>',
|
||||
array('HTML.EnableAttrID' => true)
|
||||
);
|
||||
|
||||
// test id accumulator
|
||||
$this->assertResult(
|
||||
'<div id="valid">Valid</div><div id="valid">Invalid</div>',
|
||||
'<div id="valid">Valid</div><div>Invalid</div>',
|
||||
array('HTML.EnableAttrID' => true)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testRemoveInvalidDir() {
|
||||
$this->assertResult(
|
||||
'<span dir="up-to-down">Bad dir.</span>',
|
||||
'<span>Bad dir.</span>'
|
||||
);
|
||||
|
||||
// test attribute key case sensitivity
|
||||
$this->assertResult(
|
||||
'<div ID="valid">Convert ID to lowercase.</div>',
|
||||
'<div id="valid">Convert ID to lowercase.</div>',
|
||||
array('HTML.EnableAttrID' => true)
|
||||
);
|
||||
|
||||
// test simple attribute substitution
|
||||
$this->assertResult(
|
||||
'<div id=" valid ">Trim whitespace.</div>',
|
||||
'<div id="valid">Trim whitespace.</div>',
|
||||
array('HTML.EnableAttrID' => true)
|
||||
);
|
||||
|
||||
// test configuration id blacklist
|
||||
$this->assertResult(
|
||||
'<div id="invalid">Invalid</div>',
|
||||
'<div>Invalid</div>',
|
||||
array(
|
||||
'Attr.IDBlacklist' => array('invalid'),
|
||||
'HTML.EnableAttrID' => true
|
||||
)
|
||||
);
|
||||
|
||||
// name rewritten as id
|
||||
$this->assertResult(
|
||||
'<a name="foobar" />',
|
||||
'<a id="foobar" />',
|
||||
array('HTML.EnableAttrID' => true)
|
||||
);
|
||||
}
|
||||
|
||||
function testClasses() {
|
||||
function testPreserveValidClass() {
|
||||
$this->assertResult('<div class="valid">Valid</div>');
|
||||
|
||||
}
|
||||
|
||||
function testSelectivelyRemoveInvalidClasses() {
|
||||
$this->assertResult(
|
||||
'<div class="valid 0invalid">Keep valid.</div>',
|
||||
'<div class="valid">Keep valid.</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testTitle() {
|
||||
function testPreserveTitle() {
|
||||
$this->assertResult(
|
||||
'<acronym title="PHP: Hypertext Preprocessor">PHP</acronym>'
|
||||
);
|
||||
}
|
||||
|
||||
function testLang() {
|
||||
function testAddXMLLang() {
|
||||
$this->assertResult(
|
||||
'<span lang="fr">La soupe.</span>',
|
||||
'<span lang="fr" xml:lang="fr">La soupe.</span>'
|
||||
);
|
||||
|
||||
// test only xml:lang for XHTML 1.1
|
||||
}
|
||||
|
||||
function testOnlyXMLLangInXHTML11() {
|
||||
$this->config->set('HTML', 'Doctype', 'XHTML 1.1');
|
||||
$this->assertResult(
|
||||
'<b lang="en">asdf</b>',
|
||||
'<b xml:lang="en">asdf</b>', array('HTML.Doctype' => 'XHTML 1.1')
|
||||
'<b xml:lang="en">asdf</b>'
|
||||
);
|
||||
}
|
||||
|
||||
function testAlign() {
|
||||
|
||||
$this->assertResult(
|
||||
'<h1 align="center">Centered Headline</h1>',
|
||||
'<h1 style="text-align:center;">Centered Headline</h1>'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<h1 align="right">Right-aligned Headline</h1>',
|
||||
'<h1 style="text-align:right;">Right-aligned Headline</h1>'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<h1 align="left">Left-aligned Headline</h1>',
|
||||
'<h1 style="text-align:left;">Left-aligned Headline</h1>'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<p align="justify">Justified Paragraph</p>',
|
||||
'<p style="text-align:justify;">Justified Paragraph</p>'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<h1 align="invalid">Invalid Headline</h1>',
|
||||
'<h1>Invalid Headline</h1>'
|
||||
);
|
||||
|
||||
function testBasicURI() {
|
||||
$this->assertResult('<a href="http://www.google.com/">Google</a>');
|
||||
}
|
||||
|
||||
function testTable() {
|
||||
function testInvalidURI() {
|
||||
$this->assertResult(
|
||||
'<a href="javascript:badstuff();">Google</a>',
|
||||
'<a>Google</a>'
|
||||
);
|
||||
}
|
||||
|
||||
function testBdoAddMissingDir() {
|
||||
$this->assertResult(
|
||||
'<bdo>Go left.</bdo>',
|
||||
'<bdo dir="ltr">Go left.</bdo>'
|
||||
);
|
||||
}
|
||||
|
||||
function testBdoReplaceInvalidDirWithDefault() {
|
||||
$this->assertResult(
|
||||
'<bdo dir="blahblah">Invalid value!</bdo>',
|
||||
'<bdo dir="ltr">Invalid value!</bdo>'
|
||||
);
|
||||
}
|
||||
|
||||
function testBdoAlternateDefaultDir() {
|
||||
$this->config->set('Attr', 'DefaultTextDir', 'rtl');
|
||||
$this->assertResult(
|
||||
'<bdo>Go right.</bdo>',
|
||||
'<bdo dir="rtl">Go right.</bdo>'
|
||||
);
|
||||
}
|
||||
|
||||
function testRemoveDirWhenNotRequired() {
|
||||
$this->assertResult(
|
||||
'<span dir="blahblah">Invalid value!</span>',
|
||||
'<span>Invalid value!</span>'
|
||||
);
|
||||
}
|
||||
|
||||
function testTableAttributes() {
|
||||
$this->assertResult(
|
||||
'<table frame="above" rules="rows" summary="A test table" border="2" cellpadding="5%" cellspacing="3" width="100%">
|
||||
<col align="right" width="4*" />
|
||||
@@ -148,293 +120,64 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends
|
||||
</tr>
|
||||
</table>'
|
||||
);
|
||||
|
||||
// test col.span is non-zero
|
||||
}
|
||||
|
||||
function testColSpanIsNonZero() {
|
||||
$this->assertResult(
|
||||
'<col span="0" />',
|
||||
'<col />'
|
||||
);
|
||||
// lengths
|
||||
$this->assertResult(
|
||||
'<td width="5%" height="10" /><th width="10" height="5%" /><hr width="10" height="10" />',
|
||||
'<td style="width:5%;height:10px;" /><th style="width:10px;height:5%;" /><hr style="width:10px;" />'
|
||||
);
|
||||
// td boolean transformation
|
||||
$this->assertResult(
|
||||
'<td nowrap />',
|
||||
'<td style="white-space:nowrap;" />'
|
||||
);
|
||||
|
||||
// caption align transformation
|
||||
$this->assertResult(
|
||||
'<caption align="left" />',
|
||||
'<caption style="text-align:left;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<caption align="right" />',
|
||||
'<caption style="text-align:right;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<caption align="top" />',
|
||||
'<caption style="caption-side:top;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<caption align="bottom" />',
|
||||
'<caption style="caption-side:bottom;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<caption align="nonsense" />',
|
||||
'<caption />'
|
||||
);
|
||||
|
||||
// align transformation
|
||||
$this->assertResult(
|
||||
'<table align="left" />',
|
||||
'<table style="float:left;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<table align="center" />',
|
||||
'<table style="margin-left:auto;margin-right:auto;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<table align="right" />',
|
||||
'<table style="float:right;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<table align="top" />',
|
||||
'<table />'
|
||||
);
|
||||
}
|
||||
|
||||
function testURI() {
|
||||
$this->assertResult('<a href="http://www.google.com/">Google</a>');
|
||||
|
||||
// test invalid URI
|
||||
$this->assertResult(
|
||||
'<a href="javascript:badstuff();">Google</a>',
|
||||
'<a>Google</a>'
|
||||
);
|
||||
}
|
||||
|
||||
function testImg() {
|
||||
function testImgAddDefaults() {
|
||||
$this->config->set('Core', 'RemoveInvalidImg', false);
|
||||
$this->assertResult(
|
||||
'<img />',
|
||||
'<img src="" alt="Invalid image" />',
|
||||
array('Core.RemoveInvalidImg' => false)
|
||||
'<img src="" alt="Invalid image" />'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testImgGenerateAlt() {
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" />',
|
||||
'<img src="foobar.jpg" alt="foobar.jpg" />'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testImgAddDefaultSrc() {
|
||||
$this->config->set('Core', 'RemoveInvalidImg', false);
|
||||
$this->assertResult(
|
||||
'<img alt="pretty picture" />',
|
||||
'<img alt="pretty picture" src="" />',
|
||||
array('Core.RemoveInvalidImg' => false)
|
||||
'<img alt="pretty picture" src="" />'
|
||||
);
|
||||
// mailto in image is not allowed
|
||||
}
|
||||
|
||||
function testImgRemoveNonRetrievableProtocol() {
|
||||
$this->config->set('Core', 'RemoveInvalidImg', false);
|
||||
$this->assertResult(
|
||||
'<img src="mailto:foo@example.com" />',
|
||||
'<img alt="mailto:foo@example.com" src="" />',
|
||||
array('Core.RemoveInvalidImg' => false)
|
||||
);
|
||||
// align transformation
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="left" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="float:left;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="right" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="float:right;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="bottom" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="vertical-align:baseline;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="middle" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="vertical-align:middle;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="top" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="vertical-align:top;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="outerspace" />',
|
||||
'<img src="foobar.jpg" alt="foobar" />'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function testBdo() {
|
||||
// test required attributes for bdo
|
||||
$this->assertResult(
|
||||
'<bdo>Go left.</bdo>',
|
||||
'<bdo dir="ltr">Go left.</bdo>'
|
||||
);
|
||||
|
||||
$this->assertResult(
|
||||
'<bdo dir="blahblah">Invalid value!</bdo>',
|
||||
'<bdo dir="ltr">Invalid value!</bdo>'
|
||||
'<img alt="mailto:foo@example.com" src="" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testDir() {
|
||||
// see testBdo, behavior is subtly different
|
||||
$this->assertResult(
|
||||
'<span dir="blahblah">Invalid value!</span>',
|
||||
'<span>Invalid value!</span>'
|
||||
);
|
||||
function testPreserveRel() {
|
||||
$this->config->set('Attr', 'AllowedRel', 'nofollow');
|
||||
$this->assertResult('<a href="foo" rel="nofollow" />');
|
||||
}
|
||||
|
||||
function testLinks() {
|
||||
// link types
|
||||
$this->assertResult(
|
||||
'<a href="foo" rel="nofollow" />',
|
||||
true,
|
||||
array('Attr.AllowedRel' => 'nofollow')
|
||||
);
|
||||
// link targets
|
||||
$this->assertResult(
|
||||
'<a href="foo" target="_top" />',
|
||||
true,
|
||||
array('Attr.AllowedFrameTargets' => '_top',
|
||||
'HTML.Doctype' => 'XHTML 1.0 Transitional')
|
||||
);
|
||||
|
||||
function testPreserveTarget() {
|
||||
$this->config->set('Attr', 'AllowedFrameTargets', '_top');
|
||||
$this->config->set('HTML', 'Doctype', 'XHTML 1.0 Transitional');
|
||||
$this->assertResult('<a href="foo" target="_top" />');
|
||||
}
|
||||
|
||||
function testRemoveTargetWhenNotSupported() {
|
||||
$this->config->set('HTML', 'Doctype', 'XHTML 1.0 Strict');
|
||||
$this->config->set('Attr', 'AllowedFrameTargets', '_top');
|
||||
$this->assertResult(
|
||||
'<a href="foo" target="_top" />',
|
||||
'<a href="foo" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<a href="foo" target="_top" />',
|
||||
'<a href="foo" />',
|
||||
array('Attr.AllowedFrameTargets' => '_top', 'HTML.Strict' => true)
|
||||
);
|
||||
}
|
||||
|
||||
function testBorder() {
|
||||
// border
|
||||
$this->assertResult(
|
||||
'<img src="foo" alt="foo" hspace="1" vspace="3" />',
|
||||
'<img src="foo" alt="foo" style="margin-top:3px;margin-bottom:3px;margin-left:1px;margin-right:1px;" />',
|
||||
array('Attr.AllowedRel' => 'nofollow')
|
||||
);
|
||||
}
|
||||
|
||||
function testHr() {
|
||||
$this->assertResult(
|
||||
'<hr size="3" />',
|
||||
'<hr style="height:3px;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<hr noshade />',
|
||||
'<hr style="color:#808080;background-color:#808080;border:0;" />'
|
||||
);
|
||||
// align transformation
|
||||
$this->assertResult(
|
||||
'<hr align="left" />',
|
||||
'<hr style="margin-left:0;margin-right:auto;text-align:left;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<hr align="center" />',
|
||||
'<hr style="margin-left:auto;margin-right:auto;text-align:center;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<hr align="right" />',
|
||||
'<hr style="margin-left:auto;margin-right:0;text-align:right;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<hr align="bottom" />',
|
||||
'<hr />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBr() {
|
||||
// br clear transformation
|
||||
$this->assertResult(
|
||||
'<br clear="left" />',
|
||||
'<br style="clear:left;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<br clear="right" />',
|
||||
'<br style="clear:right;" />'
|
||||
);
|
||||
$this->assertResult( // test both?
|
||||
'<br clear="all" />',
|
||||
'<br style="clear:both;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<br clear="none" />',
|
||||
'<br style="clear:none;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<br clear="foo" />',
|
||||
'<br />'
|
||||
);
|
||||
}
|
||||
|
||||
function testListTypeTransform() {
|
||||
// ul
|
||||
$this->assertResult(
|
||||
'<ul type="disc" />',
|
||||
'<ul style="list-style-type:disc;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ul type="square" />',
|
||||
'<ul style="list-style-type:square;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ul type="circle" />',
|
||||
'<ul style="list-style-type:circle;" />'
|
||||
);
|
||||
$this->assertResult( // case insensitive
|
||||
'<ul type="CIRCLE" />',
|
||||
'<ul style="list-style-type:circle;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ul type="a" />',
|
||||
'<ul />'
|
||||
);
|
||||
// ol
|
||||
$this->assertResult(
|
||||
'<ol type="1" />',
|
||||
'<ol style="list-style-type:decimal;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ol type="i" />',
|
||||
'<ol style="list-style-type:lower-roman;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ol type="I" />',
|
||||
'<ol style="list-style-type:upper-roman;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ol type="a" />',
|
||||
'<ol style="list-style-type:lower-alpha;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ol type="A" />',
|
||||
'<ol style="list-style-type:upper-alpha;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<ol type="disc" />',
|
||||
'<ol />'
|
||||
);
|
||||
// li
|
||||
$this->assertResult(
|
||||
'<li type="circle" />',
|
||||
'<li style="list-style-type:circle;" />'
|
||||
);
|
||||
$this->assertResult(
|
||||
'<li type="A" />',
|
||||
'<li style="list-style-type:upper-alpha;" />'
|
||||
);
|
||||
$this->assertResult( // case sensitive
|
||||
'<li type="CIRCLE" />',
|
||||
'<li />'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
65
tests/HTMLPurifier/Strategy/ValidateAttributes_IDTest.php
Normal file
65
tests/HTMLPurifier/Strategy/ValidateAttributes_IDTest.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
require_once('HTMLPurifier/StrategyHarness.php');
|
||||
require_once('HTMLPurifier/Strategy/ValidateAttributes.php');
|
||||
|
||||
class HTMLPurifier_Strategy_ValidateAttributes_IDTest extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_ValidateAttributes();
|
||||
$this->config->set('HTML', 'EnableAttrID', true);
|
||||
}
|
||||
|
||||
|
||||
function testPreserveIDWhenEnabled() {
|
||||
$this->assertResult('<div id="valid">Preserve the ID.</div>');
|
||||
}
|
||||
|
||||
function testRemoveInvalidID() {
|
||||
$this->assertResult(
|
||||
'<div id="0invalid">Kill the ID.</div>',
|
||||
'<div>Kill the ID.</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testRemoveDuplicateID() {
|
||||
$this->assertResult(
|
||||
'<div id="valid">Valid</div><div id="valid">Invalid</div>',
|
||||
'<div id="valid">Valid</div><div>Invalid</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testAttributeKeyCaseInsensitivity() {
|
||||
$this->assertResult(
|
||||
'<div ID="valid">Convert ID to lowercase.</div>',
|
||||
'<div id="valid">Convert ID to lowercase.</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testTrimWhitespace() {
|
||||
$this->assertResult(
|
||||
'<div id=" valid ">Trim whitespace.</div>',
|
||||
'<div id="valid">Trim whitespace.</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testIDBlacklist() {
|
||||
$this->config->set('Attr', 'IDBlacklist', array('invalid'));
|
||||
$this->assertResult(
|
||||
'<div id="invalid">Invalid</div>',
|
||||
'<div>Invalid</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function testNameConvertedToID() {
|
||||
$this->config->set('HTML', 'TidyLevel', 'heavy');
|
||||
$this->assertResult(
|
||||
'<a name="foobar" />',
|
||||
'<a id="foobar" />'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
353
tests/HTMLPurifier/Strategy/ValidateAttributes_TidyTest.php
Normal file
353
tests/HTMLPurifier/Strategy/ValidateAttributes_TidyTest.php
Normal file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
|
||||
require_once('HTMLPurifier/StrategyHarness.php');
|
||||
require_once('HTMLPurifier/Strategy/ValidateAttributes.php');
|
||||
|
||||
class HTMLPurifier_Strategy_ValidateAttributes_TidyTest extends HTMLPurifier_StrategyHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->obj = new HTMLPurifier_Strategy_ValidateAttributes();
|
||||
$this->config->set('HTML', 'TidyLevel', 'heavy');
|
||||
}
|
||||
|
||||
function testConvertCenterAlign() {
|
||||
$this->assertResult(
|
||||
'<h1 align="center">Centered Headline</h1>',
|
||||
'<h1 style="text-align:center;">Centered Headline</h1>'
|
||||
);
|
||||
}
|
||||
|
||||
function testConvertRightAlign() {
|
||||
$this->assertResult(
|
||||
'<h1 align="right">Right-aligned Headline</h1>',
|
||||
'<h1 style="text-align:right;">Right-aligned Headline</h1>'
|
||||
);
|
||||
}
|
||||
|
||||
function testConvertLeftAlign() {
|
||||
$this->assertResult(
|
||||
'<h1 align="left">Left-aligned Headline</h1>',
|
||||
'<h1 style="text-align:left;">Left-aligned Headline</h1>'
|
||||
);
|
||||
}
|
||||
|
||||
function testConvertJustifyAlign() {
|
||||
$this->assertResult(
|
||||
'<p align="justify">Justified Paragraph</p>',
|
||||
'<p style="text-align:justify;">Justified Paragraph</p>'
|
||||
);
|
||||
}
|
||||
|
||||
function testRemoveInvalidAlign() {
|
||||
$this->assertResult(
|
||||
'<h1 align="invalid">Invalid Headline</h1>',
|
||||
'<h1>Invalid Headline</h1>'
|
||||
);
|
||||
}
|
||||
|
||||
function testConvertTableLengths() {
|
||||
$this->assertResult(
|
||||
'<td width="5%" height="10" /><th width="10" height="5%" /><hr width="10" height="10" />',
|
||||
'<td style="width:5%;height:10px;" /><th style="width:10px;height:5%;" /><hr style="width:10px;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testTdConvertNowrap() {
|
||||
$this->assertResult(
|
||||
'<td nowrap />',
|
||||
'<td style="white-space:nowrap;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testCaptionConvertAlignLeft() {
|
||||
$this->assertResult(
|
||||
'<caption align="left" />',
|
||||
'<caption style="text-align:left;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testCaptionConvertAlignRight() {
|
||||
$this->assertResult(
|
||||
'<caption align="right" />',
|
||||
'<caption style="text-align:right;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testCaptionConvertAlignTop() {
|
||||
$this->assertResult(
|
||||
'<caption align="top" />',
|
||||
'<caption style="caption-side:top;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testCaptionConvertAlignBottom() {
|
||||
$this->assertResult(
|
||||
'<caption align="bottom" />',
|
||||
'<caption style="caption-side:bottom;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testCaptionRemoveInvalidAlign() {
|
||||
$this->assertResult(
|
||||
'<caption align="nonsense" />',
|
||||
'<caption />'
|
||||
);
|
||||
}
|
||||
|
||||
function testTableConvertAlignLeft() {
|
||||
$this->assertResult(
|
||||
'<table align="left" />',
|
||||
'<table style="float:left;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testTableConvertAlignCenter() {
|
||||
$this->assertResult(
|
||||
'<table align="center" />',
|
||||
'<table style="margin-left:auto;margin-right:auto;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testTableConvertAlignRight() {
|
||||
$this->assertResult(
|
||||
'<table align="right" />',
|
||||
'<table style="float:right;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testTableRemoveInvalidAlign() {
|
||||
$this->assertResult(
|
||||
'<table align="top" />',
|
||||
'<table />'
|
||||
);
|
||||
}
|
||||
|
||||
function testImgConvertAlignLeft() {
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="left" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="float:left;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testImgConvertAlignRight() {
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="right" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="float:right;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testImgConvertAlignBottom() {
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="bottom" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="vertical-align:baseline;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testImgConvertAlignMiddle() {
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="middle" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="vertical-align:middle;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testImgConvertAlignTop() {
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="top" />',
|
||||
'<img src="foobar.jpg" alt="foobar" style="vertical-align:top;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testImgRemoveInvalidAlign() {
|
||||
$this->assertResult(
|
||||
'<img src="foobar.jpg" alt="foobar" align="outerspace" />',
|
||||
'<img src="foobar.jpg" alt="foobar" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBorderConvertHVSpace() {
|
||||
$this->assertResult(
|
||||
'<img src="foo" alt="foo" hspace="1" vspace="3" />',
|
||||
'<img src="foo" alt="foo" style="margin-top:3px;margin-bottom:3px;margin-left:1px;margin-right:1px;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testHrConvertSize() {
|
||||
$this->assertResult(
|
||||
'<hr size="3" />',
|
||||
'<hr style="height:3px;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testHrConvertNoshade() {
|
||||
$this->assertResult(
|
||||
'<hr noshade />',
|
||||
'<hr style="color:#808080;background-color:#808080;border:0;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testHrConvertAlignLeft() {
|
||||
$this->assertResult(
|
||||
'<hr align="left" />',
|
||||
'<hr style="margin-left:0;margin-right:auto;text-align:left;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testHrConvertAlignCenter() {
|
||||
$this->assertResult(
|
||||
'<hr align="center" />',
|
||||
'<hr style="margin-left:auto;margin-right:auto;text-align:center;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testHrConvertAlignRight() {
|
||||
$this->assertResult(
|
||||
'<hr align="right" />',
|
||||
'<hr style="margin-left:auto;margin-right:0;text-align:right;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testHrRemoveInvalidAlign() {
|
||||
$this->assertResult(
|
||||
'<hr align="bottom" />',
|
||||
'<hr />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBrConvertClearLeft() {
|
||||
$this->assertResult(
|
||||
'<br clear="left" />',
|
||||
'<br style="clear:left;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBrConvertClearRight() {
|
||||
$this->assertResult(
|
||||
'<br clear="right" />',
|
||||
'<br style="clear:right;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBrConvertClearAll() {
|
||||
$this->assertResult(
|
||||
'<br clear="all" />',
|
||||
'<br style="clear:both;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBrConvertClearNone() {
|
||||
$this->assertResult(
|
||||
'<br clear="none" />',
|
||||
'<br style="clear:none;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBrRemoveInvalidClear() {
|
||||
$this->assertResult(
|
||||
'<br clear="foo" />',
|
||||
'<br />'
|
||||
);
|
||||
}
|
||||
|
||||
function testUlConvertTypeDisc() {
|
||||
$this->assertResult(
|
||||
'<ul type="disc" />',
|
||||
'<ul style="list-style-type:disc;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testUlConvertTypeSquare() {
|
||||
$this->assertResult(
|
||||
'<ul type="square" />',
|
||||
'<ul style="list-style-type:square;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testUlConvertTypeCircle() {
|
||||
$this->assertResult(
|
||||
'<ul type="circle" />',
|
||||
'<ul style="list-style-type:circle;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testUlConvertTypeCaseInsensitive() {
|
||||
$this->assertResult(
|
||||
'<ul type="CIRCLE" />',
|
||||
'<ul style="list-style-type:circle;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testUlRemoveInvalidType() {
|
||||
$this->assertResult(
|
||||
'<ul type="a" />',
|
||||
'<ul />'
|
||||
);
|
||||
}
|
||||
|
||||
function testOlConvertType1() {
|
||||
$this->assertResult(
|
||||
'<ol type="1" />',
|
||||
'<ol style="list-style-type:decimal;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testOlConvertTypeLowerI() {
|
||||
$this->assertResult(
|
||||
'<ol type="i" />',
|
||||
'<ol style="list-style-type:lower-roman;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testOlConvertTypeUpperI() {
|
||||
$this->assertResult(
|
||||
'<ol type="I" />',
|
||||
'<ol style="list-style-type:upper-roman;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testOlConvertTypeLowerA() {
|
||||
$this->assertResult(
|
||||
'<ol type="a" />',
|
||||
'<ol style="list-style-type:lower-alpha;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testOlConvertTypeUpperA() {
|
||||
$this->assertResult(
|
||||
'<ol type="A" />',
|
||||
'<ol style="list-style-type:upper-alpha;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testOlRemoveInvalidType() {
|
||||
$this->assertResult(
|
||||
'<ol type="disc" />',
|
||||
'<ol />'
|
||||
);
|
||||
}
|
||||
|
||||
function testLiConvertTypeCircle() {
|
||||
$this->assertResult(
|
||||
'<li type="circle" />',
|
||||
'<li style="list-style-type:circle;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testLiConvertTypeA() {
|
||||
$this->assertResult(
|
||||
'<li type="A" />',
|
||||
'<li style="list-style-type:upper-alpha;" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testLiConvertTypeCaseSensitive() {
|
||||
$this->assertResult(
|
||||
'<li type="CIRCLE" />',
|
||||
'<li />'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user