]>
Commit | Line | Data |
---|---|---|
f45a286b AD |
1 | <?php |
2 | ||
3 | /** | |
4 | * Validates the HTML attribute ID. | |
5 | * @warning Even though this is the id processor, it | |
6 | * will ignore the directive Attr:IDBlacklist, since it will only | |
7 | * go according to the ID accumulator. Since the accumulator is | |
8 | * automatically generated, it will have already absorbed the | |
9 | * blacklist. If you're hacking around, make sure you use load()! | |
10 | */ | |
11 | ||
12 | class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef | |
13 | { | |
14 | ||
dd205fba MK |
15 | // selector is NOT a valid thing to use for IDREFs, because IDREFs |
16 | // *must* target IDs that exist, whereas selector #ids do not. | |
17 | ||
18 | /** | |
19 | * Determines whether or not we're validating an ID in a CSS | |
20 | * selector context. | |
21 | */ | |
22 | protected $selector; | |
23 | ||
24 | public function __construct($selector = false) { | |
25 | $this->selector = $selector; | |
26 | } | |
f45a286b AD |
27 | |
28 | public function validate($id, $config, $context) { | |
29 | ||
dd205fba | 30 | if (!$this->selector && !$config->get('Attr.EnableID')) return false; |
f45a286b AD |
31 | |
32 | $id = trim($id); // trim it first | |
33 | ||
34 | if ($id === '') return false; | |
35 | ||
f4f0f80d | 36 | $prefix = $config->get('Attr.IDPrefix'); |
f45a286b | 37 | if ($prefix !== '') { |
f4f0f80d | 38 | $prefix .= $config->get('Attr.IDPrefixLocal'); |
f45a286b AD |
39 | // prevent re-appending the prefix |
40 | if (strpos($id, $prefix) !== 0) $id = $prefix . $id; | |
f4f0f80d | 41 | } elseif ($config->get('Attr.IDPrefixLocal') !== '') { |
f45a286b AD |
42 | trigger_error('%Attr.IDPrefixLocal cannot be used unless '. |
43 | '%Attr.IDPrefix is set', E_USER_WARNING); | |
44 | } | |
45 | ||
dd205fba | 46 | if (!$this->selector) { |
f45a286b AD |
47 | $id_accumulator =& $context->get('IDAccumulator'); |
48 | if (isset($id_accumulator->ids[$id])) return false; | |
dd205fba | 49 | } |
f45a286b AD |
50 | |
51 | // we purposely avoid using regex, hopefully this is faster | |
52 | ||
53 | if (ctype_alpha($id)) { | |
54 | $result = true; | |
55 | } else { | |
56 | if (!ctype_alpha(@$id[0])) return false; | |
57 | $trim = trim( // primitive style of regexps, I suppose | |
58 | $id, | |
59 | 'A..Za..z0..9:-._' | |
60 | ); | |
61 | $result = ($trim === ''); | |
62 | } | |
63 | ||
f4f0f80d | 64 | $regexp = $config->get('Attr.IDBlacklistRegexp'); |
f45a286b AD |
65 | if ($regexp && preg_match($regexp, $id)) { |
66 | return false; | |
67 | } | |
68 | ||
dd205fba | 69 | if (!$this->selector && $result) $id_accumulator->add($id); |
f45a286b AD |
70 | |
71 | // if no change was made to the ID, return the result | |
72 | // else, return the new id if stripping whitespace made it | |
73 | // valid, or return false. | |
74 | return $result ? $id : false; | |
75 | ||
76 | } | |
77 | ||
78 | } | |
79 | ||
80 | // vim: et sw=4 sts=4 |