diff --git a/library/HTMLPurifier/ConfigDef.php b/library/HTMLPurifier/ConfigDef.php
index f001127a..0c76ed70 100644
--- a/library/HTMLPurifier/ConfigDef.php
+++ b/library/HTMLPurifier/ConfigDef.php
@@ -29,6 +29,7 @@ class HTMLPurifier_ConfigDef {
return;
}
if (isset($def->info[$namespace][$name])) {
+ // this behavior is at risk of change
trigger_error('Cannot redefine directive', E_USER_ERROR);
return;
}
diff --git a/library/HTMLPurifier/URIScheme.php b/library/HTMLPurifier/URIScheme.php
index 8b3ec2c1..f4c1baa6 100644
--- a/library/HTMLPurifier/URIScheme.php
+++ b/library/HTMLPurifier/URIScheme.php
@@ -3,7 +3,7 @@
class HTMLPurifier_URIScheme
{
- function validateComponents() {
+ function validateComponents($authority, $path, $query, $fragment) {
}
diff --git a/library/HTMLPurifier/URIScheme/http.php b/library/HTMLPurifier/URIScheme/http.php
new file mode 100644
index 00000000..946e29ba
--- /dev/null
+++ b/library/HTMLPurifier/URIScheme/http.php
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/library/HTMLPurifier/URISchemeRegistry.php b/library/HTMLPurifier/URISchemeRegistry.php
index 438561be..fb2540f9 100644
--- a/library/HTMLPurifier/URISchemeRegistry.php
+++ b/library/HTMLPurifier/URISchemeRegistry.php
@@ -1,5 +1,21 @@
true, // "Hypertext Transfer Protocol", nuf' said
+ 'https' => true, // HTTP over SSL (Secure Socket Layer)
+ // quite useful, but not necessary
+ 'mailto' => true,// Email
+ 'ftp' => true, // "File Transfer Protocol"
+ 'irc' => true, // "Internet Relay Chat", usually needs another app
+ // for Usenet, these two are similar, but distinct
+ 'nntp' => true, // individual Netnews articles
+ 'news' => true // newsgroup or individual Netnews articles),
+ ),
+ 'Whitelist that defines the schemes that a URI is allowed to have. This '.
+ 'prevents XSS attacks from using pseudo-schemes like javascript or mocha.'
+);
+
class HTMLPurifier_URISchemeRegistry
{
@@ -16,7 +32,25 @@ class HTMLPurifier_URISchemeRegistry
return $instance;
}
- function &getScheme($scheme) {}
+ var $schemes = array();
+ var $_scheme_dir = null;
+
+ function &getScheme($scheme, $config = null) {
+ if (!$config) $config = HTMLPurifier_Config::createDefault();
+ $null = null; // for the sake of passing by reference
+ if (isset($this->schemes[$scheme])) return $this->schemes[$scheme];
+ if (empty($this->_dir)) $this->_dir = dirname(__FILE__) . '/URIScheme/';
+
+ // important, otherwise attacker could include arbitrary file
+ $allowed_schemes = $config->get('URI', 'AllowedSchemes');
+ if (!isset($allowed_schemes[$scheme])) return $null;
+
+ @include_once $this->_dir . $scheme . '.php';
+ $class = 'HTMLPurifier_URIScheme_' . $scheme;
+ if (!class_exists($class)) return $null;
+ $this->schemes[$scheme] = new $class();
+ return $this->schemes[$scheme];
+ }
}
diff --git a/tests/HTMLPurifier/AttrDef/URITest.php b/tests/HTMLPurifier/AttrDef/URITest.php
index c7533074..5f8e8b54 100644
--- a/tests/HTMLPurifier/AttrDef/URITest.php
+++ b/tests/HTMLPurifier/AttrDef/URITest.php
@@ -5,7 +5,7 @@ require_once 'HTMLPurifier/AttrDef/URI.php';
// WARNING: INCOMPLETE UNIT TESTS!
// we are currently abstaining IPv6 and percent-encode fixing unit tests
-// as well as recomposition tests
+// we also need to test all the configuration directives defined by this class
class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
{
@@ -15,6 +15,8 @@ class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
generate_mock_once('HTMLPurifier_URIScheme');
generate_mock_once('HTMLPurifier_URISchemeRegistry');
+ $old_registry = HTMLPurifier_URISchemeRegistry::instance();
+
// finally, lets get a copy of the actual class
$def = new HTMLPurifier_AttrDef_URI();
@@ -186,6 +188,9 @@ class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
}
+ // reset to regular implementation
+ HTMLPurifier_URISchemeRegistry::instance($old_registry);
+
}
}
diff --git a/tests/HTMLPurifier/ConfigDefTest.php b/tests/HTMLPurifier/ConfigDefTest.php
index 7c57fa8f..29bfe268 100644
--- a/tests/HTMLPurifier/ConfigDefTest.php
+++ b/tests/HTMLPurifier/ConfigDefTest.php
@@ -50,6 +50,9 @@ class HTMLPurifier_ConfigDefTest extends UnitTestCase
$this->swallowErrors();
// test overloading already defined value
+ // ACTUALLY, we probably should allow this behavior, which simply
+ // means that two class files need that directive. Using debug_backtrace
+ // we could probably figure which files those are too! :-D
HTMLPurifier_ConfigDef::define('Core', 'Name', 89,
'What, you\'re not allowed to overload directives? Bummer!');
$this->assertError('Cannot redefine directive');
diff --git a/tests/HTMLPurifier/URISchemeRegistryTest.php b/tests/HTMLPurifier/URISchemeRegistryTest.php
new file mode 100644
index 00000000..7b46b3bd
--- /dev/null
+++ b/tests/HTMLPurifier/URISchemeRegistryTest.php
@@ -0,0 +1,20 @@
+assertIsA($registry->getScheme('http'), 'HTMLPurifier_URIScheme_http');
+
+ // to come: overloading and custom schemes, as well as changing the
+ // configuration values used by this class
+
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/tests/index.php b/tests/index.php
index 61f5e7f7..0d2ee800 100644
--- a/tests/index.php
+++ b/tests/index.php
@@ -67,6 +67,7 @@ $test_files[] = 'IDAccumulatorTest.php';
$test_files[] = 'TagTransformTest.php';
$test_files[] = 'AttrTransform/LangTest.php';
$test_files[] = 'AttrTransform/TextAlignTest.php';
+$test_files[] = 'URISchemeRegistryTest.php';
$test_file_lookup = array_flip($test_files);