From 32c0ffde0cfe41c469d5f113aeceb1582bf316c1 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 12 Jun 2011 10:59:27 +0100 Subject: [PATCH] Don't add nofollow for matching hosts, generalize this code. Signed-off-by: Edward Z. Yang --- NEWS | 2 ++ library/HTMLPurifier/AttrTransform/Nofollow.php | 2 +- library/HTMLPurifier/URI.php | 15 +++++++++++++++ library/HTMLPurifier/URIFilter/Munge.php | 9 ++++----- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 2a523bcf..b0773b41 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier - Explicitly initialize anonModule variable to null. - Do not duplicate nofollow if already present. Thanks 178 for reporting. +- Do not add nofollow if hostname matches our current host. Thanks 178 + for reporting, and Neike Taika-Tessaro for helping diagnose. 4.3.0, released 2011-03-27 # Fixed broken caching of customized raw definitions, but requires an diff --git a/library/HTMLPurifier/AttrTransform/Nofollow.php b/library/HTMLPurifier/AttrTransform/Nofollow.php index 8143409a..f7fb1209 100644 --- a/library/HTMLPurifier/AttrTransform/Nofollow.php +++ b/library/HTMLPurifier/AttrTransform/Nofollow.php @@ -24,7 +24,7 @@ class HTMLPurifier_AttrTransform_Nofollow extends HTMLPurifier_AttrTransform $url = $this->parser->parse($attr['href']); $scheme = $url->getSchemeObj($config, $context); - if (!is_null($url->host) && $scheme !== false && $scheme->browsable) { + if ($scheme->browsable && !$url->isLocal($config, $context)) { if (isset($attr['rel'])) { $rels = explode(' ', $attr); if (!in_array('nofollow', $rels)) { diff --git a/library/HTMLPurifier/URI.php b/library/HTMLPurifier/URI.php index efdfb2c6..79b7a71f 100644 --- a/library/HTMLPurifier/URI.php +++ b/library/HTMLPurifier/URI.php @@ -199,6 +199,21 @@ class HTMLPurifier_URI return $result; } + /** + * Returns true if this URL might be considered a 'local' URL given + * the current context. This is true when the host is null, or + * when it matches the host supplied to the configuration. + * + * Note that this does not do any scheme checking (URI.Munge, I'm + * looking at you). + */ + public function isLocal($config, $context) { + if ($this->host === null) return true; + $uri_def = $config->getDefinition('URI'); + if ($uri_def->host === $this->host) return true; + return false; + } + } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/URIFilter/Munge.php b/library/HTMLPurifier/URIFilter/Munge.php index 40d059b2..448f7646 100644 --- a/library/HTMLPurifier/URIFilter/Munge.php +++ b/library/HTMLPurifier/URIFilter/Munge.php @@ -20,12 +20,11 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter $scheme_obj = $uri->getSchemeObj($config, $context); if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it - if (is_null($uri->host) || empty($scheme_obj->browsable)) { - return true; - } - $uri_definition = $config->getDefinition('URI'); + if (!$scheme_obj->browsable) return true; // ignore non-browseable schemes + // don't redirect if target host is our host - if ($uri->host === $uri_definition->host) { + if ($uri->isLocal($config, $context)) { + $uri_definition = $config->getDefinition('URI'); // but do redirect if we're currently on a secure scheme, // and the target scheme is insecure $current_scheme_obj = HTMLPurifier_URISchemeRegistry::instance()->getScheme($uri_definition->defaultScheme, $config, $context); -- 2.11.4.GIT