diff --git a/NEWS b/NEWS
index fa2a65c3..655f76c1 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,9 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
! HTMLPurifier_Config::inherit($config) allows you to inherit one
configuration, and have changes to that configuration be propagated
to all of its children.
+! Implement %HTML.Attr.Name.UseCDATA, which relaxes validation rules on
+ the name attribute when set. Use with care. Thanks Ian Cook for
+ sponsoring.
3.3.0, released 2009-02-16
! Implement CSS property 'overflow' when %CSS.AllowTricky is true.
diff --git a/library/HTMLPurifier/AttrTransform/Name.php b/library/HTMLPurifier/AttrTransform/Name.php
index e6f93aee..15315bc7 100644
--- a/library/HTMLPurifier/AttrTransform/Name.php
+++ b/library/HTMLPurifier/AttrTransform/Name.php
@@ -7,6 +7,8 @@ class HTMLPurifier_AttrTransform_Name extends HTMLPurifier_AttrTransform
{
public function transform($attr, $config, $context) {
+ // Abort early if we're using relaxed definition of name
+ if ($config->get('HTML.Attr.Name.UseCDATA')) return $attr;
if (!isset($attr['name'])) return $attr;
$id = $this->confiscateAttr($attr, 'name');
if ( isset($attr['id'])) return $attr;
diff --git a/library/HTMLPurifier/ConfigSchema/schema.ser b/library/HTMLPurifier/ConfigSchema/schema.ser
index bd8f5013..b8e5f347 100644
Binary files a/library/HTMLPurifier/ConfigSchema/schema.ser and b/library/HTMLPurifier/ConfigSchema/schema.ser differ
diff --git a/library/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt b/library/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt
new file mode 100644
index 00000000..151fb7b8
--- /dev/null
+++ b/library/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt
@@ -0,0 +1,11 @@
+HTML.Attr.Name.UseCDATA
+TYPE: bool
+DEFAULT: false
+VERSION: 4.0.0
+--DESCRIPTION--
+The W3C specification DTD defines the name attribute to be CDATA, not ID, due
+to limitations of DTD. In certain documents, this relaxed behavior is desired,
+whether it is to specify duplicate names, or to specify names that would be
+illegal IDs (for example, names that begin with a digit.) Set this configuration
+directive to true to use the relaxed parsing rules.
+--# vim: et sw=4 sts=4
diff --git a/library/HTMLPurifier/HTMLModule/Name.php b/library/HTMLPurifier/HTMLModule/Name.php
index af2b1195..05694b45 100644
--- a/library/HTMLPurifier/HTMLModule/Name.php
+++ b/library/HTMLPurifier/HTMLModule/Name.php
@@ -10,7 +10,9 @@ class HTMLPurifier_HTMLModule_Name extends HTMLPurifier_HTMLModule
foreach ($elements as $name) {
$element = $this->addBlankElement($name);
$element->attr['name'] = 'CDATA';
- $element->attr_transform_post['NameSync'] = new HTMLPurifier_AttrTransform_NameSync();
+ if (!$config->get('HTML.Attr.Name.UseCDATA')) {
+ $element->attr_transform_post['NameSync'] = new HTMLPurifier_AttrTransform_NameSync();
+ }
}
}
diff --git a/tests/HTMLPurifier/HTMLModule/NameTest.php b/tests/HTMLPurifier/HTMLModule/NameTest.php
new file mode 100644
index 00000000..55180b2e
--- /dev/null
+++ b/tests/HTMLPurifier/HTMLModule/NameTest.php
@@ -0,0 +1,30 @@
+config->set('Attr.EnableID', true);
+ $this->assertResult(
+ 'bar'
+ );
+ }
+
+ function testCDATA() {
+ $this->config->set('HTML.Attr.Name.UseCDATA', true);
+ $this->assertResult(
+ 'BazBar'
+ );
+ }
+
+ function testCDATAWithHeavyTidy() {
+ $this->config->set('HTML.Attr.Name.UseCDATA', true);
+ $this->config->set('HTML.TidyLevel', 'heavy');
+ $this->assertResult('Baz');
+ }
+
+}