summaryrefslogtreecommitdiff
path: root/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter')
-rw-r--r--vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternal.php54
-rw-r--r--vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternalResources.php25
-rw-r--r--vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableResources.php22
-rw-r--r--vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php46
-rw-r--r--vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/MakeAbsolute.php158
-rw-r--r--vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php115
-rw-r--r--vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/SafeIframe.php68
7 files changed, 488 insertions, 0 deletions
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternal.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternal.php
new file mode 100644
index 0000000..ced1b13
--- /dev/null
+++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternal.php
@@ -0,0 +1,54 @@
+<?php
+
+class HTMLPurifier_URIFilter_DisableExternal extends HTMLPurifier_URIFilter
+{
+ /**
+ * @type string
+ */
+ public $name = 'DisableExternal';
+
+ /**
+ * @type array
+ */
+ protected $ourHostParts = false;
+
+ /**
+ * @param HTMLPurifier_Config $config
+ * @return void
+ */
+ public function prepare($config)
+ {
+ $our_host = $config->getDefinition('URI')->host;
+ if ($our_host !== null) {
+ $this->ourHostParts = array_reverse(explode('.', $our_host));
+ }
+ }
+
+ /**
+ * @param HTMLPurifier_URI $uri Reference
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public 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;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternalResources.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternalResources.php
new file mode 100644
index 0000000..c656216
--- /dev/null
+++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableExternalResources.php
@@ -0,0 +1,25 @@
+<?php
+
+class HTMLPurifier_URIFilter_DisableExternalResources extends HTMLPurifier_URIFilter_DisableExternal
+{
+ /**
+ * @type string
+ */
+ public $name = 'DisableExternalResources';
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function filter(&$uri, $config, $context)
+ {
+ if (!$context->get('EmbeddedURI', true)) {
+ return true;
+ }
+ return parent::filter($uri, $config, $context);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableResources.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableResources.php
new file mode 100644
index 0000000..d5c412c
--- /dev/null
+++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/DisableResources.php
@@ -0,0 +1,22 @@
+<?php
+
+class HTMLPurifier_URIFilter_DisableResources extends HTMLPurifier_URIFilter
+{
+ /**
+ * @type string
+ */
+ public $name = 'DisableResources';
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function filter(&$uri, $config, $context)
+ {
+ return !$context->get('EmbeddedURI', true);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php
new file mode 100644
index 0000000..a6645c1
--- /dev/null
+++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php
@@ -0,0 +1,46 @@
+<?php
+
+// It's not clear to me whether or not Punycode means that hostnames
+// do not have canonical forms anymore. As far as I can tell, it's
+// not a problem (punycoding should be identity when no Unicode
+// points are involved), but I'm not 100% sure
+class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter
+{
+ /**
+ * @type string
+ */
+ public $name = 'HostBlacklist';
+
+ /**
+ * @type array
+ */
+ protected $blacklist = array();
+
+ /**
+ * @param HTMLPurifier_Config $config
+ * @return bool
+ */
+ public function prepare($config)
+ {
+ $this->blacklist = $config->get('URI.HostBlacklist');
+ return true;
+ }
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function filter(&$uri, $config, $context)
+ {
+ foreach ($this->blacklist as $blacklisted_host_fragment) {
+ if (strpos($uri->host, $blacklisted_host_fragment) !== false) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/MakeAbsolute.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/MakeAbsolute.php
new file mode 100644
index 0000000..c507bbf
--- /dev/null
+++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/MakeAbsolute.php
@@ -0,0 +1,158 @@
+<?php
+
+// does not support network paths
+
+class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter
+{
+ /**
+ * @type string
+ */
+ public $name = 'MakeAbsolute';
+
+ /**
+ * @type
+ */
+ protected $base;
+
+ /**
+ * @type array
+ */
+ protected $basePathStack = array();
+
+ /**
+ * @param HTMLPurifier_Config $config
+ * @return bool
+ */
+ public function prepare($config)
+ {
+ $def = $config->getDefinition('URI');
+ $this->base = $def->base;
+ if (is_null($this->base)) {
+ trigger_error(
+ 'URI.MakeAbsolute is being ignored due to lack of ' .
+ 'value for URI.Base configuration',
+ E_USER_WARNING
+ );
+ return false;
+ }
+ $this->base->fragment = null; // fragment is invalid for base URI
+ $stack = explode('/', $this->base->path);
+ array_pop($stack); // discard last segment
+ $stack = $this->_collapseStack($stack); // do pre-parsing
+ $this->basePathStack = $stack;
+ return true;
+ }
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function filter(&$uri, $config, $context)
+ {
+ if (is_null($this->base)) {
+ return true;
+ } // abort early
+ if ($uri->path === '' && is_null($uri->scheme) &&
+ is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)) {
+ // reference to current document
+ $uri = clone $this->base;
+ return true;
+ }
+ if (!is_null($uri->scheme)) {
+ // absolute URI already: don't change
+ if (!is_null($uri->host)) {
+ return true;
+ }
+ $scheme_obj = $uri->getSchemeObj($config, $context);
+ if (!$scheme_obj) {
+ // scheme not recognized
+ return false;
+ }
+ if (!$scheme_obj->hierarchical) {
+ // non-hierarchal URI with explicit scheme, don't change
+ return true;
+ }
+ // special case: had a scheme but always is hierarchical and had no authority
+ }
+ if (!is_null($uri->host)) {
+ // network path, don't bother
+ return true;
+ }
+ if ($uri->path === '') {
+ $uri->path = $this->base->path;
+ } elseif ($uri->path[0] !== '/') {
+ // relative path, needs more complicated processing
+ $stack = explode('/', $uri->path);
+ $new_stack = array_merge($this->basePathStack, $stack);
+ if ($new_stack[0] !== '' && !is_null($this->base->host)) {
+ array_unshift($new_stack, '');
+ }
+ $new_stack = $this->_collapseStack($new_stack);
+ $uri->path = implode('/', $new_stack);
+ } else {
+ // absolute path, but still we should collapse
+ $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path)));
+ }
+ // re-combine
+ $uri->scheme = $this->base->scheme;
+ if (is_null($uri->userinfo)) {
+ $uri->userinfo = $this->base->userinfo;
+ }
+ if (is_null($uri->host)) {
+ $uri->host = $this->base->host;
+ }
+ if (is_null($uri->port)) {
+ $uri->port = $this->base->port;
+ }
+ return true;
+ }
+
+ /**
+ * Resolve dots and double-dots in a path stack
+ * @param array $stack
+ * @return array
+ */
+ private function _collapseStack($stack)
+ {
+ $result = array();
+ $is_folder = false;
+ for ($i = 0; isset($stack[$i]); $i++) {
+ $is_folder = false;
+ // absorb an internally duplicated slash
+ if ($stack[$i] == '' && $i && isset($stack[$i + 1])) {
+ continue;
+ }
+ if ($stack[$i] == '..') {
+ if (!empty($result)) {
+ $segment = array_pop($result);
+ if ($segment === '' && empty($result)) {
+ // error case: attempted to back out too far:
+ // restore the leading slash
+ $result[] = '';
+ } elseif ($segment === '..') {
+ $result[] = '..'; // cannot remove .. with ..
+ }
+ } else {
+ // relative path, preserve the double-dots
+ $result[] = '..';
+ }
+ $is_folder = true;
+ continue;
+ }
+ if ($stack[$i] == '.') {
+ // silently absorb
+ $is_folder = true;
+ continue;
+ }
+ $result[] = $stack[$i];
+ }
+ if ($is_folder) {
+ $result[] = '';
+ }
+ return $result;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php
new file mode 100644
index 0000000..6e03315
--- /dev/null
+++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php
@@ -0,0 +1,115 @@
+<?php
+
+class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter
+{
+ /**
+ * @type string
+ */
+ public $name = 'Munge';
+
+ /**
+ * @type bool
+ */
+ public $post = true;
+
+ /**
+ * @type string
+ */
+ private $target;
+
+ /**
+ * @type HTMLPurifier_URIParser
+ */
+ private $parser;
+
+ /**
+ * @type bool
+ */
+ private $doEmbed;
+
+ /**
+ * @type string
+ */
+ private $secretKey;
+
+ /**
+ * @type array
+ */
+ protected $replace = array();
+
+ /**
+ * @param HTMLPurifier_Config $config
+ * @return bool
+ */
+ public function prepare($config)
+ {
+ $this->target = $config->get('URI.' . $this->name);
+ $this->parser = new HTMLPurifier_URIParser();
+ $this->doEmbed = $config->get('URI.MungeResources');
+ $this->secretKey = $config->get('URI.MungeSecretKey');
+ if ($this->secretKey && !function_exists('hash_hmac')) {
+ throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support.");
+ }
+ return true;
+ }
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function filter(&$uri, $config, $context)
+ {
+ if ($context->get('EmbeddedURI', true) && !$this->doEmbed) {
+ return true;
+ }
+
+ $scheme_obj = $uri->getSchemeObj($config, $context);
+ if (!$scheme_obj) {
+ return true;
+ } // ignore unknown schemes, maybe another postfilter did it
+ if (!$scheme_obj->browsable) {
+ return true;
+ } // ignore non-browseable schemes, since we can't munge those in a reasonable way
+ if ($uri->isBenign($config, $context)) {
+ return true;
+ } // don't redirect if a benign URL
+
+ $this->makeReplace($uri, $config, $context);
+ $this->replace = array_map('rawurlencode', $this->replace);
+
+ $new_uri = strtr($this->target, $this->replace);
+ $new_uri = $this->parser->parse($new_uri);
+ // don't redirect if the target host is the same as the
+ // starting host
+ if ($uri->host === $new_uri->host) {
+ return true;
+ }
+ $uri = $new_uri; // overwrite
+ return true;
+ }
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ */
+ protected function makeReplace($uri, $config, $context)
+ {
+ $string = $uri->toString();
+ // always available
+ $this->replace['%s'] = $string;
+ $this->replace['%r'] = $context->get('EmbeddedURI', true);
+ $token = $context->get('CurrentToken', true);
+ $this->replace['%n'] = $token ? $token->name : null;
+ $this->replace['%m'] = $context->get('CurrentAttr', true);
+ $this->replace['%p'] = $context->get('CurrentCSSProperty', true);
+ // not always available
+ if ($this->secretKey) {
+ $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey);
+ }
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/SafeIframe.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/SafeIframe.php
new file mode 100644
index 0000000..f609c47
--- /dev/null
+++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/SafeIframe.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * Implements safety checks for safe iframes.
+ *
+ * @warning This filter is *critical* for ensuring that %HTML.SafeIframe
+ * works safely.
+ */
+class HTMLPurifier_URIFilter_SafeIframe extends HTMLPurifier_URIFilter
+{
+ /**
+ * @type string
+ */
+ public $name = 'SafeIframe';
+
+ /**
+ * @type bool
+ */
+ public $always_load = true;
+
+ /**
+ * @type string
+ */
+ protected $regexp = null;
+
+ // XXX: The not so good bit about how this is all set up now is we
+ // can't check HTML.SafeIframe in the 'prepare' step: we have to
+ // defer till the actual filtering.
+ /**
+ * @param HTMLPurifier_Config $config
+ * @return bool
+ */
+ public function prepare($config)
+ {
+ $this->regexp = $config->get('URI.SafeIframeRegexp');
+ return true;
+ }
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function filter(&$uri, $config, $context)
+ {
+ // check if filter not applicable
+ if (!$config->get('HTML.SafeIframe')) {
+ return true;
+ }
+ // check if the filter should actually trigger
+ if (!$context->get('EmbeddedURI', true)) {
+ return true;
+ }
+ $token = $context->get('CurrentToken', true);
+ if (!($token && $token->name == 'iframe')) {
+ return true;
+ }
+ // check if we actually have some whitelists enabled
+ if ($this->regexp === null) {
+ return false;
+ }
+ // actually check the whitelists
+ return preg_match($this->regexp, $uri->toString());
+ }
+}
+
+// vim: et sw=4 sts=4