mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-06 14:16:32 +02:00
Dramatically rewrite null host URI handling.
Basically, browsers don't parse what should be valid URIs correctly, so we have to go through some backbends to accomodate them. Specifically, for browseable URIs, the following URIs have unintended behavior: - ///example.com - http:/example.com - http:///example.com Furthermore, if the path begins with //, modifying these URLs must be done with care, as if you remove the host-name component, the parse tree changes. I've modified the engine to follow correct URI semantics as much as possible while outputting browser compatible code, and invalidate the URI in cases where we can't deal. There has been a refactoring of URIScheme so that this important check is always performed, introducing a new member variable allow_empty_host which is true on data, file, mailto and news schemes. This also fixes bypass bugs on URI.Munge. Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
This commit is contained in:
@@ -3,11 +3,13 @@
|
||||
/**
|
||||
* Validator for the components of a URI for a specific scheme
|
||||
*/
|
||||
class HTMLPurifier_URIScheme
|
||||
abstract class HTMLPurifier_URIScheme
|
||||
{
|
||||
|
||||
/**
|
||||
* Scheme's default port (integer)
|
||||
* Scheme's default port (integer). If an explicit port number is
|
||||
* specified that coincides with the default port, it will be
|
||||
* elided.
|
||||
*/
|
||||
public $default_port = null;
|
||||
|
||||
@@ -24,17 +26,62 @@ class HTMLPurifier_URIScheme
|
||||
public $hierarchical = false;
|
||||
|
||||
/**
|
||||
* Validates the components of a URI
|
||||
* @note This implementation should be called by children if they define
|
||||
* a default port, as it does port processing.
|
||||
* @param $uri Instance of HTMLPurifier_URI
|
||||
* Whether or not the URI may omit a hostname when the scheme is
|
||||
* explicitly specified, ala file:///path/to/file. As of writing,
|
||||
* 'file' is the only scheme that browsers support his properly.
|
||||
*/
|
||||
public $may_omit_host = false;
|
||||
|
||||
/**
|
||||
* Validates the components of a URI for a specific scheme.
|
||||
* @param $uri Reference to a HTMLPurifier_URI object
|
||||
* @param $config HTMLPurifier_Config object
|
||||
* @param $context HTMLPurifier_Context object
|
||||
* @return Bool success or failure
|
||||
*/
|
||||
public abstract function doValidate(&$uri, $config, $context);
|
||||
|
||||
/**
|
||||
* Public interface for validating components of a URI. Performs a
|
||||
* bunch of default actions. Don't overload this method.
|
||||
* @param $uri Reference to a HTMLPurifier_URI object
|
||||
* @param $config HTMLPurifier_Config object
|
||||
* @param $context HTMLPurifier_Context object
|
||||
* @return Bool success or failure
|
||||
*/
|
||||
public function validate(&$uri, $config, $context) {
|
||||
if ($this->default_port == $uri->port) $uri->port = null;
|
||||
return true;
|
||||
// kludge: browsers do funny things when the scheme but not the
|
||||
// authority is set
|
||||
if (!$this->may_omit_host &&
|
||||
// if the scheme is present, a missing host is always in error
|
||||
(!is_null($uri->scheme) && ($uri->host === '' || is_null($uri->host))) ||
|
||||
// if the scheme is not present, a *blank* host is in error,
|
||||
// since this translates into '///path' which most browsers
|
||||
// interpret as being 'http://path'.
|
||||
(is_null($uri->scheme) && $uri->host === '')
|
||||
) {
|
||||
do {
|
||||
if (is_null($uri->scheme)) {
|
||||
if (substr($uri->path, 0, 2) != '//') {
|
||||
$uri->host = null;
|
||||
break;
|
||||
}
|
||||
// URI is '////path', so we cannot nullify the
|
||||
// host to preserve semantics. Try expanding the
|
||||
// hostname instead (fall through)
|
||||
}
|
||||
// first see if we can manually insert a hostname
|
||||
$host = $config->get('URI.Host');
|
||||
if (!is_null($host)) {
|
||||
$uri->host = $host;
|
||||
} else {
|
||||
// we can't do anything sensible, reject the URL.
|
||||
return false;
|
||||
}
|
||||
} while (false);
|
||||
}
|
||||
return $this->doValidate($uri, $config, $context);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user