File indexing completed on 2024-12-22 05:36:18
0001 <?php 0002 0003 /** 0004 * Validates the HTML attribute ID. 0005 * @warning Even though this is the id processor, it 0006 * will ignore the directive Attr:IDBlacklist, since it will only 0007 * go according to the ID accumulator. Since the accumulator is 0008 * automatically generated, it will have already absorbed the 0009 * blacklist. If you're hacking around, make sure you use load()! 0010 */ 0011 0012 class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef 0013 { 0014 0015 // selector is NOT a valid thing to use for IDREFs, because IDREFs 0016 // *must* target IDs that exist, whereas selector #ids do not. 0017 0018 /** 0019 * Determines whether or not we're validating an ID in a CSS 0020 * selector context. 0021 * @type bool 0022 */ 0023 protected $selector; 0024 0025 /** 0026 * @param bool $selector 0027 */ 0028 public function __construct($selector = false) 0029 { 0030 $this->selector = $selector; 0031 } 0032 0033 /** 0034 * @param string $id 0035 * @param HTMLPurifier_Config $config 0036 * @param HTMLPurifier_Context $context 0037 * @return bool|string 0038 */ 0039 public function validate($id, $config, $context) 0040 { 0041 if (!$this->selector && !$config->get('Attr.EnableID')) { 0042 return false; 0043 } 0044 0045 $id = trim($id); // trim it first 0046 0047 if ($id === '') { 0048 return false; 0049 } 0050 0051 $prefix = $config->get('Attr.IDPrefix'); 0052 if ($prefix !== '') { 0053 $prefix .= $config->get('Attr.IDPrefixLocal'); 0054 // prevent re-appending the prefix 0055 if (strpos($id, $prefix) !== 0) { 0056 $id = $prefix . $id; 0057 } 0058 } elseif ($config->get('Attr.IDPrefixLocal') !== '') { 0059 trigger_error( 0060 '%Attr.IDPrefixLocal cannot be used unless ' . 0061 '%Attr.IDPrefix is set', 0062 E_USER_WARNING 0063 ); 0064 } 0065 0066 if (!$this->selector) { 0067 $id_accumulator =& $context->get('IDAccumulator'); 0068 if (isset($id_accumulator->ids[$id])) { 0069 return false; 0070 } 0071 } 0072 0073 // we purposely avoid using regex, hopefully this is faster 0074 0075 if ($config->get('Attr.ID.HTML5') === true) { 0076 if (preg_match('/[\t\n\x0b\x0c ]/', $id)) { 0077 return false; 0078 } 0079 } else { 0080 if (ctype_alpha($id)) { 0081 // OK 0082 } else { 0083 if (!ctype_alpha(@$id[0])) { 0084 return false; 0085 } 0086 // primitive style of regexps, I suppose 0087 $trim = trim( 0088 $id, 0089 'A..Za..z0..9:-._' 0090 ); 0091 if ($trim !== '') { 0092 return false; 0093 } 0094 } 0095 } 0096 0097 $regexp = $config->get('Attr.IDBlacklistRegexp'); 0098 if ($regexp && preg_match($regexp, $id)) { 0099 return false; 0100 } 0101 0102 if (!$this->selector) { 0103 $id_accumulator->add($id); 0104 } 0105 0106 // if no change was made to the ID, return the result 0107 // else, return the new id if stripping whitespace made it 0108 // valid, or return false. 0109 return $id; 0110 } 0111 } 0112 0113 // vim: et sw=4 sts=4