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