]>
Commit | Line | Data |
---|---|---|
f45a286b AD |
1 | <?php |
2 | ||
3 | /** | |
4 | * Validates an IPv6 address. | |
5 | * @author Feyd @ forums.devnetwork.net (public domain) | |
6 | * @note This function requires brackets to have been removed from address | |
7 | * in URI. | |
8 | */ | |
9 | class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4 | |
10 | { | |
11 | ||
12 | public function validate($aIP, $config, $context) { | |
13 | ||
14 | if (!$this->ip4) $this->_loadRegex(); | |
15 | ||
16 | $original = $aIP; | |
17 | ||
18 | $hex = '[0-9a-fA-F]'; | |
19 | $blk = '(?:' . $hex . '{1,4})'; | |
20 | $pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128 | |
21 | ||
22 | // prefix check | |
23 | if (strpos($aIP, '/') !== false) | |
24 | { | |
25 | if (preg_match('#' . $pre . '$#s', $aIP, $find)) | |
26 | { | |
27 | $aIP = substr($aIP, 0, 0-strlen($find[0])); | |
28 | unset($find); | |
29 | } | |
30 | else | |
31 | { | |
32 | return false; | |
33 | } | |
34 | } | |
35 | ||
36 | // IPv4-compatiblity check | |
37 | if (preg_match('#(?<=:'.')' . $this->ip4 . '$#s', $aIP, $find)) | |
38 | { | |
39 | $aIP = substr($aIP, 0, 0-strlen($find[0])); | |
40 | $ip = explode('.', $find[0]); | |
41 | $ip = array_map('dechex', $ip); | |
42 | $aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3]; | |
43 | unset($find, $ip); | |
44 | } | |
45 | ||
46 | // compression check | |
47 | $aIP = explode('::', $aIP); | |
48 | $c = count($aIP); | |
49 | if ($c > 2) | |
50 | { | |
51 | return false; | |
52 | } | |
53 | elseif ($c == 2) | |
54 | { | |
55 | list($first, $second) = $aIP; | |
56 | $first = explode(':', $first); | |
57 | $second = explode(':', $second); | |
58 | ||
59 | if (count($first) + count($second) > 8) | |
60 | { | |
61 | return false; | |
62 | } | |
63 | ||
64 | while(count($first) < 8) | |
65 | { | |
66 | array_push($first, '0'); | |
67 | } | |
68 | ||
69 | array_splice($first, 8 - count($second), 8, $second); | |
70 | $aIP = $first; | |
71 | unset($first,$second); | |
72 | } | |
73 | else | |
74 | { | |
75 | $aIP = explode(':', $aIP[0]); | |
76 | } | |
77 | $c = count($aIP); | |
78 | ||
79 | if ($c != 8) | |
80 | { | |
81 | return false; | |
82 | } | |
83 | ||
84 | // All the pieces should be 16-bit hex strings. Are they? | |
85 | foreach ($aIP as $piece) | |
86 | { | |
87 | if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece))) | |
88 | { | |
89 | return false; | |
90 | } | |
91 | } | |
92 | ||
93 | return $original; | |
94 | ||
95 | } | |
96 | ||
97 | } | |
98 | ||
99 | // vim: et sw=4 sts=4 |