Minor dependency updates
[yaffs-website] / vendor / ezyang / htmlpurifier / library / HTMLPurifier / AttrDef / CSS / Color.php
1 <?php
2
3 /**
4  * Validates Color as defined by CSS.
5  */
6 class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
7 {
8
9     /**
10      * @type HTMLPurifier_AttrDef_CSS_AlphaValue
11      */
12     protected $alpha;
13
14     public function __construct()
15     {
16         $this->alpha = new HTMLPurifier_AttrDef_CSS_AlphaValue();
17     }
18
19     /**
20      * @param string $color
21      * @param HTMLPurifier_Config $config
22      * @param HTMLPurifier_Context $context
23      * @return bool|string
24      */
25     public function validate($color, $config, $context)
26     {
27         static $colors = null;
28         if ($colors === null) {
29             $colors = $config->get('Core.ColorKeywords');
30         }
31
32         $color = trim($color);
33         if ($color === '') {
34             return false;
35         }
36
37         $lower = strtolower($color);
38         if (isset($colors[$lower])) {
39             return $colors[$lower];
40         }
41
42         if (preg_match('#(rgb|rgba|hsl|hsla)\(#', $color, $matches) === 1) {
43             $length = strlen($color);
44             if (strpos($color, ')') !== $length - 1) {
45                 return false;
46             }
47
48             // get used function : rgb, rgba, hsl or hsla
49             $function = $matches[1];
50
51             $parameters_size = 3;
52             $alpha_channel = false;
53             if (substr($function, -1) === 'a') {
54                 $parameters_size = 4;
55                 $alpha_channel = true;
56             }
57
58             /*
59              * Allowed types for values :
60              * parameter_position => [type => max_value]
61              */
62             $allowed_types = array(
63                 1 => array('percentage' => 100, 'integer' => 255),
64                 2 => array('percentage' => 100, 'integer' => 255),
65                 3 => array('percentage' => 100, 'integer' => 255),
66             );
67             $allow_different_types = false;
68
69             if (strpos($function, 'hsl') !== false) {
70                 $allowed_types = array(
71                     1 => array('integer' => 360),
72                     2 => array('percentage' => 100),
73                     3 => array('percentage' => 100),
74                 );
75                 $allow_different_types = true;
76             }
77
78             $values = trim(str_replace($function, '', $color), ' ()');
79
80             $parts = explode(',', $values);
81             if (count($parts) !== $parameters_size) {
82                 return false;
83             }
84
85             $type = false;
86             $new_parts = array();
87             $i = 0;
88
89             foreach ($parts as $part) {
90                 $i++;
91                 $part = trim($part);
92
93                 if ($part === '') {
94                     return false;
95                 }
96
97                 // different check for alpha channel
98                 if ($alpha_channel === true && $i === count($parts)) {
99                     $result = $this->alpha->validate($part, $config, $context);
100
101                     if ($result === false) {
102                         return false;
103                     }
104
105                     $new_parts[] = (string)$result;
106                     continue;
107                 }
108
109                 if (substr($part, -1) === '%') {
110                     $current_type = 'percentage';
111                 } else {
112                     $current_type = 'integer';
113                 }
114
115                 if (!array_key_exists($current_type, $allowed_types[$i])) {
116                     return false;
117                 }
118
119                 if (!$type) {
120                     $type = $current_type;
121                 }
122
123                 if ($allow_different_types === false && $type != $current_type) {
124                     return false;
125                 }
126
127                 $max_value = $allowed_types[$i][$current_type];
128
129                 if ($current_type == 'integer') {
130                     // Return value between range 0 -> $max_value
131                     $new_parts[] = (int)max(min($part, $max_value), 0);
132                 } elseif ($current_type == 'percentage') {
133                     $new_parts[] = (float)max(min(rtrim($part, '%'), $max_value), 0) . '%';
134                 }
135             }
136
137             $new_values = implode(',', $new_parts);
138
139             $color = $function . '(' . $new_values . ')';
140         } else {
141             // hexadecimal handling
142             if ($color[0] === '#') {
143                 $hex = substr($color, 1);
144             } else {
145                 $hex = $color;
146                 $color = '#' . $color;
147             }
148             $length = strlen($hex);
149             if ($length !== 3 && $length !== 6) {
150                 return false;
151             }
152             if (!ctype_xdigit($hex)) {
153                 return false;
154             }
155         }
156         return $color;
157     }
158
159 }
160
161 // vim: et sw=4 sts=4