diff options
Diffstat (limited to 'inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter')
7 files changed, 488 insertions, 0 deletions
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableExternal.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableExternal.php new file mode 100644 index 00000000..52e12977 --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableExternal.php | |||
@@ -0,0 +1,54 @@ | |||
1 | <?php | ||
2 | |||
3 | class HTMLPurifier_URIFilter_DisableExternal extends HTMLPurifier_URIFilter | ||
4 | { | ||
5 | /** | ||
6 | * @type string | ||
7 | */ | ||
8 | public $name = 'DisableExternal'; | ||
9 | |||
10 | /** | ||
11 | * @type array | ||
12 | */ | ||
13 | protected $ourHostParts = false; | ||
14 | |||
15 | /** | ||
16 | * @param HTMLPurifier_Config $config | ||
17 | * @return void | ||
18 | */ | ||
19 | public function prepare($config) | ||
20 | { | ||
21 | $our_host = $config->getDefinition('URI')->host; | ||
22 | if ($our_host !== null) { | ||
23 | $this->ourHostParts = array_reverse(explode('.', $our_host)); | ||
24 | } | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * @param HTMLPurifier_URI $uri Reference | ||
29 | * @param HTMLPurifier_Config $config | ||
30 | * @param HTMLPurifier_Context $context | ||
31 | * @return bool | ||
32 | */ | ||
33 | public function filter(&$uri, $config, $context) | ||
34 | { | ||
35 | if (is_null($uri->host)) { | ||
36 | return true; | ||
37 | } | ||
38 | if ($this->ourHostParts === false) { | ||
39 | return false; | ||
40 | } | ||
41 | $host_parts = array_reverse(explode('.', $uri->host)); | ||
42 | foreach ($this->ourHostParts as $i => $x) { | ||
43 | if (!isset($host_parts[$i])) { | ||
44 | return false; | ||
45 | } | ||
46 | if ($host_parts[$i] != $this->ourHostParts[$i]) { | ||
47 | return false; | ||
48 | } | ||
49 | } | ||
50 | return true; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | // vim: et sw=4 sts=4 | ||
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableExternalResources.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableExternalResources.php new file mode 100644 index 00000000..22697d71 --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableExternalResources.php | |||
@@ -0,0 +1,25 @@ | |||
1 | <?php | ||
2 | |||
3 | class HTMLPurifier_URIFilter_DisableExternalResources extends HTMLPurifier_URIFilter_DisableExternal | ||
4 | { | ||
5 | /** | ||
6 | * @type string | ||
7 | */ | ||
8 | public $name = 'DisableExternalResources'; | ||
9 | |||
10 | /** | ||
11 | * @param HTMLPurifier_URI $uri | ||
12 | * @param HTMLPurifier_Config $config | ||
13 | * @param HTMLPurifier_Context $context | ||
14 | * @return bool | ||
15 | */ | ||
16 | public function filter(&$uri, $config, $context) | ||
17 | { | ||
18 | if (!$context->get('EmbeddedURI', true)) { | ||
19 | return true; | ||
20 | } | ||
21 | return parent::filter($uri, $config, $context); | ||
22 | } | ||
23 | } | ||
24 | |||
25 | // vim: et sw=4 sts=4 | ||
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableResources.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableResources.php new file mode 100644 index 00000000..bdae9552 --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/DisableResources.php | |||
@@ -0,0 +1,22 @@ | |||
1 | <?php | ||
2 | |||
3 | class HTMLPurifier_URIFilter_DisableResources extends HTMLPurifier_URIFilter | ||
4 | { | ||
5 | /** | ||
6 | * @type string | ||
7 | */ | ||
8 | public $name = 'DisableResources'; | ||
9 | |||
10 | /** | ||
11 | * @param HTMLPurifier_URI $uri | ||
12 | * @param HTMLPurifier_Config $config | ||
13 | * @param HTMLPurifier_Context $context | ||
14 | * @return bool | ||
15 | */ | ||
16 | public function filter(&$uri, $config, $context) | ||
17 | { | ||
18 | return !$context->get('EmbeddedURI', true); | ||
19 | } | ||
20 | } | ||
21 | |||
22 | // vim: et sw=4 sts=4 | ||
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php new file mode 100644 index 00000000..54980b6e --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php | |||
@@ -0,0 +1,46 @@ | |||
1 | <?php | ||
2 | |||
3 | // It's not clear to me whether or not Punycode means that hostnames | ||
4 | // do not have canonical forms anymore. As far as I can tell, it's | ||
5 | // not a problem (punycoding should be identity when no Unicode | ||
6 | // points are involved), but I'm not 100% sure | ||
7 | class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter | ||
8 | { | ||
9 | /** | ||
10 | * @type string | ||
11 | */ | ||
12 | public $name = 'HostBlacklist'; | ||
13 | |||
14 | /** | ||
15 | * @type array | ||
16 | */ | ||
17 | protected $blacklist = array(); | ||
18 | |||
19 | /** | ||
20 | * @param HTMLPurifier_Config $config | ||
21 | * @return bool | ||
22 | */ | ||
23 | public function prepare($config) | ||
24 | { | ||
25 | $this->blacklist = $config->get('URI.HostBlacklist'); | ||
26 | return true; | ||
27 | } | ||
28 | |||
29 | /** | ||
30 | * @param HTMLPurifier_URI $uri | ||
31 | * @param HTMLPurifier_Config $config | ||
32 | * @param HTMLPurifier_Context $context | ||
33 | * @return bool | ||
34 | */ | ||
35 | public function filter(&$uri, $config, $context) | ||
36 | { | ||
37 | foreach ($this->blacklist as $blacklisted_host_fragment) { | ||
38 | if (strpos($uri->host, $blacklisted_host_fragment) !== false) { | ||
39 | return false; | ||
40 | } | ||
41 | } | ||
42 | return true; | ||
43 | } | ||
44 | } | ||
45 | |||
46 | // vim: et sw=4 sts=4 | ||
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/MakeAbsolute.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/MakeAbsolute.php new file mode 100644 index 00000000..c873bce9 --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/MakeAbsolute.php | |||
@@ -0,0 +1,158 @@ | |||
1 | <?php | ||
2 | |||
3 | // does not support network paths | ||
4 | |||
5 | class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter | ||
6 | { | ||
7 | /** | ||
8 | * @type string | ||
9 | */ | ||
10 | public $name = 'MakeAbsolute'; | ||
11 | |||
12 | /** | ||
13 | * @type | ||
14 | */ | ||
15 | protected $base; | ||
16 | |||
17 | /** | ||
18 | * @type array | ||
19 | */ | ||
20 | protected $basePathStack = array(); | ||
21 | |||
22 | /** | ||
23 | * @param HTMLPurifier_Config $config | ||
24 | * @return bool | ||
25 | */ | ||
26 | public function prepare($config) | ||
27 | { | ||
28 | $def = $config->getDefinition('URI'); | ||
29 | $this->base = $def->base; | ||
30 | if (is_null($this->base)) { | ||
31 | trigger_error( | ||
32 | 'URI.MakeAbsolute is being ignored due to lack of ' . | ||
33 | 'value for URI.Base configuration', | ||
34 | E_USER_WARNING | ||
35 | ); | ||
36 | return false; | ||
37 | } | ||
38 | $this->base->fragment = null; // fragment is invalid for base URI | ||
39 | $stack = explode('/', $this->base->path); | ||
40 | array_pop($stack); // discard last segment | ||
41 | $stack = $this->_collapseStack($stack); // do pre-parsing | ||
42 | $this->basePathStack = $stack; | ||
43 | return true; | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * @param HTMLPurifier_URI $uri | ||
48 | * @param HTMLPurifier_Config $config | ||
49 | * @param HTMLPurifier_Context $context | ||
50 | * @return bool | ||
51 | */ | ||
52 | public function filter(&$uri, $config, $context) | ||
53 | { | ||
54 | if (is_null($this->base)) { | ||
55 | return true; | ||
56 | } // abort early | ||
57 | if ($uri->path === '' && is_null($uri->scheme) && | ||
58 | is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)) { | ||
59 | // reference to current document | ||
60 | $uri = clone $this->base; | ||
61 | return true; | ||
62 | } | ||
63 | if (!is_null($uri->scheme)) { | ||
64 | // absolute URI already: don't change | ||
65 | if (!is_null($uri->host)) { | ||
66 | return true; | ||
67 | } | ||
68 | $scheme_obj = $uri->getSchemeObj($config, $context); | ||
69 | if (!$scheme_obj) { | ||
70 | // scheme not recognized | ||
71 | return false; | ||
72 | } | ||
73 | if (!$scheme_obj->hierarchical) { | ||
74 | // non-hierarchal URI with explicit scheme, don't change | ||
75 | return true; | ||
76 | } | ||
77 | // special case: had a scheme but always is hierarchical and had no authority | ||
78 | } | ||
79 | if (!is_null($uri->host)) { | ||
80 | // network path, don't bother | ||
81 | return true; | ||
82 | } | ||
83 | if ($uri->path === '') { | ||
84 | $uri->path = $this->base->path; | ||
85 | } elseif ($uri->path[0] !== '/') { | ||
86 | // relative path, needs more complicated processing | ||
87 | $stack = explode('/', $uri->path); | ||
88 | $new_stack = array_merge($this->basePathStack, $stack); | ||
89 | if ($new_stack[0] !== '' && !is_null($this->base->host)) { | ||
90 | array_unshift($new_stack, ''); | ||
91 | } | ||
92 | $new_stack = $this->_collapseStack($new_stack); | ||
93 | $uri->path = implode('/', $new_stack); | ||
94 | } else { | ||
95 | // absolute path, but still we should collapse | ||
96 | $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path))); | ||
97 | } | ||
98 | // re-combine | ||
99 | $uri->scheme = $this->base->scheme; | ||
100 | if (is_null($uri->userinfo)) { | ||
101 | $uri->userinfo = $this->base->userinfo; | ||
102 | } | ||
103 | if (is_null($uri->host)) { | ||
104 | $uri->host = $this->base->host; | ||
105 | } | ||
106 | if (is_null($uri->port)) { | ||
107 | $uri->port = $this->base->port; | ||
108 | } | ||
109 | return true; | ||
110 | } | ||
111 | |||
112 | /** | ||
113 | * Resolve dots and double-dots in a path stack | ||
114 | * @param array $stack | ||
115 | * @return array | ||
116 | */ | ||
117 | private function _collapseStack($stack) | ||
118 | { | ||
119 | $result = array(); | ||
120 | $is_folder = false; | ||
121 | for ($i = 0; isset($stack[$i]); $i++) { | ||
122 | $is_folder = false; | ||
123 | // absorb an internally duplicated slash | ||
124 | if ($stack[$i] == '' && $i && isset($stack[$i + 1])) { | ||
125 | continue; | ||
126 | } | ||
127 | if ($stack[$i] == '..') { | ||
128 | if (!empty($result)) { | ||
129 | $segment = array_pop($result); | ||
130 | if ($segment === '' && empty($result)) { | ||
131 | // error case: attempted to back out too far: | ||
132 | // restore the leading slash | ||
133 | $result[] = ''; | ||
134 | } elseif ($segment === '..') { | ||
135 | $result[] = '..'; // cannot remove .. with .. | ||
136 | } | ||
137 | } else { | ||
138 | // relative path, preserve the double-dots | ||
139 | $result[] = '..'; | ||
140 | } | ||
141 | $is_folder = true; | ||
142 | continue; | ||
143 | } | ||
144 | if ($stack[$i] == '.') { | ||
145 | // silently absorb | ||
146 | $is_folder = true; | ||
147 | continue; | ||
148 | } | ||
149 | $result[] = $stack[$i]; | ||
150 | } | ||
151 | if ($is_folder) { | ||
152 | $result[] = ''; | ||
153 | } | ||
154 | return $result; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | // vim: et sw=4 sts=4 | ||
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/Munge.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/Munge.php new file mode 100644 index 00000000..4b4f0cf7 --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/Munge.php | |||
@@ -0,0 +1,115 @@ | |||
1 | <?php | ||
2 | |||
3 | class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter | ||
4 | { | ||
5 | /** | ||
6 | * @type string | ||
7 | */ | ||
8 | public $name = 'Munge'; | ||
9 | |||
10 | /** | ||
11 | * @type bool | ||
12 | */ | ||
13 | public $post = true; | ||
14 | |||
15 | /** | ||
16 | * @type string | ||
17 | */ | ||
18 | private $target; | ||
19 | |||
20 | /** | ||
21 | * @type HTMLPurifier_URIParser | ||
22 | */ | ||
23 | private $parser; | ||
24 | |||
25 | /** | ||
26 | * @type bool | ||
27 | */ | ||
28 | private $doEmbed; | ||
29 | |||
30 | /** | ||
31 | * @type string | ||
32 | */ | ||
33 | private $secretKey; | ||
34 | |||
35 | /** | ||
36 | * @type array | ||
37 | */ | ||
38 | protected $replace = array(); | ||
39 | |||
40 | /** | ||
41 | * @param HTMLPurifier_Config $config | ||
42 | * @return bool | ||
43 | */ | ||
44 | public function prepare($config) | ||
45 | { | ||
46 | $this->target = $config->get('URI.' . $this->name); | ||
47 | $this->parser = new HTMLPurifier_URIParser(); | ||
48 | $this->doEmbed = $config->get('URI.MungeResources'); | ||
49 | $this->secretKey = $config->get('URI.MungeSecretKey'); | ||
50 | if ($this->secretKey && !function_exists('hash_hmac')) { | ||
51 | throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support."); | ||
52 | } | ||
53 | return true; | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * @param HTMLPurifier_URI $uri | ||
58 | * @param HTMLPurifier_Config $config | ||
59 | * @param HTMLPurifier_Context $context | ||
60 | * @return bool | ||
61 | */ | ||
62 | public function filter(&$uri, $config, $context) | ||
63 | { | ||
64 | if ($context->get('EmbeddedURI', true) && !$this->doEmbed) { | ||
65 | return true; | ||
66 | } | ||
67 | |||
68 | $scheme_obj = $uri->getSchemeObj($config, $context); | ||
69 | if (!$scheme_obj) { | ||
70 | return true; | ||
71 | } // ignore unknown schemes, maybe another postfilter did it | ||
72 | if (!$scheme_obj->browsable) { | ||
73 | return true; | ||
74 | } // ignore non-browseable schemes, since we can't munge those in a reasonable way | ||
75 | if ($uri->isBenign($config, $context)) { | ||
76 | return true; | ||
77 | } // don't redirect if a benign URL | ||
78 | |||
79 | $this->makeReplace($uri, $config, $context); | ||
80 | $this->replace = array_map('rawurlencode', $this->replace); | ||
81 | |||
82 | $new_uri = strtr($this->target, $this->replace); | ||
83 | $new_uri = $this->parser->parse($new_uri); | ||
84 | // don't redirect if the target host is the same as the | ||
85 | // starting host | ||
86 | if ($uri->host === $new_uri->host) { | ||
87 | return true; | ||
88 | } | ||
89 | $uri = $new_uri; // overwrite | ||
90 | return true; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * @param HTMLPurifier_URI $uri | ||
95 | * @param HTMLPurifier_Config $config | ||
96 | * @param HTMLPurifier_Context $context | ||
97 | */ | ||
98 | protected function makeReplace($uri, $config, $context) | ||
99 | { | ||
100 | $string = $uri->toString(); | ||
101 | // always available | ||
102 | $this->replace['%s'] = $string; | ||
103 | $this->replace['%r'] = $context->get('EmbeddedURI', true); | ||
104 | $token = $context->get('CurrentToken', true); | ||
105 | $this->replace['%n'] = $token ? $token->name : null; | ||
106 | $this->replace['%m'] = $context->get('CurrentAttr', true); | ||
107 | $this->replace['%p'] = $context->get('CurrentCSSProperty', true); | ||
108 | // not always available | ||
109 | if ($this->secretKey) { | ||
110 | $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | // vim: et sw=4 sts=4 | ||
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/SafeIframe.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/SafeIframe.php new file mode 100644 index 00000000..5ecb9567 --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/URIFilter/SafeIframe.php | |||
@@ -0,0 +1,68 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Implements safety checks for safe iframes. | ||
5 | * | ||
6 | * @warning This filter is *critical* for ensuring that %HTML.SafeIframe | ||
7 | * works safely. | ||
8 | */ | ||
9 | class HTMLPurifier_URIFilter_SafeIframe extends HTMLPurifier_URIFilter | ||
10 | { | ||
11 | /** | ||
12 | * @type string | ||
13 | */ | ||
14 | public $name = 'SafeIframe'; | ||
15 | |||
16 | /** | ||
17 | * @type bool | ||
18 | */ | ||
19 | public $always_load = true; | ||
20 | |||
21 | /** | ||
22 | * @type string | ||
23 | */ | ||
24 | protected $regexp = null; | ||
25 | |||
26 | // XXX: The not so good bit about how this is all set up now is we | ||
27 | // can't check HTML.SafeIframe in the 'prepare' step: we have to | ||
28 | // defer till the actual filtering. | ||
29 | /** | ||
30 | * @param HTMLPurifier_Config $config | ||
31 | * @return bool | ||
32 | */ | ||
33 | public function prepare($config) | ||
34 | { | ||
35 | $this->regexp = $config->get('URI.SafeIframeRegexp'); | ||
36 | return true; | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * @param HTMLPurifier_URI $uri | ||
41 | * @param HTMLPurifier_Config $config | ||
42 | * @param HTMLPurifier_Context $context | ||
43 | * @return bool | ||
44 | */ | ||
45 | public function filter(&$uri, $config, $context) | ||
46 | { | ||
47 | // check if filter not applicable | ||
48 | if (!$config->get('HTML.SafeIframe')) { | ||
49 | return true; | ||
50 | } | ||
51 | // check if the filter should actually trigger | ||
52 | if (!$context->get('EmbeddedURI', true)) { | ||
53 | return true; | ||
54 | } | ||
55 | $token = $context->get('CurrentToken', true); | ||
56 | if (!($token && $token->name == 'iframe')) { | ||
57 | return true; | ||
58 | } | ||
59 | // check if we actually have some whitelists enabled | ||
60 | if ($this->regexp === null) { | ||
61 | return false; | ||
62 | } | ||
63 | // actually check the whitelists | ||
64 | return preg_match($this->regexp, $uri->toString()); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | // vim: et sw=4 sts=4 | ||