1 : <?php
2 :
3 : /**
4 : * Validates the HTML attribute lang, effectively a language code.
5 : * @note Built according to RFC 3066, which obsoleted RFC 1766
6 : */
7 1 : class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef
8 : {
9 :
10 : public function validate($string, $config, $context) {
11 :
12 0 : $string = trim($string);
13 0 : if (!$string) return false;
14 :
15 0 : $subtags = explode('-', $string);
16 0 : $num_subtags = count($subtags);
17 :
18 0 : if ($num_subtags == 0) return false; // sanity check
19 :
20 : // process primary subtag : $subtags[0]
21 0 : $length = strlen($subtags[0]);
22 : switch ($length) {
23 0 : case 0:
24 0 : return false;
25 0 : case 1:
26 0 : if (! ($subtags[0] == 'x' || $subtags[0] == 'i') ) {
27 0 : return false;
28 : }
29 0 : break;
30 0 : case 2:
31 0 : case 3:
32 0 : if (! ctype_alpha($subtags[0]) ) {
33 0 : return false;
34 0 : } elseif (! ctype_lower($subtags[0]) ) {
35 0 : $subtags[0] = strtolower($subtags[0]);
36 0 : }
37 0 : break;
38 0 : default:
39 0 : return false;
40 0 : }
41 :
42 : $new_string = $subtags[0];
43 : if ($num_subtags == 1) return $new_string;
44 :
45 : // process second subtag : $subtags[1]
46 : $length = strlen($subtags[1]);
47 : if ($length == 0 || ($length == 1 && $subtags[1] != 'x') || $length > 8 || !ctype_alnum($subtags[1])) {
48 : return $new_string;
49 : }
50 : if (!ctype_lower($subtags[1])) $subtags[1] = strtolower($subtags[1]);
51 :
52 : $new_string .= '-' . $subtags[1];
53 : if ($num_subtags == 2) return $new_string;
54 :
55 : // process all other subtags, index 2 and up
56 : for ($i = 2; $i < $num_subtags; $i++) {
57 : $length = strlen($subtags[$i]);
58 : if ($length == 0 || $length > 8 || !ctype_alnum($subtags[$i])) {
59 : return $new_string;
60 : }
61 : if (!ctype_lower($subtags[$i])) {
62 : $subtags[$i] = strtolower($subtags[$i]);
63 : }
64 : $new_string .= '-' . $subtags[$i];
65 : }
66 :
67 : return $new_string;
68 :
69 : }
70 :
71 : }
72 :
|