From 47fe34ad81ba5824d0979aa493b558b2b697650b Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Mon, 7 May 2007 01:51:26 +0000 Subject: [PATCH] [1.7.0] Create convenience functions for HTMLModule constructors, HTMLModule_Bdo was hooked up - Add initial "safe" property for elements, is not set for most though git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1039 48356398-32a2-884e-a903-53898d9a118a --- NEWS | 1 + library/HTMLPurifier/ElementDef.php | 19 ++++++++++ library/HTMLPurifier/HTMLModule.php | 43 +++++++++++++++++++++ library/HTMLPurifier/HTMLModule/Bdo.php | 29 ++++++-------- tests/HTMLPurifier/HTMLModuleTest.php | 50 +++++++++++++++++++++++++ tests/test_files.php | 1 + 6 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 tests/HTMLPurifier/HTMLModuleTest.php diff --git a/NEWS b/NEWS index 0988f7a9..b1baf882 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier 1.7.0, unknown release date . Unit test for ElementDef created, ElementDef behavior modified to be more flexible +. Added convenience functions for HTMLModule constructors 1.6.1, released 2007-05-05 ! Support for more deprecated attributes via transformations: diff --git a/library/HTMLPurifier/ElementDef.php b/library/HTMLPurifier/ElementDef.php index 81e24338..30c80cd4 100644 --- a/library/HTMLPurifier/ElementDef.php +++ b/library/HTMLPurifier/ElementDef.php @@ -58,6 +58,7 @@ class HTMLPurifier_ElementDef /** * Value of $child->type, used to determine which ChildDef to use, * used in combination with $content_model. + * @warning This must be lowercase * @public */ var $content_model_type; @@ -86,6 +87,24 @@ class HTMLPurifier_ElementDef */ var $excludes = array(); + /** + * Is this element safe for untrusted users to use? + */ + var $safe = false; + + /** + * Factory constructor for creating new standalone element defs + * @static + */ + function create($safe, $content_model, $content_model_type, $attr) { + $def = new HTMLPurifier_ElementDef(); + $def->safe = (bool) $safe; + $def->content_model = $content_model; + $def->content_model_type = $content_model_type; + $def->attr = $attr; + return $def; + } + /** * Merges the values of another element definition into this one. * Values from the new element def take precedence if a value is diff --git a/library/HTMLPurifier/HTMLModule.php b/library/HTMLPurifier/HTMLModule.php index 930b605d..2a0ec9f4 100644 --- a/library/HTMLPurifier/HTMLModule.php +++ b/library/HTMLPurifier/HTMLModule.php @@ -120,6 +120,49 @@ class HTMLPurifier_HTMLModule */ function setup(&$definition) {} + /** + * Convenience function that sets up a new element + * @param $element Name of element to add + * @param $safe Is element safe for untrusted users to use? + * @param $type What content set should element be registered to? + * Set as false to skip this step. + * @param $content_model Content model definition in form of: + * "$content_model_type: $content_model" + * @param $attr_includes What attribute collections to register to + * element? + * @param $attr What unique attributes does the element define? + * @note See ElementDef for in-depth descriptions of these parameters. + * @protected + */ + function addElement($element, $safe, $type, $content_model, $attr_includes, $attr) { + $this->elements[] = $element; + // parse content_model + list($content_model_type, $content_model) = explode(':', $content_model); + $content_model_type = strtolower(trim($content_model_type)); + $content_model = trim($content_model); + // merge in attribute inclusions + $attr[0] = $attr_includes; + // add element to content sets + if ($type) $this->addElementToContentSet($element, $type); + // create element + $this->info[$element] = HTMLPurifier_ElementDef::create( + $safe, $content_model, $content_model_type, $attr + ); + } + + /** + * Convenience function that registers an element to a content set + * @param Element to register + * @param Name content set (warning: case sensitive, usually upper-case + * first letter) + * @protected + */ + function addElementToContentSet($element, $type) { + if (!isset($this->content_sets[$type])) $this->content_sets[$type] = ''; + else $this->content_sets[$type] .= ' | '; + $this->content_sets[$type] .= $element; + } + } ?> \ No newline at end of file diff --git a/library/HTMLPurifier/HTMLModule/Bdo.php b/library/HTMLPurifier/HTMLModule/Bdo.php index 6feae005..5b280d64 100644 --- a/library/HTMLPurifier/HTMLModule/Bdo.php +++ b/library/HTMLPurifier/HTMLModule/Bdo.php @@ -11,30 +11,25 @@ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule { var $name = 'Bdo'; - var $elements = array('bdo'); - var $content_sets = array('Inline' => 'bdo'); var $attr_collections = array( 'I18N' => array('dir' => false) ); function HTMLPurifier_HTMLModule_Bdo() { $dir = new HTMLPurifier_AttrDef_Enum(array('ltr','rtl'), false); - $this->attr_collections['I18N']['dir'] = $dir; - $this->info['bdo'] = new HTMLPurifier_ElementDef(); - $this->info['bdo']->attr = array( - 0 => array('Core', 'Lang'), - 'dir' => $dir, // required - // The Abstract Module specification has the attribute - // inclusions wrong for bdo: bdo allows - // xml:lang too (and we'll toss in lang for good measure, - // though it is not allowed for XHTML 1.1, this will - // be managed with a global attribute transform) + $this->addElement( + 'bdo', true, 'Inline', 'Optional: #PCDATA | Inline', array('Core', 'Lang'), + array( + 'dir' => $dir, // required + // The Abstract Module specification has the attribute + // inclusions wrong for bdo: bdo allows + // xml:lang too (and we'll toss in lang for good measure, + // though it is not allowed for XHTML 1.1, this will + // be managed with a global attribute transform) + ) ); - $this->info['bdo']->content_model = '#PCDATA | Inline'; - $this->info['bdo']->content_model_type = 'optional'; - // provides fallback behavior if dir's missing (dir is required) - $this->info['bdo']->attr_transform_post['required-dir'] = - new HTMLPurifier_AttrTransform_BdoDir(); + $this->info['bdo']->attr_transform_post['required-dir'] = new HTMLPurifier_AttrTransform_BdoDir(); + $this->attr_collections['I18N']['dir'] = $dir; } } diff --git a/tests/HTMLPurifier/HTMLModuleTest.php b/tests/HTMLPurifier/HTMLModuleTest.php new file mode 100644 index 00000000..9ea48de7 --- /dev/null +++ b/tests/HTMLPurifier/HTMLModuleTest.php @@ -0,0 +1,50 @@ +addElementToContentSet('b', 'Inline'); + $this->assertIdentical($module->content_sets, array('Inline' => 'b')); + + $module->addElementToContentSet('i', 'Inline'); + $this->assertIdentical($module->content_sets, array('Inline' => 'b | i')); + + } + + function test_addElement() { + + $module = new HTMLPurifier_HTMLModule(); + $module->addElement( + 'a', true, 'Inline', 'Optional: #PCDATA', array('Common'), + array( + 'href' => 'URI' + ) + ); + + $module2 = new HTMLPurifier_HTMLModule(); + $def = new HTMLPurifier_ElementDef(); + $def->safe = true; + $def->content_model = '#PCDATA'; + $def->content_model_type = 'optional'; + $def->attr = array( + 'href' => 'URI', + 0 => array('Common') + ); + $module2->info['a'] = $def; + $module2->elements = array('a'); + $module2->content_sets['Inline'] = 'a'; + + $this->assertIdentical($module, $module2); + + } + +} + +?> \ No newline at end of file diff --git a/tests/test_files.php b/tests/test_files.php index 1b59bc0e..06af15ee 100644 --- a/tests/test_files.php +++ b/tests/test_files.php @@ -61,6 +61,7 @@ $test_files[] = 'EntityLookupTest.php'; $test_files[] = 'EntityParserTest.php'; $test_files[] = 'GeneratorTest.php'; $test_files[] = 'HTMLModuleManagerTest.php'; +$test_files[] = 'HTMLModuleTest.php'; $test_files[] = 'IDAccumulatorTest.php'; $test_files[] = 'LanguageFactoryTest.php'; $test_files[] = 'LanguageTest.php';