@@ -3,99 +3,99 @@ |
||
3 | 3 | class HTMLPurifier_URIDefinition extends HTMLPurifier_Definition |
4 | 4 | { |
5 | 5 | |
6 | - public $type = 'URI'; |
|
7 | - protected $filters = array(); |
|
8 | - protected $postFilters = array(); |
|
9 | - protected $registeredFilters = array(); |
|
10 | - |
|
11 | - /** |
|
12 | - * HTMLPurifier_URI object of the base specified at %URI.Base |
|
13 | - */ |
|
14 | - public $base; |
|
15 | - |
|
16 | - /** |
|
17 | - * String host to consider "home" base, derived off of $base |
|
18 | - */ |
|
19 | - public $host; |
|
20 | - |
|
21 | - /** |
|
22 | - * Name of default scheme based on %URI.DefaultScheme and %URI.Base |
|
23 | - */ |
|
24 | - public $defaultScheme; |
|
25 | - |
|
26 | - public function __construct() { |
|
27 | - $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternal()); |
|
28 | - $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources()); |
|
29 | - $this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist()); |
|
30 | - $this->registerFilter(new HTMLPurifier_URIFilter_SafeIframe()); |
|
31 | - $this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute()); |
|
32 | - $this->registerFilter(new HTMLPurifier_URIFilter_Munge()); |
|
33 | - } |
|
34 | - |
|
35 | - public function registerFilter($filter) { |
|
36 | - $this->registeredFilters[$filter->name] = $filter; |
|
37 | - } |
|
38 | - |
|
39 | - public function addFilter($filter, $config) { |
|
40 | - $r = $filter->prepare($config); |
|
41 | - if ($r === false) return; // null is ok, for backwards compat |
|
42 | - if ($filter->post) { |
|
43 | - $this->postFilters[$filter->name] = $filter; |
|
44 | - } else { |
|
45 | - $this->filters[$filter->name] = $filter; |
|
46 | - } |
|
47 | - } |
|
48 | - |
|
49 | - protected function doSetup($config) { |
|
50 | - $this->setupMemberVariables($config); |
|
51 | - $this->setupFilters($config); |
|
52 | - } |
|
53 | - |
|
54 | - protected function setupFilters($config) { |
|
55 | - foreach ($this->registeredFilters as $name => $filter) { |
|
56 | - if ($filter->always_load) { |
|
57 | - $this->addFilter($filter, $config); |
|
58 | - } else { |
|
59 | - $conf = $config->get('URI.' . $name); |
|
60 | - if ($conf !== false && $conf !== null) { |
|
61 | - $this->addFilter($filter, $config); |
|
62 | - } |
|
63 | - } |
|
64 | - } |
|
65 | - unset($this->registeredFilters); |
|
66 | - } |
|
67 | - |
|
68 | - protected function setupMemberVariables($config) { |
|
69 | - $this->host = $config->get('URI.Host'); |
|
70 | - $base_uri = $config->get('URI.Base'); |
|
71 | - if (!is_null($base_uri)) { |
|
72 | - $parser = new HTMLPurifier_URIParser(); |
|
73 | - $this->base = $parser->parse($base_uri); |
|
74 | - $this->defaultScheme = $this->base->scheme; |
|
75 | - if (is_null($this->host)) $this->host = $this->base->host; |
|
76 | - } |
|
77 | - if (is_null($this->defaultScheme)) $this->defaultScheme = $config->get('URI.DefaultScheme'); |
|
78 | - } |
|
79 | - |
|
80 | - public function getDefaultScheme($config, $context) { |
|
81 | - return HTMLPurifier_URISchemeRegistry::instance()->getScheme($this->defaultScheme, $config, $context); |
|
82 | - } |
|
83 | - |
|
84 | - public function filter(&$uri, $config, $context) { |
|
85 | - foreach ($this->filters as $name => $f) { |
|
86 | - $result = $f->filter($uri, $config, $context); |
|
87 | - if (!$result) return false; |
|
88 | - } |
|
89 | - return true; |
|
90 | - } |
|
91 | - |
|
92 | - public function postFilter(&$uri, $config, $context) { |
|
93 | - foreach ($this->postFilters as $name => $f) { |
|
94 | - $result = $f->filter($uri, $config, $context); |
|
95 | - if (!$result) return false; |
|
96 | - } |
|
97 | - return true; |
|
98 | - } |
|
6 | + public $type = 'URI'; |
|
7 | + protected $filters = array(); |
|
8 | + protected $postFilters = array(); |
|
9 | + protected $registeredFilters = array(); |
|
10 | + |
|
11 | + /** |
|
12 | + * HTMLPurifier_URI object of the base specified at %URI.Base |
|
13 | + */ |
|
14 | + public $base; |
|
15 | + |
|
16 | + /** |
|
17 | + * String host to consider "home" base, derived off of $base |
|
18 | + */ |
|
19 | + public $host; |
|
20 | + |
|
21 | + /** |
|
22 | + * Name of default scheme based on %URI.DefaultScheme and %URI.Base |
|
23 | + */ |
|
24 | + public $defaultScheme; |
|
25 | + |
|
26 | + public function __construct() { |
|
27 | + $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternal()); |
|
28 | + $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources()); |
|
29 | + $this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist()); |
|
30 | + $this->registerFilter(new HTMLPurifier_URIFilter_SafeIframe()); |
|
31 | + $this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute()); |
|
32 | + $this->registerFilter(new HTMLPurifier_URIFilter_Munge()); |
|
33 | + } |
|
34 | + |
|
35 | + public function registerFilter($filter) { |
|
36 | + $this->registeredFilters[$filter->name] = $filter; |
|
37 | + } |
|
38 | + |
|
39 | + public function addFilter($filter, $config) { |
|
40 | + $r = $filter->prepare($config); |
|
41 | + if ($r === false) return; // null is ok, for backwards compat |
|
42 | + if ($filter->post) { |
|
43 | + $this->postFilters[$filter->name] = $filter; |
|
44 | + } else { |
|
45 | + $this->filters[$filter->name] = $filter; |
|
46 | + } |
|
47 | + } |
|
48 | + |
|
49 | + protected function doSetup($config) { |
|
50 | + $this->setupMemberVariables($config); |
|
51 | + $this->setupFilters($config); |
|
52 | + } |
|
53 | + |
|
54 | + protected function setupFilters($config) { |
|
55 | + foreach ($this->registeredFilters as $name => $filter) { |
|
56 | + if ($filter->always_load) { |
|
57 | + $this->addFilter($filter, $config); |
|
58 | + } else { |
|
59 | + $conf = $config->get('URI.' . $name); |
|
60 | + if ($conf !== false && $conf !== null) { |
|
61 | + $this->addFilter($filter, $config); |
|
62 | + } |
|
63 | + } |
|
64 | + } |
|
65 | + unset($this->registeredFilters); |
|
66 | + } |
|
67 | + |
|
68 | + protected function setupMemberVariables($config) { |
|
69 | + $this->host = $config->get('URI.Host'); |
|
70 | + $base_uri = $config->get('URI.Base'); |
|
71 | + if (!is_null($base_uri)) { |
|
72 | + $parser = new HTMLPurifier_URIParser(); |
|
73 | + $this->base = $parser->parse($base_uri); |
|
74 | + $this->defaultScheme = $this->base->scheme; |
|
75 | + if (is_null($this->host)) $this->host = $this->base->host; |
|
76 | + } |
|
77 | + if (is_null($this->defaultScheme)) $this->defaultScheme = $config->get('URI.DefaultScheme'); |
|
78 | + } |
|
79 | + |
|
80 | + public function getDefaultScheme($config, $context) { |
|
81 | + return HTMLPurifier_URISchemeRegistry::instance()->getScheme($this->defaultScheme, $config, $context); |
|
82 | + } |
|
83 | + |
|
84 | + public function filter(&$uri, $config, $context) { |
|
85 | + foreach ($this->filters as $name => $f) { |
|
86 | + $result = $f->filter($uri, $config, $context); |
|
87 | + if (!$result) return false; |
|
88 | + } |
|
89 | + return true; |
|
90 | + } |
|
91 | + |
|
92 | + public function postFilter(&$uri, $config, $context) { |
|
93 | + foreach ($this->postFilters as $name => $f) { |
|
94 | + $result = $f->filter($uri, $config, $context); |
|
95 | + if (!$result) return false; |
|
96 | + } |
|
97 | + return true; |
|
98 | + } |
|
99 | 99 | |
100 | 100 | } |
101 | 101 |
@@ -38,7 +38,10 @@ discard block |
||
38 | 38 | |
39 | 39 | public function addFilter($filter, $config) { |
40 | 40 | $r = $filter->prepare($config); |
41 | - if ($r === false) return; // null is ok, for backwards compat |
|
41 | + if ($r === false) { |
|
42 | + return; |
|
43 | + } |
|
44 | + // null is ok, for backwards compat |
|
42 | 45 | if ($filter->post) { |
43 | 46 | $this->postFilters[$filter->name] = $filter; |
44 | 47 | } else { |
@@ -72,9 +75,13 @@ discard block |
||
72 | 75 | $parser = new HTMLPurifier_URIParser(); |
73 | 76 | $this->base = $parser->parse($base_uri); |
74 | 77 | $this->defaultScheme = $this->base->scheme; |
75 | - if (is_null($this->host)) $this->host = $this->base->host; |
|
78 | + if (is_null($this->host)) { |
|
79 | + $this->host = $this->base->host; |
|
80 | + } |
|
81 | + } |
|
82 | + if (is_null($this->defaultScheme)) { |
|
83 | + $this->defaultScheme = $config->get('URI.DefaultScheme'); |
|
76 | 84 | } |
77 | - if (is_null($this->defaultScheme)) $this->defaultScheme = $config->get('URI.DefaultScheme'); |
|
78 | 85 | } |
79 | 86 | |
80 | 87 | public function getDefaultScheme($config, $context) { |
@@ -84,7 +91,9 @@ discard block |
||
84 | 91 | public function filter(&$uri, $config, $context) { |
85 | 92 | foreach ($this->filters as $name => $f) { |
86 | 93 | $result = $f->filter($uri, $config, $context); |
87 | - if (!$result) return false; |
|
94 | + if (!$result) { |
|
95 | + return false; |
|
96 | + } |
|
88 | 97 | } |
89 | 98 | return true; |
90 | 99 | } |
@@ -92,7 +101,9 @@ discard block |
||
92 | 101 | public function postFilter(&$uri, $config, $context) { |
93 | 102 | foreach ($this->postFilters as $name => $f) { |
94 | 103 | $result = $f->filter($uri, $config, $context); |
95 | - if (!$result) return false; |
|
104 | + if (!$result) { |
|
105 | + return false; |
|
106 | + } |
|
96 | 107 | } |
97 | 108 | return true; |
98 | 109 | } |
@@ -28,39 +28,39 @@ |
||
28 | 28 | abstract class HTMLPurifier_URIFilter |
29 | 29 | { |
30 | 30 | |
31 | - /** |
|
32 | - * Unique identifier of filter |
|
33 | - */ |
|
34 | - public $name; |
|
31 | + /** |
|
32 | + * Unique identifier of filter |
|
33 | + */ |
|
34 | + public $name; |
|
35 | 35 | |
36 | - /** |
|
37 | - * True if this filter should be run after scheme validation. |
|
38 | - */ |
|
39 | - public $post = false; |
|
36 | + /** |
|
37 | + * True if this filter should be run after scheme validation. |
|
38 | + */ |
|
39 | + public $post = false; |
|
40 | 40 | |
41 | - /** |
|
42 | - * True if this filter should always be loaded (this permits |
|
43 | - * a filter to be named Foo without the corresponding %URI.Foo |
|
44 | - * directive existing.) |
|
45 | - */ |
|
46 | - public $always_load = false; |
|
41 | + /** |
|
42 | + * True if this filter should always be loaded (this permits |
|
43 | + * a filter to be named Foo without the corresponding %URI.Foo |
|
44 | + * directive existing.) |
|
45 | + */ |
|
46 | + public $always_load = false; |
|
47 | 47 | |
48 | - /** |
|
49 | - * Performs initialization for the filter. If the filter returns |
|
50 | - * false, this means that it shouldn't be considered active. |
|
51 | - */ |
|
52 | - public function prepare($config) {return true;} |
|
48 | + /** |
|
49 | + * Performs initialization for the filter. If the filter returns |
|
50 | + * false, this means that it shouldn't be considered active. |
|
51 | + */ |
|
52 | + public function prepare($config) {return true;} |
|
53 | 53 | |
54 | - /** |
|
55 | - * Filter a URI object |
|
56 | - * @param $uri Reference to URI object variable |
|
57 | - * @param $config Instance of HTMLPurifier_Config |
|
58 | - * @param $context Instance of HTMLPurifier_Context |
|
59 | - * @return bool Whether or not to continue processing: false indicates |
|
60 | - * URL is no good, true indicates continue processing. Note that |
|
61 | - * all changes are committed directly on the URI object |
|
62 | - */ |
|
63 | - abstract public function filter(&$uri, $config, $context); |
|
54 | + /** |
|
55 | + * Filter a URI object |
|
56 | + * @param $uri Reference to URI object variable |
|
57 | + * @param $config Instance of HTMLPurifier_Config |
|
58 | + * @param $context Instance of HTMLPurifier_Context |
|
59 | + * @return bool Whether or not to continue processing: false indicates |
|
60 | + * URL is no good, true indicates continue processing. Note that |
|
61 | + * all changes are committed directly on the URI object |
|
62 | + */ |
|
63 | + abstract public function filter(&$uri, $config, $context); |
|
64 | 64 | |
65 | 65 | } |
66 | 66 |
@@ -49,7 +49,7 @@ |
||
49 | 49 | * Performs initialization for the filter. If the filter returns |
50 | 50 | * false, this means that it shouldn't be considered active. |
51 | 51 | */ |
52 | - public function prepare($config) {return true;} |
|
52 | + public function prepare($config) {return true; } |
|
53 | 53 | |
54 | 54 | /** |
55 | 55 | * Filter a URI object |
@@ -2,22 +2,22 @@ |
||
2 | 2 | |
3 | 3 | class HTMLPurifier_URIFilter_DisableExternal extends HTMLPurifier_URIFilter |
4 | 4 | { |
5 | - public $name = 'DisableExternal'; |
|
6 | - protected $ourHostParts = false; |
|
7 | - public function prepare($config) { |
|
8 | - $our_host = $config->getDefinition('URI')->host; |
|
9 | - if ($our_host !== null) $this->ourHostParts = array_reverse(explode('.', $our_host)); |
|
10 | - } |
|
11 | - public function filter(&$uri, $config, $context) { |
|
12 | - if (is_null($uri->host)) return true; |
|
13 | - if ($this->ourHostParts === false) return false; |
|
14 | - $host_parts = array_reverse(explode('.', $uri->host)); |
|
15 | - foreach ($this->ourHostParts as $i => $x) { |
|
16 | - if (!isset($host_parts[$i])) return false; |
|
17 | - if ($host_parts[$i] != $this->ourHostParts[$i]) return false; |
|
18 | - } |
|
19 | - return true; |
|
20 | - } |
|
5 | + public $name = 'DisableExternal'; |
|
6 | + protected $ourHostParts = false; |
|
7 | + public function prepare($config) { |
|
8 | + $our_host = $config->getDefinition('URI')->host; |
|
9 | + if ($our_host !== null) $this->ourHostParts = array_reverse(explode('.', $our_host)); |
|
10 | + } |
|
11 | + public function filter(&$uri, $config, $context) { |
|
12 | + if (is_null($uri->host)) return true; |
|
13 | + if ($this->ourHostParts === false) return false; |
|
14 | + $host_parts = array_reverse(explode('.', $uri->host)); |
|
15 | + foreach ($this->ourHostParts as $i => $x) { |
|
16 | + if (!isset($host_parts[$i])) return false; |
|
17 | + if ($host_parts[$i] != $this->ourHostParts[$i]) return false; |
|
18 | + } |
|
19 | + return true; |
|
20 | + } |
|
21 | 21 | } |
22 | 22 | |
23 | 23 | // vim: et sw=4 sts=4 |
@@ -6,15 +6,25 @@ |
||
6 | 6 | protected $ourHostParts = false; |
7 | 7 | public function prepare($config) { |
8 | 8 | $our_host = $config->getDefinition('URI')->host; |
9 | - if ($our_host !== null) $this->ourHostParts = array_reverse(explode('.', $our_host)); |
|
9 | + if ($our_host !== null) { |
|
10 | + $this->ourHostParts = array_reverse(explode('.', $our_host)); |
|
11 | + } |
|
10 | 12 | } |
11 | 13 | public function filter(&$uri, $config, $context) { |
12 | - if (is_null($uri->host)) return true; |
|
13 | - if ($this->ourHostParts === false) return false; |
|
14 | + if (is_null($uri->host)) { |
|
15 | + return true; |
|
16 | + } |
|
17 | + if ($this->ourHostParts === false) { |
|
18 | + return false; |
|
19 | + } |
|
14 | 20 | $host_parts = array_reverse(explode('.', $uri->host)); |
15 | 21 | foreach ($this->ourHostParts as $i => $x) { |
16 | - if (!isset($host_parts[$i])) return false; |
|
17 | - if ($host_parts[$i] != $this->ourHostParts[$i]) return false; |
|
22 | + if (!isset($host_parts[$i])) { |
|
23 | + return false; |
|
24 | + } |
|
25 | + if ($host_parts[$i] != $this->ourHostParts[$i]) { |
|
26 | + return false; |
|
27 | + } |
|
18 | 28 | } |
19 | 29 | return true; |
20 | 30 | } |
@@ -2,11 +2,11 @@ |
||
2 | 2 | |
3 | 3 | class HTMLPurifier_URIFilter_DisableExternalResources extends HTMLPurifier_URIFilter_DisableExternal |
4 | 4 | { |
5 | - public $name = 'DisableExternalResources'; |
|
6 | - public function filter(&$uri, $config, $context) { |
|
7 | - if (!$context->get('EmbeddedURI', true)) return true; |
|
8 | - return parent::filter($uri, $config, $context); |
|
9 | - } |
|
5 | + public $name = 'DisableExternalResources'; |
|
6 | + public function filter(&$uri, $config, $context) { |
|
7 | + if (!$context->get('EmbeddedURI', true)) return true; |
|
8 | + return parent::filter($uri, $config, $context); |
|
9 | + } |
|
10 | 10 | } |
11 | 11 | |
12 | 12 | // vim: et sw=4 sts=4 |
@@ -4,7 +4,9 @@ |
||
4 | 4 | { |
5 | 5 | public $name = 'DisableExternalResources'; |
6 | 6 | public function filter(&$uri, $config, $context) { |
7 | - if (!$context->get('EmbeddedURI', true)) return true; |
|
7 | + if (!$context->get('EmbeddedURI', true)) { |
|
8 | + return true; |
|
9 | + } |
|
8 | 10 | return parent::filter($uri, $config, $context); |
9 | 11 | } |
10 | 12 | } |
@@ -2,10 +2,10 @@ |
||
2 | 2 | |
3 | 3 | class HTMLPurifier_URIFilter_DisableResources extends HTMLPurifier_URIFilter |
4 | 4 | { |
5 | - public $name = 'DisableResources'; |
|
6 | - public function filter(&$uri, $config, $context) { |
|
7 | - return !$context->get('EmbeddedURI', true); |
|
8 | - } |
|
5 | + public $name = 'DisableResources'; |
|
6 | + public function filter(&$uri, $config, $context) { |
|
7 | + return !$context->get('EmbeddedURI', true); |
|
8 | + } |
|
9 | 9 | } |
10 | 10 | |
11 | 11 | // vim: et sw=4 sts=4 |
@@ -6,20 +6,20 @@ |
||
6 | 6 | // points are involved), but I'm not 100% sure |
7 | 7 | class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter |
8 | 8 | { |
9 | - public $name = 'HostBlacklist'; |
|
10 | - protected $blacklist = array(); |
|
11 | - public function prepare($config) { |
|
12 | - $this->blacklist = $config->get('URI.HostBlacklist'); |
|
13 | - return true; |
|
14 | - } |
|
15 | - public function filter(&$uri, $config, $context) { |
|
16 | - foreach($this->blacklist as $blacklisted_host_fragment) { |
|
17 | - if (strpos($uri->host, $blacklisted_host_fragment) !== false) { |
|
18 | - return false; |
|
19 | - } |
|
20 | - } |
|
21 | - return true; |
|
22 | - } |
|
9 | + public $name = 'HostBlacklist'; |
|
10 | + protected $blacklist = array(); |
|
11 | + public function prepare($config) { |
|
12 | + $this->blacklist = $config->get('URI.HostBlacklist'); |
|
13 | + return true; |
|
14 | + } |
|
15 | + public function filter(&$uri, $config, $context) { |
|
16 | + foreach($this->blacklist as $blacklisted_host_fragment) { |
|
17 | + if (strpos($uri->host, $blacklisted_host_fragment) !== false) { |
|
18 | + return false; |
|
19 | + } |
|
20 | + } |
|
21 | + return true; |
|
22 | + } |
|
23 | 23 | } |
24 | 24 | |
25 | 25 | // vim: et sw=4 sts=4 |
@@ -13,7 +13,7 @@ |
||
13 | 13 | return true; |
14 | 14 | } |
15 | 15 | public function filter(&$uri, $config, $context) { |
16 | - foreach($this->blacklist as $blacklisted_host_fragment) { |
|
16 | + foreach ($this->blacklist as $blacklisted_host_fragment) { |
|
17 | 17 | if (strpos($uri->host, $blacklisted_host_fragment) !== false) { |
18 | 18 | return false; |
19 | 19 | } |
@@ -4,111 +4,111 @@ |
||
4 | 4 | |
5 | 5 | class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter |
6 | 6 | { |
7 | - public $name = 'MakeAbsolute'; |
|
8 | - protected $base; |
|
9 | - protected $basePathStack = array(); |
|
10 | - public function prepare($config) { |
|
11 | - $def = $config->getDefinition('URI'); |
|
12 | - $this->base = $def->base; |
|
13 | - if (is_null($this->base)) { |
|
14 | - trigger_error('URI.MakeAbsolute is being ignored due to lack of value for URI.Base configuration', E_USER_WARNING); |
|
15 | - return false; |
|
16 | - } |
|
17 | - $this->base->fragment = null; // fragment is invalid for base URI |
|
18 | - $stack = explode('/', $this->base->path); |
|
19 | - array_pop($stack); // discard last segment |
|
20 | - $stack = $this->_collapseStack($stack); // do pre-parsing |
|
21 | - $this->basePathStack = $stack; |
|
22 | - return true; |
|
23 | - } |
|
24 | - public function filter(&$uri, $config, $context) { |
|
25 | - if (is_null($this->base)) return true; // abort early |
|
26 | - if ( |
|
27 | - $uri->path === '' && is_null($uri->scheme) && |
|
28 | - is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment) |
|
29 | - ) { |
|
30 | - // reference to current document |
|
31 | - $uri = clone $this->base; |
|
32 | - return true; |
|
33 | - } |
|
34 | - if (!is_null($uri->scheme)) { |
|
35 | - // absolute URI already: don't change |
|
36 | - if (!is_null($uri->host)) return true; |
|
37 | - $scheme_obj = $uri->getSchemeObj($config, $context); |
|
38 | - if (!$scheme_obj) { |
|
39 | - // scheme not recognized |
|
40 | - return false; |
|
41 | - } |
|
42 | - if (!$scheme_obj->hierarchical) { |
|
43 | - // non-hierarchal URI with explicit scheme, don't change |
|
44 | - return true; |
|
45 | - } |
|
46 | - // special case: had a scheme but always is hierarchical and had no authority |
|
47 | - } |
|
48 | - if (!is_null($uri->host)) { |
|
49 | - // network path, don't bother |
|
50 | - return true; |
|
51 | - } |
|
52 | - if ($uri->path === '') { |
|
53 | - $uri->path = $this->base->path; |
|
54 | - } elseif ($uri->path[0] !== '/') { |
|
55 | - // relative path, needs more complicated processing |
|
56 | - $stack = explode('/', $uri->path); |
|
57 | - $new_stack = array_merge($this->basePathStack, $stack); |
|
58 | - if ($new_stack[0] !== '' && !is_null($this->base->host)) { |
|
59 | - array_unshift($new_stack, ''); |
|
60 | - } |
|
61 | - $new_stack = $this->_collapseStack($new_stack); |
|
62 | - $uri->path = implode('/', $new_stack); |
|
63 | - } else { |
|
64 | - // absolute path, but still we should collapse |
|
65 | - $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path))); |
|
66 | - } |
|
67 | - // re-combine |
|
68 | - $uri->scheme = $this->base->scheme; |
|
69 | - if (is_null($uri->userinfo)) $uri->userinfo = $this->base->userinfo; |
|
70 | - if (is_null($uri->host)) $uri->host = $this->base->host; |
|
71 | - if (is_null($uri->port)) $uri->port = $this->base->port; |
|
72 | - return true; |
|
73 | - } |
|
7 | + public $name = 'MakeAbsolute'; |
|
8 | + protected $base; |
|
9 | + protected $basePathStack = array(); |
|
10 | + public function prepare($config) { |
|
11 | + $def = $config->getDefinition('URI'); |
|
12 | + $this->base = $def->base; |
|
13 | + if (is_null($this->base)) { |
|
14 | + trigger_error('URI.MakeAbsolute is being ignored due to lack of value for URI.Base configuration', E_USER_WARNING); |
|
15 | + return false; |
|
16 | + } |
|
17 | + $this->base->fragment = null; // fragment is invalid for base URI |
|
18 | + $stack = explode('/', $this->base->path); |
|
19 | + array_pop($stack); // discard last segment |
|
20 | + $stack = $this->_collapseStack($stack); // do pre-parsing |
|
21 | + $this->basePathStack = $stack; |
|
22 | + return true; |
|
23 | + } |
|
24 | + public function filter(&$uri, $config, $context) { |
|
25 | + if (is_null($this->base)) return true; // abort early |
|
26 | + if ( |
|
27 | + $uri->path === '' && is_null($uri->scheme) && |
|
28 | + is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment) |
|
29 | + ) { |
|
30 | + // reference to current document |
|
31 | + $uri = clone $this->base; |
|
32 | + return true; |
|
33 | + } |
|
34 | + if (!is_null($uri->scheme)) { |
|
35 | + // absolute URI already: don't change |
|
36 | + if (!is_null($uri->host)) return true; |
|
37 | + $scheme_obj = $uri->getSchemeObj($config, $context); |
|
38 | + if (!$scheme_obj) { |
|
39 | + // scheme not recognized |
|
40 | + return false; |
|
41 | + } |
|
42 | + if (!$scheme_obj->hierarchical) { |
|
43 | + // non-hierarchal URI with explicit scheme, don't change |
|
44 | + return true; |
|
45 | + } |
|
46 | + // special case: had a scheme but always is hierarchical and had no authority |
|
47 | + } |
|
48 | + if (!is_null($uri->host)) { |
|
49 | + // network path, don't bother |
|
50 | + return true; |
|
51 | + } |
|
52 | + if ($uri->path === '') { |
|
53 | + $uri->path = $this->base->path; |
|
54 | + } elseif ($uri->path[0] !== '/') { |
|
55 | + // relative path, needs more complicated processing |
|
56 | + $stack = explode('/', $uri->path); |
|
57 | + $new_stack = array_merge($this->basePathStack, $stack); |
|
58 | + if ($new_stack[0] !== '' && !is_null($this->base->host)) { |
|
59 | + array_unshift($new_stack, ''); |
|
60 | + } |
|
61 | + $new_stack = $this->_collapseStack($new_stack); |
|
62 | + $uri->path = implode('/', $new_stack); |
|
63 | + } else { |
|
64 | + // absolute path, but still we should collapse |
|
65 | + $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path))); |
|
66 | + } |
|
67 | + // re-combine |
|
68 | + $uri->scheme = $this->base->scheme; |
|
69 | + if (is_null($uri->userinfo)) $uri->userinfo = $this->base->userinfo; |
|
70 | + if (is_null($uri->host)) $uri->host = $this->base->host; |
|
71 | + if (is_null($uri->port)) $uri->port = $this->base->port; |
|
72 | + return true; |
|
73 | + } |
|
74 | 74 | |
75 | - /** |
|
76 | - * Resolve dots and double-dots in a path stack |
|
77 | - */ |
|
78 | - private function _collapseStack($stack) { |
|
79 | - $result = array(); |
|
80 | - $is_folder = false; |
|
81 | - for ($i = 0; isset($stack[$i]); $i++) { |
|
82 | - $is_folder = false; |
|
83 | - // absorb an internally duplicated slash |
|
84 | - if ($stack[$i] == '' && $i && isset($stack[$i+1])) continue; |
|
85 | - if ($stack[$i] == '..') { |
|
86 | - if (!empty($result)) { |
|
87 | - $segment = array_pop($result); |
|
88 | - if ($segment === '' && empty($result)) { |
|
89 | - // error case: attempted to back out too far: |
|
90 | - // restore the leading slash |
|
91 | - $result[] = ''; |
|
92 | - } elseif ($segment === '..') { |
|
93 | - $result[] = '..'; // cannot remove .. with .. |
|
94 | - } |
|
95 | - } else { |
|
96 | - // relative path, preserve the double-dots |
|
97 | - $result[] = '..'; |
|
98 | - } |
|
99 | - $is_folder = true; |
|
100 | - continue; |
|
101 | - } |
|
102 | - if ($stack[$i] == '.') { |
|
103 | - // silently absorb |
|
104 | - $is_folder = true; |
|
105 | - continue; |
|
106 | - } |
|
107 | - $result[] = $stack[$i]; |
|
108 | - } |
|
109 | - if ($is_folder) $result[] = ''; |
|
110 | - return $result; |
|
111 | - } |
|
75 | + /** |
|
76 | + * Resolve dots and double-dots in a path stack |
|
77 | + */ |
|
78 | + private function _collapseStack($stack) { |
|
79 | + $result = array(); |
|
80 | + $is_folder = false; |
|
81 | + for ($i = 0; isset($stack[$i]); $i++) { |
|
82 | + $is_folder = false; |
|
83 | + // absorb an internally duplicated slash |
|
84 | + if ($stack[$i] == '' && $i && isset($stack[$i+1])) continue; |
|
85 | + if ($stack[$i] == '..') { |
|
86 | + if (!empty($result)) { |
|
87 | + $segment = array_pop($result); |
|
88 | + if ($segment === '' && empty($result)) { |
|
89 | + // error case: attempted to back out too far: |
|
90 | + // restore the leading slash |
|
91 | + $result[] = ''; |
|
92 | + } elseif ($segment === '..') { |
|
93 | + $result[] = '..'; // cannot remove .. with .. |
|
94 | + } |
|
95 | + } else { |
|
96 | + // relative path, preserve the double-dots |
|
97 | + $result[] = '..'; |
|
98 | + } |
|
99 | + $is_folder = true; |
|
100 | + continue; |
|
101 | + } |
|
102 | + if ($stack[$i] == '.') { |
|
103 | + // silently absorb |
|
104 | + $is_folder = true; |
|
105 | + continue; |
|
106 | + } |
|
107 | + $result[] = $stack[$i]; |
|
108 | + } |
|
109 | + if ($is_folder) $result[] = ''; |
|
110 | + return $result; |
|
111 | + } |
|
112 | 112 | } |
113 | 113 | |
114 | 114 | // vim: et sw=4 sts=4 |
@@ -81,7 +81,7 @@ |
||
81 | 81 | for ($i = 0; isset($stack[$i]); $i++) { |
82 | 82 | $is_folder = false; |
83 | 83 | // absorb an internally duplicated slash |
84 | - if ($stack[$i] == '' && $i && isset($stack[$i+1])) continue; |
|
84 | + if ($stack[$i] == '' && $i && isset($stack[$i + 1])) continue; |
|
85 | 85 | if ($stack[$i] == '..') { |
86 | 86 | if (!empty($result)) { |
87 | 87 | $segment = array_pop($result); |
@@ -22,7 +22,10 @@ discard block |
||
22 | 22 | return true; |
23 | 23 | } |
24 | 24 | public function filter(&$uri, $config, $context) { |
25 | - if (is_null($this->base)) return true; // abort early |
|
25 | + if (is_null($this->base)) { |
|
26 | + return true; |
|
27 | + } |
|
28 | + // abort early |
|
26 | 29 | if ( |
27 | 30 | $uri->path === '' && is_null($uri->scheme) && |
28 | 31 | is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment) |
@@ -33,7 +36,9 @@ discard block |
||
33 | 36 | } |
34 | 37 | if (!is_null($uri->scheme)) { |
35 | 38 | // absolute URI already: don't change |
36 | - if (!is_null($uri->host)) return true; |
|
39 | + if (!is_null($uri->host)) { |
|
40 | + return true; |
|
41 | + } |
|
37 | 42 | $scheme_obj = $uri->getSchemeObj($config, $context); |
38 | 43 | if (!$scheme_obj) { |
39 | 44 | // scheme not recognized |
@@ -66,9 +71,15 @@ discard block |
||
66 | 71 | } |
67 | 72 | // re-combine |
68 | 73 | $uri->scheme = $this->base->scheme; |
69 | - if (is_null($uri->userinfo)) $uri->userinfo = $this->base->userinfo; |
|
70 | - if (is_null($uri->host)) $uri->host = $this->base->host; |
|
71 | - if (is_null($uri->port)) $uri->port = $this->base->port; |
|
74 | + if (is_null($uri->userinfo)) { |
|
75 | + $uri->userinfo = $this->base->userinfo; |
|
76 | + } |
|
77 | + if (is_null($uri->host)) { |
|
78 | + $uri->host = $this->base->host; |
|
79 | + } |
|
80 | + if (is_null($uri->port)) { |
|
81 | + $uri->port = $this->base->port; |
|
82 | + } |
|
72 | 83 | return true; |
73 | 84 | } |
74 | 85 | |
@@ -81,7 +92,9 @@ discard block |
||
81 | 92 | for ($i = 0; isset($stack[$i]); $i++) { |
82 | 93 | $is_folder = false; |
83 | 94 | // absorb an internally duplicated slash |
84 | - if ($stack[$i] == '' && $i && isset($stack[$i+1])) continue; |
|
95 | + if ($stack[$i] == '' && $i && isset($stack[$i+1])) { |
|
96 | + continue; |
|
97 | + } |
|
85 | 98 | if ($stack[$i] == '..') { |
86 | 99 | if (!empty($result)) { |
87 | 100 | $segment = array_pop($result); |
@@ -106,7 +119,9 @@ discard block |
||
106 | 119 | } |
107 | 120 | $result[] = $stack[$i]; |
108 | 121 | } |
109 | - if ($is_folder) $result[] = ''; |
|
122 | + if ($is_folder) { |
|
123 | + $result[] = ''; |
|
124 | + } |
|
110 | 125 | return $result; |
111 | 126 | } |
112 | 127 | } |
@@ -2,51 +2,51 @@ |
||
2 | 2 | |
3 | 3 | class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter |
4 | 4 | { |
5 | - public $name = 'Munge'; |
|
6 | - public $post = true; |
|
7 | - private $target, $parser, $doEmbed, $secretKey; |
|
8 | - |
|
9 | - protected $replace = array(); |
|
10 | - |
|
11 | - public function prepare($config) { |
|
12 | - $this->target = $config->get('URI.' . $this->name); |
|
13 | - $this->parser = new HTMLPurifier_URIParser(); |
|
14 | - $this->doEmbed = $config->get('URI.MungeResources'); |
|
15 | - $this->secretKey = $config->get('URI.MungeSecretKey'); |
|
16 | - return true; |
|
17 | - } |
|
18 | - public function filter(&$uri, $config, $context) { |
|
19 | - if ($context->get('EmbeddedURI', true) && !$this->doEmbed) return true; |
|
20 | - |
|
21 | - $scheme_obj = $uri->getSchemeObj($config, $context); |
|
22 | - if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it |
|
23 | - if (!$scheme_obj->browsable) return true; // ignore non-browseable schemes, since we can't munge those in a reasonable way |
|
24 | - if ($uri->isBenign($config, $context)) return true; // don't redirect if a benign URL |
|
25 | - |
|
26 | - $this->makeReplace($uri, $config, $context); |
|
27 | - $this->replace = array_map('rawurlencode', $this->replace); |
|
28 | - |
|
29 | - $new_uri = strtr($this->target, $this->replace); |
|
30 | - $new_uri = $this->parser->parse($new_uri); |
|
31 | - // don't redirect if the target host is the same as the |
|
32 | - // starting host |
|
33 | - if ($uri->host === $new_uri->host) return true; |
|
34 | - $uri = $new_uri; // overwrite |
|
35 | - return true; |
|
36 | - } |
|
37 | - |
|
38 | - protected function makeReplace($uri, $config, $context) { |
|
39 | - $string = $uri->toString(); |
|
40 | - // always available |
|
41 | - $this->replace['%s'] = $string; |
|
42 | - $this->replace['%r'] = $context->get('EmbeddedURI', true); |
|
43 | - $token = $context->get('CurrentToken', true); |
|
44 | - $this->replace['%n'] = $token ? $token->name : null; |
|
45 | - $this->replace['%m'] = $context->get('CurrentAttr', true); |
|
46 | - $this->replace['%p'] = $context->get('CurrentCSSProperty', true); |
|
47 | - // not always available |
|
48 | - if ($this->secretKey) $this->replace['%t'] = sha1($this->secretKey . ':' . $string); |
|
49 | - } |
|
5 | + public $name = 'Munge'; |
|
6 | + public $post = true; |
|
7 | + private $target, $parser, $doEmbed, $secretKey; |
|
8 | + |
|
9 | + protected $replace = array(); |
|
10 | + |
|
11 | + public function prepare($config) { |
|
12 | + $this->target = $config->get('URI.' . $this->name); |
|
13 | + $this->parser = new HTMLPurifier_URIParser(); |
|
14 | + $this->doEmbed = $config->get('URI.MungeResources'); |
|
15 | + $this->secretKey = $config->get('URI.MungeSecretKey'); |
|
16 | + return true; |
|
17 | + } |
|
18 | + public function filter(&$uri, $config, $context) { |
|
19 | + if ($context->get('EmbeddedURI', true) && !$this->doEmbed) return true; |
|
20 | + |
|
21 | + $scheme_obj = $uri->getSchemeObj($config, $context); |
|
22 | + if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it |
|
23 | + if (!$scheme_obj->browsable) return true; // ignore non-browseable schemes, since we can't munge those in a reasonable way |
|
24 | + if ($uri->isBenign($config, $context)) return true; // don't redirect if a benign URL |
|
25 | + |
|
26 | + $this->makeReplace($uri, $config, $context); |
|
27 | + $this->replace = array_map('rawurlencode', $this->replace); |
|
28 | + |
|
29 | + $new_uri = strtr($this->target, $this->replace); |
|
30 | + $new_uri = $this->parser->parse($new_uri); |
|
31 | + // don't redirect if the target host is the same as the |
|
32 | + // starting host |
|
33 | + if ($uri->host === $new_uri->host) return true; |
|
34 | + $uri = $new_uri; // overwrite |
|
35 | + return true; |
|
36 | + } |
|
37 | + |
|
38 | + protected function makeReplace($uri, $config, $context) { |
|
39 | + $string = $uri->toString(); |
|
40 | + // always available |
|
41 | + $this->replace['%s'] = $string; |
|
42 | + $this->replace['%r'] = $context->get('EmbeddedURI', true); |
|
43 | + $token = $context->get('CurrentToken', true); |
|
44 | + $this->replace['%n'] = $token ? $token->name : null; |
|
45 | + $this->replace['%m'] = $context->get('CurrentAttr', true); |
|
46 | + $this->replace['%p'] = $context->get('CurrentCSSProperty', true); |
|
47 | + // not always available |
|
48 | + if ($this->secretKey) $this->replace['%t'] = sha1($this->secretKey . ':' . $string); |
|
49 | + } |
|
50 | 50 | |
51 | 51 | } |
52 | 52 |
@@ -16,12 +16,23 @@ discard block |
||
16 | 16 | return true; |
17 | 17 | } |
18 | 18 | public function filter(&$uri, $config, $context) { |
19 | - if ($context->get('EmbeddedURI', true) && !$this->doEmbed) return true; |
|
19 | + if ($context->get('EmbeddedURI', true) && !$this->doEmbed) { |
|
20 | + return true; |
|
21 | + } |
|
20 | 22 | |
21 | 23 | $scheme_obj = $uri->getSchemeObj($config, $context); |
22 | - if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it |
|
23 | - if (!$scheme_obj->browsable) return true; // ignore non-browseable schemes, since we can't munge those in a reasonable way |
|
24 | - if ($uri->isBenign($config, $context)) return true; // don't redirect if a benign URL |
|
24 | + if (!$scheme_obj) { |
|
25 | + return true; |
|
26 | + } |
|
27 | + // ignore unknown schemes, maybe another postfilter did it |
|
28 | + if (!$scheme_obj->browsable) { |
|
29 | + return true; |
|
30 | + } |
|
31 | + // ignore non-browseable schemes, since we can't munge those in a reasonable way |
|
32 | + if ($uri->isBenign($config, $context)) { |
|
33 | + return true; |
|
34 | + } |
|
35 | + // don't redirect if a benign URL |
|
25 | 36 | |
26 | 37 | $this->makeReplace($uri, $config, $context); |
27 | 38 | $this->replace = array_map('rawurlencode', $this->replace); |
@@ -30,7 +41,9 @@ discard block |
||
30 | 41 | $new_uri = $this->parser->parse($new_uri); |
31 | 42 | // don't redirect if the target host is the same as the |
32 | 43 | // starting host |
33 | - if ($uri->host === $new_uri->host) return true; |
|
44 | + if ($uri->host === $new_uri->host) { |
|
45 | + return true; |
|
46 | + } |
|
34 | 47 | $uri = $new_uri; // overwrite |
35 | 48 | return true; |
36 | 49 | } |
@@ -45,7 +58,9 @@ discard block |
||
45 | 58 | $this->replace['%m'] = $context->get('CurrentAttr', true); |
46 | 59 | $this->replace['%p'] = $context->get('CurrentCSSProperty', true); |
47 | 60 | // not always available |
48 | - if ($this->secretKey) $this->replace['%t'] = sha1($this->secretKey . ':' . $string); |
|
61 | + if ($this->secretKey) { |
|
62 | + $this->replace['%t'] = sha1($this->secretKey . ':' . $string); |
|
63 | + } |
|
49 | 64 | } |
50 | 65 | |
51 | 66 | } |
@@ -8,28 +8,28 @@ |
||
8 | 8 | */ |
9 | 9 | class HTMLPurifier_URIFilter_SafeIframe extends HTMLPurifier_URIFilter |
10 | 10 | { |
11 | - public $name = 'SafeIframe'; |
|
12 | - public $always_load = true; |
|
13 | - protected $regexp = NULL; |
|
14 | - // XXX: The not so good bit about how this is all setup now is we |
|
15 | - // can't check HTML.SafeIframe in the 'prepare' step: we have to |
|
16 | - // defer till the actual filtering. |
|
17 | - public function prepare($config) { |
|
18 | - $this->regexp = $config->get('URI.SafeIframeRegexp'); |
|
19 | - return true; |
|
20 | - } |
|
21 | - public function filter(&$uri, $config, $context) { |
|
22 | - // check if filter not applicable |
|
23 | - if (!$config->get('HTML.SafeIframe')) return true; |
|
24 | - // check if the filter should actually trigger |
|
25 | - if (!$context->get('EmbeddedURI', true)) return true; |
|
26 | - $token = $context->get('CurrentToken', true); |
|
27 | - if (!($token && $token->name == 'iframe')) return true; |
|
28 | - // check if we actually have some whitelists enabled |
|
29 | - if ($this->regexp === null) return false; |
|
30 | - // actually check the whitelists |
|
31 | - return preg_match($this->regexp, $uri->toString()); |
|
32 | - } |
|
11 | + public $name = 'SafeIframe'; |
|
12 | + public $always_load = true; |
|
13 | + protected $regexp = NULL; |
|
14 | + // XXX: The not so good bit about how this is all setup now is we |
|
15 | + // can't check HTML.SafeIframe in the 'prepare' step: we have to |
|
16 | + // defer till the actual filtering. |
|
17 | + public function prepare($config) { |
|
18 | + $this->regexp = $config->get('URI.SafeIframeRegexp'); |
|
19 | + return true; |
|
20 | + } |
|
21 | + public function filter(&$uri, $config, $context) { |
|
22 | + // check if filter not applicable |
|
23 | + if (!$config->get('HTML.SafeIframe')) return true; |
|
24 | + // check if the filter should actually trigger |
|
25 | + if (!$context->get('EmbeddedURI', true)) return true; |
|
26 | + $token = $context->get('CurrentToken', true); |
|
27 | + if (!($token && $token->name == 'iframe')) return true; |
|
28 | + // check if we actually have some whitelists enabled |
|
29 | + if ($this->regexp === null) return false; |
|
30 | + // actually check the whitelists |
|
31 | + return preg_match($this->regexp, $uri->toString()); |
|
32 | + } |
|
33 | 33 | } |
34 | 34 | |
35 | 35 | // vim: et sw=4 sts=4 |
@@ -20,13 +20,21 @@ |
||
20 | 20 | } |
21 | 21 | public function filter(&$uri, $config, $context) { |
22 | 22 | // check if filter not applicable |
23 | - if (!$config->get('HTML.SafeIframe')) return true; |
|
23 | + if (!$config->get('HTML.SafeIframe')) { |
|
24 | + return true; |
|
25 | + } |
|
24 | 26 | // check if the filter should actually trigger |
25 | - if (!$context->get('EmbeddedURI', true)) return true; |
|
27 | + if (!$context->get('EmbeddedURI', true)) { |
|
28 | + return true; |
|
29 | + } |
|
26 | 30 | $token = $context->get('CurrentToken', true); |
27 | - if (!($token && $token->name == 'iframe')) return true; |
|
31 | + if (!($token && $token->name == 'iframe')) { |
|
32 | + return true; |
|
33 | + } |
|
28 | 34 | // check if we actually have some whitelists enabled |
29 | - if ($this->regexp === null) return false; |
|
35 | + if ($this->regexp === null) { |
|
36 | + return false; |
|
37 | + } |
|
30 | 38 | // actually check the whitelists |
31 | 39 | return preg_match($this->regexp, $uri->toString()); |
32 | 40 | } |