summaryrefslogtreecommitdiff
path: root/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI
diff options
context:
space:
mode:
Diffstat (limited to 'lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI')
-rw-r--r--lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email.php17
-rw-r--r--lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php21
-rw-r--r--lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php101
-rw-r--r--lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv4.php39
-rw-r--r--lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv6.php99
5 files changed, 277 insertions, 0 deletions
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email.php
new file mode 100644
index 000000000..bfee9d166
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email.php
@@ -0,0 +1,17 @@
+<?php
+
+abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
+{
+
+ /**
+ * Unpacks a mailbox into its display-name and address
+ */
+ function unpack($string) {
+ // needs to be implemented
+ }
+
+}
+
+// sub-implementations
+
+// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php
new file mode 100644
index 000000000..94c715ab4
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * Primitive email validation class based on the regexp found at
+ * http://www.regular-expressions.info/email.html
+ */
+class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email
+{
+
+ public function validate($string, $config, $context) {
+ // no support for named mailboxes i.e. "Bob <[email protected]>"
+ // that needs more percent encoding to be done
+ if ($string == '') return false;
+ $string = trim($string);
+ $result = preg_match('/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string);
+ return $result ? $string : false;
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php
new file mode 100644
index 000000000..125decb2d
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php
@@ -0,0 +1,101 @@
+<?php
+
+/**
+ * Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
+ */
+class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
+{
+
+ /**
+ * Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator
+ */
+ protected $ipv4;
+
+ /**
+ * Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator
+ */
+ protected $ipv6;
+
+ public function __construct() {
+ $this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
+ $this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
+ }
+
+ public function validate($string, $config, $context) {
+ $length = strlen($string);
+ // empty hostname is OK; it's usually semantically equivalent:
+ // the default host as defined by a URI scheme is used:
+ //
+ // If the URI scheme defines a default for host, then that
+ // default applies when the host subcomponent is undefined
+ // or when the registered name is empty (zero length).
+ if ($string === '') return '';
+ if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
+ //IPv6
+ $ip = substr($string, 1, $length - 2);
+ $valid = $this->ipv6->validate($ip, $config, $context);
+ if ($valid === false) return false;
+ return '['. $valid . ']';
+ }
+
+ // need to do checks on unusual encodings too
+ $ipv4 = $this->ipv4->validate($string, $config, $context);
+ if ($ipv4 !== false) return $ipv4;
+
+ // A regular domain name.
+
+ // This doesn't match I18N domain names, but we don't have proper IRI support,
+ // so force users to insert Punycode.
+
+ // The productions describing this are:
+ $a = '[a-z]'; // alpha
+ $an = '[a-z0-9]'; // alphanum
+ $and = '[a-z0-9-]'; // alphanum | "-"
+ // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
+ $domainlabel = "$an($and*$an)?";
+ // toplabel = alpha | alpha *( alphanum | "-" ) alphanum
+ $toplabel = "$a($and*$an)?";
+ // hostname = *( domainlabel "." ) toplabel [ "." ]
+ if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
+ return $string;
+ }
+
+ // If we have Net_IDNA2 support, we can support IRIs by
+ // punycoding them. (This is the most portable thing to do,
+ // since otherwise we have to assume browsers support
+
+ if ($config->get('Core.EnableIDNA')) {
+ $idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true));
+ // we need to encode each period separately
+ $parts = explode('.', $string);
+ try {
+ $new_parts = array();
+ foreach ($parts as $part) {
+ $encodable = false;
+ for ($i = 0, $c = strlen($part); $i < $c; $i++) {
+ if (ord($part[$i]) > 0x7a) {
+ $encodable = true;
+ break;
+ }
+ }
+ if (!$encodable) {
+ $new_parts[] = $part;
+ } else {
+ $new_parts[] = $idna->encode($part);
+ }
+ }
+ $string = implode('.', $new_parts);
+ if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
+ return $string;
+ }
+ } catch (Exception $e) {
+ // XXX error reporting
+ }
+ }
+
+ return false;
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv4.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv4.php
new file mode 100644
index 000000000..ec4cf591b
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv4.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * Validates an IPv4 address
+ * @author Feyd @ forums.devnetwork.net (public domain)
+ */
+class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef
+{
+
+ /**
+ * IPv4 regex, protected so that IPv6 can reuse it
+ */
+ protected $ip4;
+
+ public function validate($aIP, $config, $context) {
+
+ if (!$this->ip4) $this->_loadRegex();
+
+ if (preg_match('#^' . $this->ip4 . '$#s', $aIP))
+ {
+ return $aIP;
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Lazy load function to prevent regex from being stuffed in
+ * cache.
+ */
+ protected function _loadRegex() {
+ $oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255
+ $this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})";
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv6.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv6.php
new file mode 100644
index 000000000..9454e9be5
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv6.php
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * Validates an IPv6 address.
+ * @author Feyd @ forums.devnetwork.net (public domain)
+ * @note This function requires brackets to have been removed from address
+ * in URI.
+ */
+class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
+{
+
+ public function validate($aIP, $config, $context) {
+
+ if (!$this->ip4) $this->_loadRegex();
+
+ $original = $aIP;
+
+ $hex = '[0-9a-fA-F]';
+ $blk = '(?:' . $hex . '{1,4})';
+ $pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128
+
+ // prefix check
+ if (strpos($aIP, '/') !== false)
+ {
+ if (preg_match('#' . $pre . '$#s', $aIP, $find))
+ {
+ $aIP = substr($aIP, 0, 0-strlen($find[0]));
+ unset($find);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // IPv4-compatiblity check
+ if (preg_match('#(?<=:'.')' . $this->ip4 . '$#s', $aIP, $find))
+ {
+ $aIP = substr($aIP, 0, 0-strlen($find[0]));
+ $ip = explode('.', $find[0]);
+ $ip = array_map('dechex', $ip);
+ $aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3];
+ unset($find, $ip);
+ }
+
+ // compression check
+ $aIP = explode('::', $aIP);
+ $c = count($aIP);
+ if ($c > 2)
+ {
+ return false;
+ }
+ elseif ($c == 2)
+ {
+ list($first, $second) = $aIP;
+ $first = explode(':', $first);
+ $second = explode(':', $second);
+
+ if (count($first) + count($second) > 8)
+ {
+ return false;
+ }
+
+ while(count($first) < 8)
+ {
+ array_push($first, '0');
+ }
+
+ array_splice($first, 8 - count($second), 8, $second);
+ $aIP = $first;
+ unset($first,$second);
+ }
+ else
+ {
+ $aIP = explode(':', $aIP[0]);
+ }
+ $c = count($aIP);
+
+ if ($c != 8)
+ {
+ return false;
+ }
+
+ // All the pieces should be 16-bit hex strings. Are they?
+ foreach ($aIP as $piece)
+ {
+ if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece)))
+ {
+ return false;
+ }
+ }
+
+ return $original;
+
+ }
+
+}
+
+// vim: et sw=4 sts=4