summaryrefslogtreecommitdiffstats
path: root/library/vendor/HTMLPurifier/URIScheme
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/vendor/HTMLPurifier/URIScheme.php102
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/data.php136
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/file.php44
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/ftp.php58
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/http.php36
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/https.php18
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/mailto.php40
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/news.php35
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/nntp.php32
-rw-r--r--library/vendor/HTMLPurifier/URIScheme/tel.php46
-rw-r--r--library/vendor/HTMLPurifier/URISchemeRegistry.php81
11 files changed, 628 insertions, 0 deletions
diff --git a/library/vendor/HTMLPurifier/URIScheme.php b/library/vendor/HTMLPurifier/URIScheme.php
new file mode 100644
index 0000000..fe9e82c
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * Validator for the components of a URI for a specific scheme
+ */
+abstract class HTMLPurifier_URIScheme
+{
+
+ /**
+ * Scheme's default port (integer). If an explicit port number is
+ * specified that coincides with the default port, it will be
+ * elided.
+ * @type int
+ */
+ public $default_port = null;
+
+ /**
+ * Whether or not URIs of this scheme are locatable by a browser
+ * http and ftp are accessible, while mailto and news are not.
+ * @type bool
+ */
+ public $browsable = false;
+
+ /**
+ * Whether or not data transmitted over this scheme is encrypted.
+ * https is secure, http is not.
+ * @type bool
+ */
+ public $secure = false;
+
+ /**
+ * Whether or not the URI always uses <hier_part>, resolves edge cases
+ * with making relative URIs absolute
+ * @type bool
+ */
+ public $hierarchical = false;
+
+ /**
+ * 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.
+ * @type bool
+ */
+ public $may_omit_host = false;
+
+ /**
+ * Validates the components of a URI for a specific scheme.
+ * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool success or failure
+ */
+ abstract public 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 HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool success or failure
+ */
+ public function validate(&$uri, $config, $context)
+ {
+ if ($this->default_port == $uri->port) {
+ $uri->port = null;
+ }
+ // 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);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/data.php b/library/vendor/HTMLPurifier/URIScheme/data.php
new file mode 100644
index 0000000..41c49d5
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/data.php
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * Implements data: URI for base64 encoded images supported by GD.
+ */
+class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme
+{
+ /**
+ * @type bool
+ */
+ public $browsable = true;
+
+ /**
+ * @type array
+ */
+ public $allowed_types = array(
+ // you better write validation code for other types if you
+ // decide to allow them
+ 'image/jpeg' => true,
+ 'image/gif' => true,
+ 'image/png' => true,
+ );
+ // this is actually irrelevant since we only write out the path
+ // component
+ /**
+ * @type bool
+ */
+ public $may_omit_host = true;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ $result = explode(',', $uri->path, 2);
+ $is_base64 = false;
+ $charset = null;
+ $content_type = null;
+ if (count($result) == 2) {
+ list($metadata, $data) = $result;
+ // do some legwork on the metadata
+ $metas = explode(';', $metadata);
+ while (!empty($metas)) {
+ $cur = array_shift($metas);
+ if ($cur == 'base64') {
+ $is_base64 = true;
+ break;
+ }
+ if (substr($cur, 0, 8) == 'charset=') {
+ // doesn't match if there are arbitrary spaces, but
+ // whatever dude
+ if ($charset !== null) {
+ continue;
+ } // garbage
+ $charset = substr($cur, 8); // not used
+ } else {
+ if ($content_type !== null) {
+ continue;
+ } // garbage
+ $content_type = $cur;
+ }
+ }
+ } else {
+ $data = $result[0];
+ }
+ if ($content_type !== null && empty($this->allowed_types[$content_type])) {
+ return false;
+ }
+ if ($charset !== null) {
+ // error; we don't allow plaintext stuff
+ $charset = null;
+ }
+ $data = rawurldecode($data);
+ if ($is_base64) {
+ $raw_data = base64_decode($data);
+ } else {
+ $raw_data = $data;
+ }
+ if ( strlen($raw_data) < 12 ) {
+ // error; exif_imagetype throws exception with small files,
+ // and this likely indicates a corrupt URI/failed parse anyway
+ return false;
+ }
+ // XXX probably want to refactor this into a general mechanism
+ // for filtering arbitrary content types
+ if (function_exists('sys_get_temp_dir')) {
+ $file = tempnam(sys_get_temp_dir(), "");
+ } else {
+ $file = tempnam("/tmp", "");
+ }
+ file_put_contents($file, $raw_data);
+ if (function_exists('exif_imagetype')) {
+ $image_code = exif_imagetype($file);
+ unlink($file);
+ } elseif (function_exists('getimagesize')) {
+ set_error_handler(array($this, 'muteErrorHandler'));
+ $info = getimagesize($file);
+ restore_error_handler();
+ unlink($file);
+ if ($info == false) {
+ return false;
+ }
+ $image_code = $info[2];
+ } else {
+ trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR);
+ }
+ $real_content_type = image_type_to_mime_type($image_code);
+ if ($real_content_type != $content_type) {
+ // we're nice guys; if the content type is something else we
+ // support, change it over
+ if (empty($this->allowed_types[$real_content_type])) {
+ return false;
+ }
+ $content_type = $real_content_type;
+ }
+ // ok, it's kosher, rewrite what we need
+ $uri->userinfo = null;
+ $uri->host = null;
+ $uri->port = null;
+ $uri->fragment = null;
+ $uri->query = null;
+ $uri->path = "$content_type;base64," . base64_encode($raw_data);
+ return true;
+ }
+
+ /**
+ * @param int $errno
+ * @param string $errstr
+ */
+ public function muteErrorHandler($errno, $errstr)
+ {
+ }
+}
diff --git a/library/vendor/HTMLPurifier/URIScheme/file.php b/library/vendor/HTMLPurifier/URIScheme/file.php
new file mode 100644
index 0000000..215be4b
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/file.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * Validates file as defined by RFC 1630 and RFC 1738.
+ */
+class HTMLPurifier_URIScheme_file extends HTMLPurifier_URIScheme
+{
+ /**
+ * Generally file:// URLs are not accessible from most
+ * machines, so placing them as an img src is incorrect.
+ * @type bool
+ */
+ public $browsable = false;
+
+ /**
+ * Basically the *only* URI scheme for which this is true, since
+ * accessing files on the local machine is very common. In fact,
+ * browsers on some operating systems don't understand the
+ * authority, though I hear it is used on Windows to refer to
+ * network shares.
+ * @type bool
+ */
+ public $may_omit_host = true;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ // Authentication method is not supported
+ $uri->userinfo = null;
+ // file:// makes no provisions for accessing the resource
+ $uri->port = null;
+ // While it seems to work on Firefox, the querystring has
+ // no possible effect and is thus stripped.
+ $uri->query = null;
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/ftp.php b/library/vendor/HTMLPurifier/URIScheme/ftp.php
new file mode 100644
index 0000000..1eb43ee
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/ftp.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * Validates ftp (File Transfer Protocol) URIs as defined by generic RFC 1738.
+ */
+class HTMLPurifier_URIScheme_ftp extends HTMLPurifier_URIScheme
+{
+ /**
+ * @type int
+ */
+ public $default_port = 21;
+
+ /**
+ * @type bool
+ */
+ public $browsable = true; // usually
+
+ /**
+ * @type bool
+ */
+ public $hierarchical = true;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ $uri->query = null;
+
+ // typecode check
+ $semicolon_pos = strrpos($uri->path, ';'); // reverse
+ if ($semicolon_pos !== false) {
+ $type = substr($uri->path, $semicolon_pos + 1); // no semicolon
+ $uri->path = substr($uri->path, 0, $semicolon_pos);
+ $type_ret = '';
+ if (strpos($type, '=') !== false) {
+ // figure out whether or not the declaration is correct
+ list($key, $typecode) = explode('=', $type, 2);
+ if ($key !== 'type') {
+ // invalid key, tack it back on encoded
+ $uri->path .= '%3B' . $type;
+ } elseif ($typecode === 'a' || $typecode === 'i' || $typecode === 'd') {
+ $type_ret = ";type=$typecode";
+ }
+ } else {
+ $uri->path .= '%3B' . $type;
+ }
+ $uri->path = str_replace(';', '%3B', $uri->path);
+ $uri->path .= $type_ret;
+ }
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/http.php b/library/vendor/HTMLPurifier/URIScheme/http.php
new file mode 100644
index 0000000..ce69ec4
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/http.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * Validates http (HyperText Transfer Protocol) as defined by RFC 2616
+ */
+class HTMLPurifier_URIScheme_http extends HTMLPurifier_URIScheme
+{
+ /**
+ * @type int
+ */
+ public $default_port = 80;
+
+ /**
+ * @type bool
+ */
+ public $browsable = true;
+
+ /**
+ * @type bool
+ */
+ public $hierarchical = true;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ $uri->userinfo = null;
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/https.php b/library/vendor/HTMLPurifier/URIScheme/https.php
new file mode 100644
index 0000000..0e96882
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/https.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * Validates https (Secure HTTP) according to http scheme.
+ */
+class HTMLPurifier_URIScheme_https extends HTMLPurifier_URIScheme_http
+{
+ /**
+ * @type int
+ */
+ public $default_port = 443;
+ /**
+ * @type bool
+ */
+ public $secure = true;
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/mailto.php b/library/vendor/HTMLPurifier/URIScheme/mailto.php
new file mode 100644
index 0000000..c3a6b60
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/mailto.php
@@ -0,0 +1,40 @@
+<?php
+
+// VERY RELAXED! Shouldn't cause problems, not even Firefox checks if the
+// email is valid, but be careful!
+
+/**
+ * Validates mailto (for E-mail) according to RFC 2368
+ * @todo Validate the email address
+ * @todo Filter allowed query parameters
+ */
+
+class HTMLPurifier_URIScheme_mailto extends HTMLPurifier_URIScheme
+{
+ /**
+ * @type bool
+ */
+ public $browsable = false;
+
+ /**
+ * @type bool
+ */
+ public $may_omit_host = true;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ $uri->userinfo = null;
+ $uri->host = null;
+ $uri->port = null;
+ // we need to validate path against RFC 2368's addr-spec
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/news.php b/library/vendor/HTMLPurifier/URIScheme/news.php
new file mode 100644
index 0000000..7490927
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/news.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * Validates news (Usenet) as defined by generic RFC 1738
+ */
+class HTMLPurifier_URIScheme_news extends HTMLPurifier_URIScheme
+{
+ /**
+ * @type bool
+ */
+ public $browsable = false;
+
+ /**
+ * @type bool
+ */
+ public $may_omit_host = true;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ $uri->userinfo = null;
+ $uri->host = null;
+ $uri->port = null;
+ $uri->query = null;
+ // typecode check needed on path
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/nntp.php b/library/vendor/HTMLPurifier/URIScheme/nntp.php
new file mode 100644
index 0000000..f211d71
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/nntp.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * Validates nntp (Network News Transfer Protocol) as defined by generic RFC 1738
+ */
+class HTMLPurifier_URIScheme_nntp extends HTMLPurifier_URIScheme
+{
+ /**
+ * @type int
+ */
+ public $default_port = 119;
+
+ /**
+ * @type bool
+ */
+ public $browsable = false;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ $uri->userinfo = null;
+ $uri->query = null;
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URIScheme/tel.php b/library/vendor/HTMLPurifier/URIScheme/tel.php
new file mode 100644
index 0000000..8cd1933
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URIScheme/tel.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * Validates tel (for phone numbers).
+ *
+ * The relevant specifications for this protocol are RFC 3966 and RFC 5341,
+ * but this class takes a much simpler approach: we normalize phone
+ * numbers so that they only include (possibly) a leading plus,
+ * and then any number of digits and x'es.
+ */
+
+class HTMLPurifier_URIScheme_tel extends HTMLPurifier_URIScheme
+{
+ /**
+ * @type bool
+ */
+ public $browsable = false;
+
+ /**
+ * @type bool
+ */
+ public $may_omit_host = true;
+
+ /**
+ * @param HTMLPurifier_URI $uri
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return bool
+ */
+ public function doValidate(&$uri, $config, $context)
+ {
+ $uri->userinfo = null;
+ $uri->host = null;
+ $uri->port = null;
+
+ // Delete all non-numeric characters, non-x characters
+ // from phone number, EXCEPT for a leading plus sign.
+ $uri->path = preg_replace('/(?!^\+)[^\dx]/', '',
+ // Normalize e(x)tension to lower-case
+ str_replace('X', 'x', $uri->path));
+
+ return true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/URISchemeRegistry.php b/library/vendor/HTMLPurifier/URISchemeRegistry.php
new file mode 100644
index 0000000..4ac8a0b
--- /dev/null
+++ b/library/vendor/HTMLPurifier/URISchemeRegistry.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Registry for retrieving specific URI scheme validator objects.
+ */
+class HTMLPurifier_URISchemeRegistry
+{
+
+ /**
+ * Retrieve sole instance of the registry.
+ * @param HTMLPurifier_URISchemeRegistry $prototype Optional prototype to overload sole instance with,
+ * or bool true to reset to default registry.
+ * @return HTMLPurifier_URISchemeRegistry
+ * @note Pass a registry object $prototype with a compatible interface and
+ * the function will copy it and return it all further times.
+ */
+ public static function instance($prototype = null)
+ {
+ static $instance = null;
+ if ($prototype !== null) {
+ $instance = $prototype;
+ } elseif ($instance === null || $prototype == true) {
+ $instance = new HTMLPurifier_URISchemeRegistry();
+ }
+ return $instance;
+ }
+
+ /**
+ * Cache of retrieved schemes.
+ * @type HTMLPurifier_URIScheme[]
+ */
+ protected $schemes = array();
+
+ /**
+ * Retrieves a scheme validator object
+ * @param string $scheme String scheme name like http or mailto
+ * @param HTMLPurifier_Config $config
+ * @param HTMLPurifier_Context $context
+ * @return HTMLPurifier_URIScheme
+ */
+ public function getScheme($scheme, $config, $context)
+ {
+ if (!$config) {
+ $config = HTMLPurifier_Config::createDefault();
+ }
+
+ // important, otherwise attacker could include arbitrary file
+ $allowed_schemes = $config->get('URI.AllowedSchemes');
+ if (!$config->get('URI.OverrideAllowedSchemes') &&
+ !isset($allowed_schemes[$scheme])
+ ) {
+ return;
+ }
+
+ if (isset($this->schemes[$scheme])) {
+ return $this->schemes[$scheme];
+ }
+ if (!isset($allowed_schemes[$scheme])) {
+ return;
+ }
+
+ $class = 'HTMLPurifier_URIScheme_' . $scheme;
+ if (!class_exists($class)) {
+ return;
+ }
+ $this->schemes[$scheme] = new $class();
+ return $this->schemes[$scheme];
+ }
+
+ /**
+ * Registers a custom scheme to the cache, bypassing reflection.
+ * @param string $scheme Scheme name
+ * @param HTMLPurifier_URIScheme $scheme_obj
+ */
+ public function register($scheme, $scheme_obj)
+ {
+ $this->schemes[$scheme] = $scheme_obj;
+ }
+}
+
+// vim: et sw=4 sts=4