diff --git a/library/HTMLPurifier/AttrDef/Enum.php b/library/HTMLPurifier/AttrDef/Enum.php index 94e24603..c199a057 100644 --- a/library/HTMLPurifier/AttrDef/Enum.php +++ b/library/HTMLPurifier/AttrDef/Enum.php @@ -14,11 +14,16 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef $this->case_sensitive = $case_sensitive; } - function validate($string) { + function validate($raw_string) { + $string = trim($raw_string); if (!$this->case_sensitive) { $string = ctype_lower($string) ? $string : strtolower($string); } - return isset($this->valid_values[$string]); + $result = isset($this->valid_values[$string]); + + // if strings equal, return result, otherwise, return + // the new string on a good result and false on a bad one + return ($string == $raw_string) ? $result : $result ? $string : false; } } diff --git a/library/HTMLPurifier/AttrDef/ID.php b/library/HTMLPurifier/AttrDef/ID.php index bc3015f6..6141bf77 100644 --- a/library/HTMLPurifier/AttrDef/ID.php +++ b/library/HTMLPurifier/AttrDef/ID.php @@ -6,9 +6,9 @@ require_once 'HTMLPurifier/IDAccumulator.php'; class HTMLPurifier_AttrDef_ID extends HTMLPurifier_AttrDef { - function validate($id, &$accumulator) { + function validate($old_id, &$accumulator) { - $id = @ (string) $id; // sanity check + $id = trim($old_id); // trim it first if ($id === '') return false; if (isset($accumulator->ids[$id])) return false; @@ -19,7 +19,7 @@ class HTMLPurifier_AttrDef_ID extends HTMLPurifier_AttrDef $result = true; } else { if (!ctype_alpha(@$id[0])) return false; - $trim = trim( + $trim = trim( // primitive style of regexps, I suppose $id, 'A..Za..z0..9:-._' ); @@ -28,7 +28,10 @@ class HTMLPurifier_AttrDef_ID extends HTMLPurifier_AttrDef if ($result) $accumulator->add($id); - return $result; + // if no change was made to the ID, return the result + // else, return the new id if stripping whitespace made it + // valid, or return false. + return ($id == $old_id) ? $result : ($result ? $id : false); } diff --git a/library/HTMLPurifier/Definition.php b/library/HTMLPurifier/Definition.php index b27244d0..8a382b5f 100644 --- a/library/HTMLPurifier/Definition.php +++ b/library/HTMLPurifier/Definition.php @@ -222,9 +222,11 @@ class HTMLPurifier_Definition // info[]->attr : defines allowed attributes for elements // this doesn't include REQUIRED declarations, those are handled - // by the transform classes + // by the transform classes. It will, however, do simple and slightly + // complex attribute value substitution - // attrs, included in almost every single one except for a few + // attrs, included in almost every single one except for a few, + // which manually override these in their local definitions $this->info_global_attr = array( // core attrs 'id' => new HTMLPurifier_AttrDef_ID(), diff --git a/library/HTMLPurifier/Strategy/ValidateAttributes.php b/library/HTMLPurifier/Strategy/ValidateAttributes.php index a9e21980..417ec3cd 100644 --- a/library/HTMLPurifier/Strategy/ValidateAttributes.php +++ b/library/HTMLPurifier/Strategy/ValidateAttributes.php @@ -36,10 +36,17 @@ class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy } else { $result = false; } - if (!$result) { + if ($result === false) { $changed = true; unset($attr[$attr_key]); + } elseif (is_string($result)) { + // simple substitution + $changed = true; + $attr[$attr_key] = $result; } + // we'd also want slightly more complicated substitution, + // although we're not sure how colliding attributes would + // resolve } if ($changed) { $tokens[$key]->attributes = $attr; diff --git a/tests/HTMLPurifier/AttrDef/EnumTest.php b/tests/HTMLPurifier/AttrDef/EnumTest.php index 8e8acbf7..b130c919 100644 --- a/tests/HTMLPurifier/AttrDef/EnumTest.php +++ b/tests/HTMLPurifier/AttrDef/EnumTest.php @@ -23,6 +23,14 @@ class HTMLPurifier_AttrDef_EnumTest extends UnitTestCase } + function testFixing() { + + $def = new HTMLPurifier_AttrDef_Enum(array('one')); + + $this->assertEqual('one', $def->validate(' one ')); + + } + } ?> \ No newline at end of file diff --git a/tests/HTMLPurifier/AttrDef/IDTest.php b/tests/HTMLPurifier/AttrDef/IDTest.php index 0b7d8f5b..6baddf67 100644 --- a/tests/HTMLPurifier/AttrDef/IDTest.php +++ b/tests/HTMLPurifier/AttrDef/IDTest.php @@ -26,6 +26,9 @@ class HTMLPurifier_AttrDef_IDTest extends UnitTestCase // test duplicate detection $this->assertFalse($def->validate('a' , $acc)); + // valid once whitespace stripped, but needs to be amended + $this->assertEqual('whee', $def->validate(' whee ', $acc)); + } } diff --git a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php index 3bfb4eae..8a7cc919 100644 --- a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php +++ b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php @@ -34,6 +34,10 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends $inputs[5] = '
Convert ID to lowercase.
'; $expect[5] = '
Convert ID to lowercase.
'; + // test simple attribute substitution + $inputs[6] = '
Trim whitespace.
'; + $expect[6] = '
Trim whitespace.
'; + $this->assertStrategyWorks($strategy, $inputs, $expect); }