| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | /** |
|---|
| 4 | * Validates a URI as defined by RFC 3986. |
|---|
| 5 | * @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme |
|---|
| 6 | */ |
|---|
| 7 | class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef |
|---|
| 8 | { |
|---|
| 9 | |
|---|
| 10 | protected $parser; |
|---|
| 11 | protected $embedsResource; |
|---|
| 12 | |
|---|
| 13 | /** |
|---|
| 14 | * @param $embeds_resource_resource Does the URI here result in an extra HTTP request? |
|---|
| 15 | */ |
|---|
| 16 | public function __construct($embeds_resource = false) { |
|---|
| 17 | $this->parser = new HTMLPurifier_URIParser(); |
|---|
| 18 | $this->embedsResource = (bool) $embeds_resource; |
|---|
| 19 | } |
|---|
| 20 | |
|---|
| 21 | public function validate($uri, $config, $context) { |
|---|
| 22 | |
|---|
| 23 | if ($config->get('URI', 'Disable')) return false; |
|---|
| 24 | |
|---|
| 25 | $uri = $this->parseCDATA($uri); |
|---|
| 26 | |
|---|
| 27 | // parse the URI |
|---|
| 28 | $uri = $this->parser->parse($uri); |
|---|
| 29 | if ($uri === false) return false; |
|---|
| 30 | |
|---|
| 31 | // add embedded flag to context for validators |
|---|
| 32 | $context->register('EmbeddedURI', $this->embedsResource); |
|---|
| 33 | |
|---|
| 34 | $ok = false; |
|---|
| 35 | do { |
|---|
| 36 | |
|---|
| 37 | // generic validation |
|---|
| 38 | $result = $uri->validate($config, $context); |
|---|
| 39 | if (!$result) break; |
|---|
| 40 | |
|---|
| 41 | // chained filtering |
|---|
| 42 | $uri_def = $config->getDefinition('URI'); |
|---|
| 43 | $result = $uri_def->filter($uri, $config, $context); |
|---|
| 44 | if (!$result) break; |
|---|
| 45 | |
|---|
| 46 | // scheme-specific validation |
|---|
| 47 | $scheme_obj = $uri->getSchemeObj($config, $context); |
|---|
| 48 | if (!$scheme_obj) break; |
|---|
| 49 | if ($this->embedsResource && !$scheme_obj->browsable) break; |
|---|
| 50 | $result = $scheme_obj->validate($uri, $config, $context); |
|---|
| 51 | if (!$result) break; |
|---|
| 52 | |
|---|
| 53 | // survived gauntlet |
|---|
| 54 | $ok = true; |
|---|
| 55 | |
|---|
| 56 | } while (false); |
|---|
| 57 | |
|---|
| 58 | $context->destroy('EmbeddedURI'); |
|---|
| 59 | if (!$ok) return false; |
|---|
| 60 | |
|---|
| 61 | // back to string |
|---|
| 62 | $result = $uri->toString(); |
|---|
| 63 | |
|---|
| 64 | // munge entire URI if necessary |
|---|
| 65 | if ( |
|---|
| 66 | !is_null($uri->host) && // indicator for authority |
|---|
| 67 | !empty($scheme_obj->browsable) && |
|---|
| 68 | !is_null($munge = $config->get('URI', 'Munge')) |
|---|
| 69 | ) { |
|---|
| 70 | $result = str_replace('%s', rawurlencode($result), $munge); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | return $result; |
|---|
| 74 | |
|---|
| 75 | } |
|---|
| 76 | |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | |
|---|