| 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 | class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef |
|---|
| 8 | { |
|---|
| 9 | |
|---|
| 10 | public function validate($string, $config, $context) { |
|---|
| 11 | |
|---|
| 12 | $string = trim($string); |
|---|
| 13 | if (!$string) return false; |
|---|
| 14 | |
|---|
| 15 | $subtags = explode('-', $string); |
|---|
| 16 | $num_subtags = count($subtags); |
|---|
| 17 | |
|---|
| 18 | if ($num_subtags == 0) return false; // sanity check |
|---|
| 19 | |
|---|
| 20 | // process primary subtag : $subtags[0] |
|---|
| 21 | $length = strlen($subtags[0]); |
|---|
| 22 | switch ($length) { |
|---|
| 23 | case 0: |
|---|
| 24 | return false; |
|---|
| 25 | case 1: |
|---|
| 26 | if (! ($subtags[0] == 'x' || $subtags[0] == 'i') ) { |
|---|
| 27 | return false; |
|---|
| 28 | } |
|---|
| 29 | break; |
|---|
| 30 | case 2: |
|---|
| 31 | case 3: |
|---|
| 32 | if (! ctype_alpha($subtags[0]) ) { |
|---|
| 33 | return false; |
|---|
| 34 | } elseif (! ctype_lower($subtags[0]) ) { |
|---|
| 35 | $subtags[0] = strtolower($subtags[0]); |
|---|
| 36 | } |
|---|
| 37 | break; |
|---|
| 38 | default: |
|---|
| 39 | return false; |
|---|
| 40 | } |
|---|
| 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 | |
|---|