From fcbf724e6e8824c9a1ce40baf469446eefb70be0 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sat, 21 Feb 2009 02:58:30 -0500 Subject: [PATCH] Make name="" and id="" play nicely together. Signed-off-by: Edward Z. Yang --- NEWS | 2 +- TODO | 1 - library/HTMLPurifier.includes.php | 1 + library/HTMLPurifier.safe-includes.php | 1 + library/HTMLPurifier/AttrTransform/NameSync.php | 27 +++++++++++++++ library/HTMLPurifier/HTMLModule/Name.php | 3 +- tests/HTMLPurifier/AttrTransform/NameSyncTest.php | 40 +++++++++++++++++++++++ tests/HTMLPurifier/ComplexHarness.php | 2 +- tests/HTMLPurifier/HTMLT/id-name-mix.htmlt | 11 +++++++ 9 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 library/HTMLPurifier/AttrTransform/NameSync.php create mode 100644 tests/HTMLPurifier/AttrTransform/NameSyncTest.php create mode 100644 tests/HTMLPurifier/HTMLT/id-name-mix.htmlt diff --git a/NEWS b/NEWS index dc4d50b8..97371fdb 100644 --- a/NEWS +++ b/NEWS @@ -10,7 +10,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier ========================== 4.0.0, unknown release date -(no items yet) +! More robust support for name="" and id="" 3.3.0, released 2009-02-16 ! Implement CSS property 'overflow' when %CSS.AllowTricky is true. diff --git a/TODO b/TODO index 9c5a71d7..770b46d0 100644 --- a/TODO +++ b/TODO @@ -14,7 +14,6 @@ afraid to cast your vote for the next feature to be implemented! - Investigate how early internal structures can be accessed; this would prevent structures from being parsed and serialized multiple times. - Built-in support for target="_blank" on all external links -- Allow - Convert configuration to allow an arbitrary number of namespaces; then rename as appropriate. diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index 944f0893..5ee92d80 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -123,6 +123,7 @@ require 'HTMLPurifier/AttrTransform/Input.php'; require 'HTMLPurifier/AttrTransform/Lang.php'; require 'HTMLPurifier/AttrTransform/Length.php'; require 'HTMLPurifier/AttrTransform/Name.php'; +require 'HTMLPurifier/AttrTransform/NameSync.php'; require 'HTMLPurifier/AttrTransform/SafeEmbed.php'; require 'HTMLPurifier/AttrTransform/SafeObject.php'; require 'HTMLPurifier/AttrTransform/SafeParam.php'; diff --git a/library/HTMLPurifier.safe-includes.php b/library/HTMLPurifier.safe-includes.php index 7d393036..052ddcc3 100644 --- a/library/HTMLPurifier.safe-includes.php +++ b/library/HTMLPurifier.safe-includes.php @@ -117,6 +117,7 @@ require_once $__dir . '/HTMLPurifier/AttrTransform/Input.php'; require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php'; require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php'; require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php'; +require_once $__dir . '/HTMLPurifier/AttrTransform/NameSync.php'; require_once $__dir . '/HTMLPurifier/AttrTransform/SafeEmbed.php'; require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php'; require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php'; diff --git a/library/HTMLPurifier/AttrTransform/NameSync.php b/library/HTMLPurifier/AttrTransform/NameSync.php new file mode 100644 index 00000000..a95638c1 --- /dev/null +++ b/library/HTMLPurifier/AttrTransform/NameSync.php @@ -0,0 +1,27 @@ +idDef = new HTMLPurifier_AttrDef_HTML_ID(); + } + + public function transform($attr, $config, $context) { + if (!isset($attr['name'])) return $attr; + $name = $attr['name']; + if (isset($attr['id']) && $attr['id'] === $name) return $attr; + $result = $this->idDef->validate($name, $config, $context); + if ($result === false) unset($attr['name']); + else $attr['name'] = $result; + return $attr; + } + +} + +// vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/HTMLModule/Name.php b/library/HTMLPurifier/HTMLModule/Name.php index d908a0ad..af2b1195 100644 --- a/library/HTMLPurifier/HTMLModule/Name.php +++ b/library/HTMLPurifier/HTMLModule/Name.php @@ -9,7 +9,8 @@ class HTMLPurifier_HTMLModule_Name extends HTMLPurifier_HTMLModule $elements = array('a', 'applet', 'form', 'frame', 'iframe', 'img', 'map'); foreach ($elements as $name) { $element = $this->addBlankElement($name); - $element->attr['name'] = 'ID'; + $element->attr['name'] = 'CDATA'; + $element->attr_transform_post['NameSync'] = new HTMLPurifier_AttrTransform_NameSync(); } } diff --git a/tests/HTMLPurifier/AttrTransform/NameSyncTest.php b/tests/HTMLPurifier/AttrTransform/NameSyncTest.php new file mode 100644 index 00000000..1f673010 --- /dev/null +++ b/tests/HTMLPurifier/AttrTransform/NameSyncTest.php @@ -0,0 +1,40 @@ +obj = new HTMLPurifier_AttrTransform_NameSync(); + $this->accumulator = new HTMLPurifier_IDAccumulator(); + $this->context->register('IDAccumulator', $this->accumulator); + $this->config->set('Attr', 'EnableID', true); + } + + function testEmpty() { + $this->assertResult( array() ); + } + + function testAllowSame() { + $this->assertResult( + array('name' => 'free', 'id' => 'free') + ); + } + + function testAllowDifferent() { + $this->assertResult( + array('name' => 'tryit', 'id' => 'thisgood') + ); + } + + function testCheckName() { + $this->accumulator->add('notok'); + $this->assertResult( + array('name' => 'notok', 'id' => 'ok'), + array('id' => 'ok') + ); + } + +} + +// vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/ComplexHarness.php b/tests/HTMLPurifier/ComplexHarness.php index 76d04152..8e806c63 100644 --- a/tests/HTMLPurifier/ComplexHarness.php +++ b/tests/HTMLPurifier/ComplexHarness.php @@ -81,7 +81,7 @@ class HTMLPurifier_ComplexHarness extends HTMLPurifier_Harness $this->assertIdentical($expect, $result); if ($expect !== $result) { - echo '
' . htmlspecialchars($result) . '
'; + echo '
' . var_dump($result) . '
'; } } diff --git a/tests/HTMLPurifier/HTMLT/id-name-mix.htmlt b/tests/HTMLPurifier/HTMLT/id-name-mix.htmlt new file mode 100644 index 00000000..a48da8e6 --- /dev/null +++ b/tests/HTMLPurifier/HTMLT/id-name-mix.htmlt @@ -0,0 +1,11 @@ +--INI-- +Attr.EnableID = true +--HTML-- +
Test +Test2 +Test3 +--EXPECT-- +Test +Test2 +Test3 +--# vim: et sw=4 sts=4 -- 2.11.4.GIT