File indexing completed on 2024-05-12 06:02:06

0001 <?php
0002 
0003 class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter
0004 {
0005     /**
0006      * @type string
0007      */
0008     public $name = 'Munge';
0009 
0010     /**
0011      * @type bool
0012      */
0013     public $post = true;
0014 
0015     /**
0016      * @type string
0017      */
0018     private $target;
0019 
0020     /**
0021      * @type HTMLPurifier_URIParser
0022      */
0023     private $parser;
0024 
0025     /**
0026      * @type bool
0027      */
0028     private $doEmbed;
0029 
0030     /**
0031      * @type string
0032      */
0033     private $secretKey;
0034 
0035     /**
0036      * @type array
0037      */
0038     protected $replace = array();
0039 
0040     /**
0041      * @param HTMLPurifier_Config $config
0042      * @return bool
0043      */
0044     public function prepare($config)
0045     {
0046         $this->target = $config->get('URI.' . $this->name);
0047         $this->parser = new HTMLPurifier_URIParser();
0048         $this->doEmbed = $config->get('URI.MungeResources');
0049         $this->secretKey = $config->get('URI.MungeSecretKey');
0050         if ($this->secretKey && !function_exists('hash_hmac')) {
0051             throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support.");
0052         }
0053         return true;
0054     }
0055 
0056     /**
0057      * @param HTMLPurifier_URI $uri
0058      * @param HTMLPurifier_Config $config
0059      * @param HTMLPurifier_Context $context
0060      * @return bool
0061      */
0062     public function filter(&$uri, $config, $context)
0063     {
0064         if ($context->get('EmbeddedURI', true) && !$this->doEmbed) {
0065             return true;
0066         }
0067 
0068         $scheme_obj = $uri->getSchemeObj($config, $context);
0069         if (!$scheme_obj) {
0070             return true;
0071         } // ignore unknown schemes, maybe another postfilter did it
0072         if (!$scheme_obj->browsable) {
0073             return true;
0074         } // ignore non-browseable schemes, since we can't munge those in a reasonable way
0075         if ($uri->isBenign($config, $context)) {
0076             return true;
0077         } // don't redirect if a benign URL
0078 
0079         $this->makeReplace($uri, $config, $context);
0080         $this->replace = array_map('rawurlencode', $this->replace);
0081 
0082         $new_uri = strtr($this->target, $this->replace);
0083         $new_uri = $this->parser->parse($new_uri);
0084         // don't redirect if the target host is the same as the
0085         // starting host
0086         if ($uri->host === $new_uri->host) {
0087             return true;
0088         }
0089         $uri = $new_uri; // overwrite
0090         return true;
0091     }
0092 
0093     /**
0094      * @param HTMLPurifier_URI $uri
0095      * @param HTMLPurifier_Config $config
0096      * @param HTMLPurifier_Context $context
0097      */
0098     protected function makeReplace($uri, $config, $context)
0099     {
0100         $string = $uri->toString();
0101         // always available
0102         $this->replace['%s'] = $string;
0103         $this->replace['%r'] = $context->get('EmbeddedURI', true);
0104         $token = $context->get('CurrentToken', true);
0105         $this->replace['%n'] = $token ? $token->name : null;
0106         $this->replace['%m'] = $context->get('CurrentAttr', true);
0107         $this->replace['%p'] = $context->get('CurrentCSSProperty', true);
0108         // not always available
0109         if ($this->secretKey) {
0110             $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey);
0111         }
0112     }
0113 }
0114 
0115 // vim: et sw=4 sts=4