1
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2025-07-30 19:00:10 +02:00

[2.1.0] Further refactoring of AttrDef_URI, creation of new URIFilter and URIDefinition subsystems.

git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1335 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
Edward Z. Yang
2007-08-02 01:12:27 +00:00
parent 797b899305
commit 4919187fc6
20 changed files with 420 additions and 132 deletions

View File

@@ -25,29 +25,6 @@ HTMLPurifier_ConfigSchema::define(
'This directive has been available since 1.2.0.'
);
HTMLPurifier_ConfigSchema::define(
'URI', 'DisableExternal', false, 'bool',
'Disables links to external websites. This is a highly effective '.
'anti-spam and anti-pagerank-leech measure, but comes at a hefty price: no'.
'links or images outside of your domain will be allowed. Non-linkified '.
'URIs will still be preserved. If you want to be able to link to '.
'subdomains or use absolute URIs, specify %URI.Host for your website. '.
'This directive has been available since 1.2.0.'
);
HTMLPurifier_ConfigSchema::define(
'URI', 'DisableExternalResources', false, 'bool',
'Disables the embedding of external resources, preventing users from '.
'embedding things like images from other hosts. This prevents '.
'access tracking (good for email viewers), bandwidth leeching, '.
'cross-site request forging, goatse.cx posting, and '.
'other nasties, but also results in '.
'a loss of end-user functionality (they can\'t directly post a pic '.
'they posted from Flickr anymore). Use it if you don\'t have a '.
'robust user-content moderation team. This directive has been '.
'available since 1.3.0.'
);
HTMLPurifier_ConfigSchema::define(
'URI', 'DisableResources', false, 'bool',
'Disables embedding resources, essentially meaning no pictures. You can '.
@@ -117,18 +94,35 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
$uri = $this->parser->parse($uri);
if ($uri === false) return false;
// generic validation
$context->register('EmbeddedURI', $this->embedsResource); // flag
$result = $uri->validate($config, $context);
$context->destroy('EmbeddedURI');
if (!$result) return false;
// add embedded flag to context for validators
$context->register('EmbeddedURI', $this->embedsResource);
// scheme-specific validation
$scheme_obj = $uri->getSchemeObj($config, $context);
if (!$scheme_obj) return false;
if ($this->embedsResource && !$scheme_obj->browsable) return false;
$result = $scheme_obj->validate($uri, $config, $context);
if (!$result) return false;
$ok = false;
do {
// generic validation
$result = $uri->validate($config, $context);
if (!$result) break;
// chained validation
$uri_def =& $config->getDefinition('URI');
$result = $uri_def->filter($uri, $config, $context);
if (!$result) break;
// scheme-specific validation
$scheme_obj = $uri->getSchemeObj($config, $context);
if (!$scheme_obj) break;
if ($this->embedsResource && !$scheme_obj->browsable) break;
$result = $scheme_obj->validate($uri, $config, $context);
if (!$result) break;
// survived gauntlet
$ok = true;
} while (false);
$context->destroy('EmbeddedURI');
if (!$ok) return false;
// back to string
$result = $uri->toString();

View File

@@ -5,6 +5,7 @@ require_once 'HTMLPurifier/ConfigSchema.php';
// member variables
require_once 'HTMLPurifier/HTMLDefinition.php';
require_once 'HTMLPurifier/CSSDefinition.php';
require_once 'HTMLPurifier/URIDefinition.php';
require_once 'HTMLPurifier/Doctype.php';
require_once 'HTMLPurifier/DefinitionCacheFactory.php';
@@ -313,6 +314,8 @@ class HTMLPurifier_Config
$this->definitions[$type] = new HTMLPurifier_HTMLDefinition();
} elseif ($type == 'CSS') {
$this->definitions[$type] = new HTMLPurifier_CSSDefinition();
} elseif ($type == 'URI') {
$this->definitions[$type] = new HTMLPurifier_URIDefinition();
} else {
trigger_error("Definition of $type type not supported");
$false = false;

View File

@@ -1,6 +1,7 @@
<?php
require_once 'HTMLPurifier/URIParser.php';
require_once 'HTMLPurifier/URIFilter.php';
/**
* HTML Purifier's internal representation of a URI
@@ -50,19 +51,7 @@ class HTMLPurifier_URI
// validate host
if (!is_null($this->host)) {
// remove URI if it's absolute and we disabled externals or
// if it's absolute and embedded and we disabled external resources
unset($our_host); // ensure this variable is not set
if (
$config->get('URI', 'DisableExternal') ||
(
$config->get('URI', 'DisableExternalResources') &&
$context->get('EmbeddedURI', true) // suppress errors
)
) {
$our_host = $config->get('URI', 'Host');
if ($our_host === null) return false;
}
$host_def = new HTMLPurifier_AttrDef_URI_Host();
$this->host = $host_def->validate($this->host, $config, $context);
if ($this->host === false) $this->host = null;
@@ -70,16 +59,6 @@ class HTMLPurifier_URI
// check host against blacklist
if ($this->checkBlacklist($this->host, $config, $context)) return false;
// more lenient absolute checking
if (isset($our_host)) {
$host_parts = array_reverse(explode('.', $this->host));
// could be cached
$our_host_parts = array_reverse(explode('.', $our_host));
foreach ($our_host_parts as $i => $discard) {
if (!isset($host_parts[$i])) return false;
if ($host_parts[$i] != $our_host_parts[$i]) return false;
}
}
}
// munge scheme off if necessary

View File

@@ -0,0 +1,53 @@
<?php
require_once 'HTMLPurifier/Definition.php';
require_once 'HTMLPurifier/URIFilter.php';
require_once 'HTMLPurifier/URIFilter/DisableExternal.php';
require_once 'HTMLPurifier/URIFilter/DisableExternalResources.php';
HTMLPurifier_ConfigSchema::define(
'URI', 'DefinitionRev', 1, 'int', '
<p>
Revision identifier for your custom definition. See
%HTML.DefinitionRev for details. This directive has been available
since 2.1.0.
</p>
');
class HTMLPurifier_URIDefinition extends HTMLPurifier_Definition
{
var $type = 'URI';
var $filters = array();
var $registeredFilters = array();
function HTMLPurifier_URIDefinition() {
$this->registerFilter(new HTMLPurifier_URIFilter_DisableExternal());
$this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources());
}
function registerFilter($filter) {
$this->registeredFilters[$filter->name] = $filter;
}
function doSetup($config) {
foreach ($this->registeredFilters as $name => $filter) {
$conf = $config->get('URI', $name);
if ($conf !== false && $conf !== null) {
$this->filters[$name] = $filter;
}
}
foreach ($this->filters as $n => $x) $this->filters[$n]->prepare($config);
unset($this->registeredFilters);
}
function filter(&$uri, $config, &$context) {
foreach ($this->filters as $name => $x) {
$result = $this->filters[$name]->filter($uri, $config, $context);
if (!$result) return false;
}
return true;
}
}

View File

@@ -0,0 +1,24 @@
<?php
/**
* Chainable filters for custom URI processing
*/
class HTMLPurifier_URIFilter
{
var $name;
/**
* Performs initialization for the filter
*/
function prepare($config) {}
/**
* Filter a URI object
* @param &$uri Reference to URI object
* @param $config Instance of HTMLPurifier_Config
* @param &$context Instance of HTMLPurifier_Context
*/
function filter(&$uri, $config, &$context) {
trigger_error('Cannot call abstract function', E_USER_ERROR);
}
}

View File

@@ -0,0 +1,34 @@
<?php
require_once 'HTMLPurifier/URIFilter.php';
HTMLPurifier_ConfigSchema::define(
'URI', 'DisableExternal', false, 'bool',
'Disables links to external websites. This is a highly effective '.
'anti-spam and anti-pagerank-leech measure, but comes at a hefty price: no'.
'links or images outside of your domain will be allowed. Non-linkified '.
'URIs will still be preserved. If you want to be able to link to '.
'subdomains or use absolute URIs, specify %URI.Host for your website. '.
'This directive has been available since 1.2.0.'
);
class HTMLPurifier_URIFilter_DisableExternal extends HTMLPurifier_URIFilter
{
var $name = 'DisableExternal';
var $ourHostParts = false;
function prepare($config) {
$our_host = $config->get('URI', 'Host');
if ($our_host !== null) $this->ourHostParts = array_reverse(explode('.', $our_host));
}
function filter(&$uri, $config, &$context) {
if (is_null($uri->host)) return true;
if ($this->ourHostParts === false) return false;
$host_parts = array_reverse(explode('.', $uri->host));
foreach ($this->ourHostParts as $i => $x) {
if (!isset($host_parts[$i])) return false;
if ($host_parts[$i] != $this->ourHostParts[$i]) return false;
}
return true;
}
}

View File

@@ -0,0 +1,26 @@
<?php
require_once 'HTMLPurifier/URIFilter/DisableExternal.php';
HTMLPurifier_ConfigSchema::define(
'URI', 'DisableExternalResources', false, 'bool',
'Disables the embedding of external resources, preventing users from '.
'embedding things like images from other hosts. This prevents '.
'access tracking (good for email viewers), bandwidth leeching, '.
'cross-site request forging, goatse.cx posting, and '.
'other nasties, but also results in '.
'a loss of end-user functionality (they can\'t directly post a pic '.
'they posted from Flickr anymore). Use it if you don\'t have a '.
'robust user-content moderation team. This directive has been '.
'available since 1.3.0.'
);
class HTMLPurifier_URIFilter_DisableExternalResources extends HTMLPurifier_URIFilter_DisableExternal
{
var $name = 'DisableExternalResources';
function filter(&$uri, $config, &$context) {
if (!$context->get('EmbeddedURI', true)) return true;
return parent::filter($uri, $config, $context);
}
}