From 6b9c5ec603eed297f58c7ebeecadf5b076b8b71e Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Mon, 14 May 2007 22:36:35 +0000 Subject: [PATCH] [1.7.0] Implement DoctypeRegistry. Add transparent constructor to Doctype. git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1059 48356398-32a2-884e-a903-53898d9a118a --- library/HTMLPurifier/Doctype.php | 19 +++-- library/HTMLPurifier/DoctypeRegistry.php | 69 +++++++++++++++++++ tests/HTMLPurifier/DoctypeRegistryTest.php | 80 ++++++++++++++++++++++ tests/test_files.php | 1 + 4 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 library/HTMLPurifier/DoctypeRegistry.php create mode 100644 tests/HTMLPurifier/DoctypeRegistryTest.php diff --git a/library/HTMLPurifier/Doctype.php b/library/HTMLPurifier/Doctype.php index 4056e569..4c9f3a05 100644 --- a/library/HTMLPurifier/Doctype.php +++ b/library/HTMLPurifier/Doctype.php @@ -11,11 +11,6 @@ class HTMLPurifier_Doctype */ var $name; - /** - * List of aliases to doctype name - */ - var $aliases = array(); - /** * List of standard modules (string identifiers or literal objects) * that this doctype uses @@ -28,6 +23,20 @@ class HTMLPurifier_Doctype * is enabled, such as lenient or correctional. */ var $modulesForModes = array(); + + /** + * List of aliases to doctype name + */ + var $aliases = array(); + + function HTMLPurifier_Doctype($name = null, $modules = array(), + $modules_for_modes = array(), $aliases = array() + ) { + $this->name = $name; + $this->modules = $modules; + $this->modulesForModes = $modules_for_modes; + $this->aliases = $aliases; + } } ?> \ No newline at end of file diff --git a/library/HTMLPurifier/DoctypeRegistry.php b/library/HTMLPurifier/DoctypeRegistry.php new file mode 100644 index 00000000..8b3f0e0b --- /dev/null +++ b/library/HTMLPurifier/DoctypeRegistry.php @@ -0,0 +1,69 @@ +doctypes[$doctype->name] =& $doctype; + $name = $doctype->name; + // hookup aliases + foreach ($doctype->aliases as $alias) { + if (isset($this->doctypes[$alias])) continue; + $this->aliases[$alias] = $name; + } + // remove old aliases + if (isset($this->aliases[$name])) unset($this->aliases[$name]); + return $doctype; + } + + /** + * Retrieves reference to a doctype of a certain name + * @note This function resolves aliases + * @param $doctype Name of doctype + * @return Reference to doctype object + */ + function &get($doctype) { + if (isset($this->aliases[$doctype])) $doctype = $this->aliases[$doctype]; + if (!isset($this->doctypes[$doctype])) { + trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist'); + $null = null; return $null; + } + return $this->doctypes[$doctype]; + } + +} + +?> \ No newline at end of file diff --git a/tests/HTMLPurifier/DoctypeRegistryTest.php b/tests/HTMLPurifier/DoctypeRegistryTest.php new file mode 100644 index 00000000..b94b10e1 --- /dev/null +++ b/tests/HTMLPurifier/DoctypeRegistryTest.php @@ -0,0 +1,80 @@ +register( + $name = 'XHTML 1.0 Transitional', + $modules = array('module-one', 'module-two'), + $modulesForModes = array( + 'lenient' => array('lenient-module'), + ), + $aliases = array('X10T') + ); + + $d2 = new HTMLPurifier_Doctype($name, $modules, $modulesForModes, $aliases); + + $this->assertIdentical($d, $d2); + $this->assertReference($d, $registry->get('XHTML 1.0 Transitional')); + + // test shorthand + $d =& $registry->register( + $name = 'XHTML 1.0 Strict', 'module', array(), 'X10S' + ); + $d2 = new HTMLPurifier_Doctype($name, array('module'), array(), array('X10S')); + + $this->assertIdentical($d, $d2); + + } + + function test_get() { + + // see also alias and register tests + + $registry = new HTMLPurifier_DoctypeRegistry(); + + $this->expectError('Doctype XHTML 2.0 does not exist'); + $registry->get('XHTML 2.0'); + + // prevent XSS + $this->expectError('Doctype <foo> does not exist'); + $registry->get(''); + + } + + function testAliases() { + + $registry = new HTMLPurifier_DoctypeRegistry(); + + $d1 =& $registry->register('Doc1', array(), array(), array('1')); + + $this->assertReference($d1, $registry->get('Doc1')); + $this->assertReference($d1, $registry->get('1')); + + $d2 =& $registry->register('Doc2', array(), array(), array('2')); + + $this->assertReference($d2, $registry->get('Doc2')); + $this->assertReference($d2, $registry->get('2')); + + $d3 =& $registry->register('1', array(), array(), array()); + + // literal name overrides alias + $this->assertReference($d3, $registry->get('1')); + + $d4 =& $registry->register('One', array(), array(), array('1')); + + $this->assertReference($d4, $registry->get('One')); + // still it overrides + $this->assertReference($d3, $registry->get('1')); + + } + +} + +?> \ No newline at end of file diff --git a/tests/test_files.php b/tests/test_files.php index d0ec5089..602dc47b 100644 --- a/tests/test_files.php +++ b/tests/test_files.php @@ -55,6 +55,7 @@ $test_files[] = 'ChildDef/TableTest.php'; $test_files[] = 'ConfigSchemaTest.php'; $test_files[] = 'ConfigTest.php'; $test_files[] = 'ContextTest.php'; +$test_files[] = 'DoctypeRegistryTest.php'; $test_files[] = 'ElementDefTest.php'; $test_files[] = 'EncoderTest.php'; $test_files[] = 'EntityLookupTest.php';