Completed
Branch development (176841)
by Elk
06:59
created

DataValidator::_validate_limits()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
nc 16
nop 3
dl 0
loc 27
ccs 16
cts 16
cp 1
crap 6
rs 8.8657
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Used to validate and transform user supplied data from forms etc
5
 *
6
 * @package   ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
9
 *
10
 * @version 2.0 dev
11
 *
12
 */
13
14
namespace ElkArte;
15
16
/**
17
 * Class used to validate and transform data
18
 *
19
 * Initiate
20
 *    $validation = new \ElkArte\DataValidator();
21
 *
22
 * Set validation rules
23
 *    $validation->validation_rules(array(
24
 *      'username' => 'required|alpha_numeric|max_length[10]|min_length[6]',
25
 *      'email'    => 'required|valid_email'
26
 *    ));
27
 *
28
 * Set optional sanitation rules
29
 *    $validation->sanitation_rules(array(
30
 *      'username' => 'trim|strtoupper',
31
 *      'email'    => 'trim|gmail_normalize'
32
 *    ));
33
 *
34
 * Set optional variable name substitutions
35
 *    $validation->text_replacements(array(
36
 *      'username' => $txt['someThing'],
37
 *      'email'    => $txt['someEmail']
38
 *    ));
39
 *
40
 * Set optional special processing tags
41
 *    $validation->input_processing(array(
42
 *      'somefield'    => 'csv',
43
 *      'anotherfield' => 'array'
44
 *    ));
45
 *
46
 * Run the validation
47
 *    $validation->validate($data);
48
 * $data must be an array with keys matching the validation rule e.g. $data['username'], $data['email']
49
 *
50
 * Get the results
51
 *    $validation->validation_errors(optional array of fields to return errors on)
52
 *    $validation->validation_data()
53
 *    $validation->username
54
 *
55
 * Use it inline with the static method
56
 * $_POST['username'] = ' username '
57
 * if (\ElkArte\DataValidator::is_valid($_POST, array('username' => 'required|alpha_numeric'), array('username' => 'trim|strtoupper')))
58
 *    $username = $_POST['username'] // now = 'USERNAME'
59
 *
60
 * Current validation can be one or a combination of:
61
 *    max_length[x], min_length[x], length[x],
62
 *    alpha, alpha_numeric, alpha_dash
63
 *    numeric, integer, boolean, float, notequal[x,y,z], isarray, limits[min,max]
64
 *    valid_url, valid_ip, valid_ipv6, valid_email, valid_color
65
 *    php_syntax, contains[x,y,x], required, without[x,y,z]
66
 */
67
class DataValidator
68
{
69
	/**
70
	 * Validation rules
71
	 * @var mixed[]
72
	 */
73
	protected $_validation_rules = array();
74
75
	/**
76
	 * Sanitation rules
77
	 * @var mixed[]
78
	 */
79
	protected $_sanitation_rules = array();
80
81
	/**
82
	 * Text substitutions for field names in the error messages
83
	 * @var mixed[]
84
	 */
85
	protected $_replacements = array();
86
87
	/**
88
	 * Holds validation errors
89
	 * @var mixed[]
90
	 */
91
	protected $_validation_errors = array();
92
93
	/**
94
	 * Holds our data
95
	 * @var mixed[]
96
	 */
97
	protected $_data = array();
98
99
	/**
100
	 * Strict data processing,
101
	 * if true drops data for which no sanitation rule was set
102
	 * @var boolean
103
	 */
104
	protected $_strict = false;
105
106
	/**
107
	 * Holds any special processing that is required for certain fields
108
	 * csv or array
109
	 * @var string[]
110
	 */
111
	protected $_datatype = array();
112
113
	/**
114
	 * Allow reading otherwise inaccessible data values
115
	 *
116
	 * @param string $property key name of array value to return
117
	 *
118
	 * @return mixed|null
119
	 */
120 10
	public function __get($property)
121
	{
122 10
		return array_key_exists($property, $this->_data) ? $this->_data[$property] : null;
123
	}
124
125
	/**
126
	 * Allow testing data values for empty/isset
127
	 *
128
	 * @param string $property key name of array value to return
129
	 *
130
	 * @return bool
131
	 */
132
	public function __isset($property)
133
	{
134
		return isset($this->_data[$property]);
135
	}
136
137
	/**
138
	 * Shorthand static method for simple inline validation
139
	 *
140
	 * @param mixed[]|object $data generally $_POST data for this method
141
	 * @param mixed[] $validation_rules associative array of field => rules
142
	 * @param mixed[] $sanitation_rules associative array of field => rules
143
	 *
144
	 * @return bool
145
	 */
146 140
	public static function is_valid(&$data = array(), $validation_rules = array(), $sanitation_rules = array())
147
	{
148 140
		$validator = new DataValidator();
149
150
		// Set the rules
151 140
		$validator->sanitation_rules($sanitation_rules);
152 140
		$validator->validation_rules($validation_rules);
153
154
		// Run the test
155 140
		$result = $validator->validate($data);
156
157
		// Replace the data
158 140
		if (!empty($sanitation_rules))
159
		{
160
			// Handle cases where we have an object
161 6
			if (is_object($data))
162
			{
163
				$data = array_replace((array) $data, $validator->validation_data());
164
				$data = (object) $data;
165
			}
166
			else
167
			{
168 6
				$data = array_replace($data, $validator->validation_data());
169
			}
170
		}
171
172
		// Return true or false on valid data
173 140
		return $result;
174
	}
175
176
	/**
177
	 * Set the validation rules that will be run against the data
178
	 *
179
	 * @param mixed[] $rules associative array of field => rule|rule|rule
180
	 *
181
	 * @return mixed[]
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
182
	 */
183 156 View Code Duplication
	public function validation_rules($rules = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
	{
185
		// If its not an array, make it one
186 156
		if (!is_array($rules))
187
			$rules = array($rules);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $rules. This often makes code more readable.
Loading history...
188
189
		// Set the validation rules
190 156
		if (!empty($rules))
191 150
			$this->_validation_rules = $rules;
192
		else
193 6
			return $this->_validation_rules;
194 150
	}
195
196
	/**
197
	 * Sets the sanitation rules used to clean data
198
	 *
199
	 * @param mixed[] $rules associative array of field => rule|rule|rule
200
	 * @param boolean $strict
201
	 *
202
	 * @return mixed[]
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
203
	 */
204 160 View Code Duplication
	public function sanitation_rules($rules = array(), $strict = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
205
	{
206
		// If its not an array, make it one
207 160
		if (!is_array($rules))
208
			$rules = array($rules);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $rules. This often makes code more readable.
Loading history...
209
210
		// Set the sanitation rules
211 160
		$this->_strict = $strict;
212
213 160
		if (!empty($rules))
214 26
			$this->_sanitation_rules = $rules;
215
		else
216 134
			return $this->_sanitation_rules;
217 26
	}
218
219
	/**
220
	 * Field Name Replacements
221
	 *
222
	 * @param mixed[] $replacements associative array of field => txt string key
223
	 *
224
	 * @return mixed[]
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
225
	 */
226
	public function text_replacements($replacements = array())
227
	{
228
		if (!empty($replacements))
229
			$this->_replacements = $replacements;
230
		else
231
			return $this->_replacements;
232
	}
233
234
	/**
235
	 * Set special processing conditions for fields, such as (and only)
236
	 * csv or array
237
	 *
238
	 * @param string[] $datatype csv or array processing for the field
239
	 *
240
	 * @return string[]
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string[]?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
241
	 */
242 4
	public function input_processing($datatype = array())
243
	{
244 4
		if (!empty($datatype))
245 4
			$this->_datatype = $datatype;
246
		else
247
			return $this->_datatype;
248 4
	}
249
250
	/**
251
	 * Run the sanitation and validation on the data
252
	 *
253
	 * @param mixed[]|object $input associative array or object of data to process name => value
254
	 *
255
	 * @return bool
256
	 */
257 162
	public function validate($input)
258
	{
259
		// If its an object, convert it to an array
260 162
		if (is_object($input))
261
			$input = (array) $input;
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $input. This often makes code more readable.
Loading history...
262
263
		// @todo this won't work, $input[$field] will be undefined
264 162
		if (!is_array($input))
265
			$input[$input] = array($input);
266
267
		// Clean em
268 162
		$this->_data = $this->_sanitize($input, $this->_sanitation_rules);
269
270
		// Check em
271 162
		return $this->_validate($this->_data, $this->_validation_rules);
272
	}
273
274
	/**
275
	 * Return any errors found, either in the raw or nicely formatted
276
	 *
277
	 * @param mixed[]|string|boolean $raw
278
	 *    - true returns the raw error array,
279
	 *    - array returns just error messages of those fields
280
	 *    - string returns just that error message
281
	 *    - default is all error message(s)
282
	 *
283
	 * @return array|bool|mixed[]
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
284
	 */
285 4
	public function validation_errors($raw = false)
286
	{
287
		// Return the array
288 4
		if ($raw === true)
289 4
			return $this->_validation_errors;
290
		// Otherwise return the formatted text string(s)
291
		else
292 2
			return $this->_get_error_messages($raw);
293
	}
294
295
	/**
296
	 * Return the validation data, all or a specific key
297
	 *
298
	 * @param integer|string|null $key int or string
299
	 *
300
	 * @return mixed|mixed[]|null
301
	 */
302 14
	public function validation_data($key = null)
303
	{
304 14
		if ($key === null)
305 8
			return $this->_data;
306
307 6
		return isset($this->_data[$key]) ? $this->_data[$key] : null;
308
	}
309
310
	/**
311
	 * Performs data validation against the provided rule
312
	 *
313
	 * @param mixed[] $input
314
	 * @param mixed[] $ruleset
315
	 *
316
	 * @return bool
317
	 */
318 162
	private function _validate($input, $ruleset)
319
	{
320
		// No errors ... yet ;)
321 162
		$this->_validation_errors = array();
322
323
		// For each field, run our rules against the data
324 162
		foreach ($ruleset as $field => $rules)
325
		{
326
			// Special processing required on this field like csv or array?
327 150
			if (isset($this->_datatype[$field]) && in_array($this->_datatype[$field], array('csv', 'array')))
328 4
				$this->_validate_recursive($input, $field, $rules);
329
			else
330
			{
331
				// Get rules for this field
332 150
				$rules = explode('|', $rules);
333 150
				foreach ($rules as $rule)
334
				{
335 150
					$validation_parameters = null;
336 150
					$validation_parameters_function = array();
337
338
					// Were any parameters provided for the rule, e.g. min_length[6]
339 150
					if (preg_match('~(.*)\[(.*)\]~', $rule, $match))
340
					{
341 16
						$validation_method = '_validate_' . $match[1];
342 16
						$validation_parameters = $match[2];
343 16
						$validation_function = $match[1];
344 16
						$validation_parameters_function = explode(',', $match[2]);
345
					}
346
					// Or just a predefined rule e.g. valid_email
347
					else
348
					{
349 148
						$validation_method = '_validate_' . $rule;
350 148
						$validation_function = $rule;
351
					}
352
353
					// Defined method to use?
354 150
					if (is_callable(array($this, $validation_method)))
355 150
						$result = $this->{$validation_method}($field, $input, $validation_parameters);
0 ignored issues
show
Security Code Execution introduced by
$validation_method can contain request data and is used in code execution context(s) leading to a potential security vulnerability.

3 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST is passed to DataValidator::is_valid() in sources/ElkArte/Controller/Post.php on line 900
  1. Read from $_POST, and $_POST is passed to DataValidator::is_valid()
    in sources/ElkArte/Controller/Post.php on line 900
  2. $data is passed to DataValidator::validate()
    in sources/ElkArte/DataValidator.php on line 155
  3. DataValidator::$_data is assigned
    in sources/ElkArte/DataValidator.php on line 268
  4. Tainted property DataValidator::$_data is read, and $this->_data is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  5. $input is passed to DataValidator::_validate_recursive()
    in sources/ElkArte/DataValidator.php on line 328
  6. $key is assigned
    in sources/ElkArte/DataValidator.php on line 402
  7. $validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 404
  8. $validation_rules is passed to DataValidator::validation_rules()
    in sources/ElkArte/DataValidator.php on line 421
  9. DataValidator::$_validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 191
  10. Tainted property DataValidator::$_validation_rules is read, and $this->_validation_rules is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  11. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 324
  12. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 332
  13. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 333
  14. $validation_method is assigned
    in sources/ElkArte/DataValidator.php on line 349
  2. Path: Read from $_REQUEST, and $context is assigned in sources/ElkArte/Controller/Post.php on line 320
  1. Read from $_REQUEST, and $context is assigned
    in sources/ElkArte/Controller/Post.php on line 320
  2. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 351
  3. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 352
  4. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 353
  5. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 366
  6. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 367
  7. $context['name'] is passed to ValuesContainer::__set()
    in sources/ElkArte/Controller/Post.php on line -1
  8. ValuesContainer::$data is assigned
    in sources/ElkArte/ValuesContainer.php on line 53
  9. Tainted property ValuesContainer::$data is read
    in sources/ElkArte/ValuesContainer.php on line 65
  10. ValuesContainer::__get() returns tainted data, and $str is assigned
    in sources/Subs.php on line 456
  11. $str is passed through strftime()
    in sources/Subs.php on line 492
  12. standardTime() returns tainted data, and $cur_data is assigned
    in sources/ElkArte/GenericList.php on line 338
  13. $cur_row is assigned
    in sources/ElkArte/GenericList.php on line 349
  14. GenericList::$context is assigned
    in sources/ElkArte/GenericList.php on line 365
  15. Tainted property GenericList::$context is read, and $this->context['start_var_name'] is passed to HttpReq::getQuery()
    in sources/ElkArte/GenericList.php on line 228
  16. HttpReq::$_param is assigned
    in sources/ElkArte/HttpReq.php on line 282
  17. Tainted property HttpReq::$_param is read, and $this->_param is passed to DataValidator::validate()
    in sources/ElkArte/HttpReq.php on line 382
  18. DataValidator::$_data is assigned
    in sources/ElkArte/DataValidator.php on line 268
  19. Tainted property DataValidator::$_data is read, and $this->_data is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  20. $input is passed to DataValidator::_validate_recursive()
    in sources/ElkArte/DataValidator.php on line 328
  21. $key is assigned
    in sources/ElkArte/DataValidator.php on line 402
  22. $validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 404
  23. $validation_rules is passed to DataValidator::validation_rules()
    in sources/ElkArte/DataValidator.php on line 421
  24. DataValidator::$_validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 191
  25. Tainted property DataValidator::$_validation_rules is read, and $this->_validation_rules is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  26. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 324
  27. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 332
  28. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 333
  29. $validation_method is assigned
    in sources/ElkArte/DataValidator.php on line 349
  3. Path: Read from $_POST in sources/ElkArte/Controller/Post.php on line 946
  1. Read from $_POST
    in sources/ElkArte/Controller/Post.php on line 946
  2. $_POST['guestname'] is passed to ValuesContainer::__set()
    in sources/ElkArte/Controller/Post.php on line -1
  3. ValuesContainer::$data is assigned
    in sources/ElkArte/ValuesContainer.php on line 53
  4. Tainted property ValuesContainer::$data is read
    in sources/ElkArte/ValuesContainer.php on line 65
  5. ValuesContainer::__get() returns tainted data, and $str is assigned
    in sources/Subs.php on line 456
  6. $str is passed through strftime()
    in sources/Subs.php on line 492
  7. standardTime() returns tainted data, and $cur_data is assigned
    in sources/ElkArte/GenericList.php on line 338
  8. $cur_row is assigned
    in sources/ElkArte/GenericList.php on line 349
  9. GenericList::$context is assigned
    in sources/ElkArte/GenericList.php on line 365
  10. Tainted property GenericList::$context is read, and $this->context['start_var_name'] is passed to HttpReq::getQuery()
    in sources/ElkArte/GenericList.php on line 228
  11. HttpReq::$_param is assigned
    in sources/ElkArte/HttpReq.php on line 282
  12. Tainted property HttpReq::$_param is read, and $this->_param is passed to DataValidator::validate()
    in sources/ElkArte/HttpReq.php on line 382
  13. DataValidator::$_data is assigned
    in sources/ElkArte/DataValidator.php on line 268
  14. Tainted property DataValidator::$_data is read, and $this->_data is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  15. $input is passed to DataValidator::_validate_recursive()
    in sources/ElkArte/DataValidator.php on line 328
  16. $key is assigned
    in sources/ElkArte/DataValidator.php on line 402
  17. $validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 404
  18. $validation_rules is passed to DataValidator::validation_rules()
    in sources/ElkArte/DataValidator.php on line 421
  19. DataValidator::$_validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 191
  20. Tainted property DataValidator::$_validation_rules is read, and $this->_validation_rules is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  21. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 324
  22. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 332
  23. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 333
  24. $validation_method is assigned
    in sources/ElkArte/DataValidator.php on line 349

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
356
					// Maybe even a custom function set up like a defined one, addons can do this.
357 2
					elseif (is_callable($validation_function) && strpos($validation_function, 'validate_') === 0 && isset($input[$field]))
358 2
						$result = call_user_func_array($validation_function, array_merge((array) $field, (array) $input[$field], $validation_parameters_function));
0 ignored issues
show
Security Code Execution introduced by
$validation_function can contain request data and is used in code execution context(s) leading to a potential security vulnerability.

3 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST is passed to DataValidator::is_valid() in sources/ElkArte/Controller/Post.php on line 900
  1. Read from $_POST, and $_POST is passed to DataValidator::is_valid()
    in sources/ElkArte/Controller/Post.php on line 900
  2. $data is passed to DataValidator::validate()
    in sources/ElkArte/DataValidator.php on line 155
  3. DataValidator::$_data is assigned
    in sources/ElkArte/DataValidator.php on line 268
  4. Tainted property DataValidator::$_data is read, and $this->_data is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  5. $input is passed to DataValidator::_validate_recursive()
    in sources/ElkArte/DataValidator.php on line 328
  6. $key is assigned
    in sources/ElkArte/DataValidator.php on line 402
  7. $validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 404
  8. $validation_rules is passed to DataValidator::validation_rules()
    in sources/ElkArte/DataValidator.php on line 421
  9. DataValidator::$_validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 191
  10. Tainted property DataValidator::$_validation_rules is read, and $this->_validation_rules is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  11. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 324
  12. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 332
  13. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 333
  14. $validation_function is assigned
    in sources/ElkArte/DataValidator.php on line 350
  2. Path: Read from $_REQUEST, and $context is assigned in sources/ElkArte/Controller/Post.php on line 320
  1. Read from $_REQUEST, and $context is assigned
    in sources/ElkArte/Controller/Post.php on line 320
  2. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 351
  3. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 352
  4. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 353
  5. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 366
  6. $context is assigned
    in sources/ElkArte/Controller/Post.php on line 367
  7. $context['name'] is passed to ValuesContainer::__set()
    in sources/ElkArte/Controller/Post.php on line -1
  8. ValuesContainer::$data is assigned
    in sources/ElkArte/ValuesContainer.php on line 53
  9. Tainted property ValuesContainer::$data is read
    in sources/ElkArte/ValuesContainer.php on line 65
  10. ValuesContainer::__get() returns tainted data, and $str is assigned
    in sources/Subs.php on line 456
  11. $str is passed through strftime()
    in sources/Subs.php on line 492
  12. standardTime() returns tainted data, and $cur_data is assigned
    in sources/ElkArte/GenericList.php on line 338
  13. $cur_row is assigned
    in sources/ElkArte/GenericList.php on line 349
  14. GenericList::$context is assigned
    in sources/ElkArte/GenericList.php on line 365
  15. Tainted property GenericList::$context is read, and $this->context['start_var_name'] is passed to HttpReq::getQuery()
    in sources/ElkArte/GenericList.php on line 228
  16. HttpReq::$_param is assigned
    in sources/ElkArte/HttpReq.php on line 282
  17. Tainted property HttpReq::$_param is read, and $this->_param is passed to DataValidator::validate()
    in sources/ElkArte/HttpReq.php on line 382
  18. DataValidator::$_data is assigned
    in sources/ElkArte/DataValidator.php on line 268
  19. Tainted property DataValidator::$_data is read, and $this->_data is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  20. $input is passed to DataValidator::_validate_recursive()
    in sources/ElkArte/DataValidator.php on line 328
  21. $key is assigned
    in sources/ElkArte/DataValidator.php on line 402
  22. $validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 404
  23. $validation_rules is passed to DataValidator::validation_rules()
    in sources/ElkArte/DataValidator.php on line 421
  24. DataValidator::$_validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 191
  25. Tainted property DataValidator::$_validation_rules is read, and $this->_validation_rules is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  26. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 324
  27. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 332
  28. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 333
  29. $validation_function is assigned
    in sources/ElkArte/DataValidator.php on line 350
  3. Path: Read from $_POST in sources/ElkArte/Controller/Post.php on line 946
  1. Read from $_POST
    in sources/ElkArte/Controller/Post.php on line 946
  2. $_POST['guestname'] is passed to ValuesContainer::__set()
    in sources/ElkArte/Controller/Post.php on line -1
  3. ValuesContainer::$data is assigned
    in sources/ElkArte/ValuesContainer.php on line 53
  4. Tainted property ValuesContainer::$data is read
    in sources/ElkArte/ValuesContainer.php on line 65
  5. ValuesContainer::__get() returns tainted data, and $str is assigned
    in sources/Subs.php on line 456
  6. $str is passed through strftime()
    in sources/Subs.php on line 492
  7. standardTime() returns tainted data, and $cur_data is assigned
    in sources/ElkArte/GenericList.php on line 338
  8. $cur_row is assigned
    in sources/ElkArte/GenericList.php on line 349
  9. GenericList::$context is assigned
    in sources/ElkArte/GenericList.php on line 365
  10. Tainted property GenericList::$context is read, and $this->context['start_var_name'] is passed to HttpReq::getQuery()
    in sources/ElkArte/GenericList.php on line 228
  11. HttpReq::$_param is assigned
    in sources/ElkArte/HttpReq.php on line 282
  12. Tainted property HttpReq::$_param is read, and $this->_param is passed to DataValidator::validate()
    in sources/ElkArte/HttpReq.php on line 382
  13. DataValidator::$_data is assigned
    in sources/ElkArte/DataValidator.php on line 268
  14. Tainted property DataValidator::$_data is read, and $this->_data is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  15. $input is passed to DataValidator::_validate_recursive()
    in sources/ElkArte/DataValidator.php on line 328
  16. $key is assigned
    in sources/ElkArte/DataValidator.php on line 402
  17. $validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 404
  18. $validation_rules is passed to DataValidator::validation_rules()
    in sources/ElkArte/DataValidator.php on line 421
  19. DataValidator::$_validation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 191
  20. Tainted property DataValidator::$_validation_rules is read, and $this->_validation_rules is passed to DataValidator::_validate()
    in sources/ElkArte/DataValidator.php on line 271
  21. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 324
  22. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 332
  23. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 333
  24. $validation_function is assigned
    in sources/ElkArte/DataValidator.php on line 350

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
359
					else
360
						$result = array(
361
							'field' => $validation_method,
362
							'input' => isset($input[$field]) ? $input[$field] : null,
363
							'function' => '_validate_invalid_function',
364
							'param' => $validation_parameters
365
						);
366
367 150
					if (is_array($result))
368 109
						$this->_validation_errors[] = $result;
369
				}
370
			}
371
		}
372
373 162
		return count($this->_validation_errors) === 0 ? true : false;
374
	}
375
376
	/**
377
	 * Used when a field contains csv or array of data
378
	 *
379
	 * -Will convert field to individual elements and run a separate validation on that group
380
	 * using the rules defined to the parent node
381
	 *
382
	 * @param mixed[] $input
383
	 * @param string $field
384
	 * @param string $rules
385
	 *
386
	 * @return bool|void
387
	 */
388 4
	private function _validate_recursive($input, $field, $rules)
389
	{
390 4
		if (!isset($input[$field]))
391
			return;
392
393
		// Start a new instance of the validator to work on this sub data (csv/array)
394 4
		$sub_validator = new DataValidator();
395
396 4
		$fields = array();
397 4
		$validation_rules = array();
398
399 4
		if ($this->_datatype[$field] === 'array')
400
		{
401
			// Convert the array to individual values, they all use the same rules
402 2 View Code Duplication
			foreach ($input[$field] as $key => $value)
403
			{
404 2
				$validation_rules[$key] = $rules;
405 2
				$fields[$key] = $value;
406
			}
407
		}
408
		// CSV is much the same process as array
409 4
		elseif ($this->_datatype[$field] === 'csv')
410
		{
411
			// Blow it up!
412 4
			$temp = explode(',', $input[$field]);
413 4
			foreach ($temp as $key => $value)
414
			{
415 4
				$validation_rules[$key] = $rules;
416 4
				$fields[$key] = $value;
417
			}
418
		}
419
420
		// Validate each "new" field
421 4
		$sub_validator->validation_rules($validation_rules);
422 4
		$result = $sub_validator->validate($fields);
423
424
		// If its not valid, then just take the first error and use it for the original field
425 4
		if (!$result)
426
		{
427 4
			$errors = $sub_validator->validation_errors(true);
428 4
			foreach ($errors as $error)
0 ignored issues
show
Bug introduced by
The expression $errors of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
429
			{
430 4
				$this->_validation_errors[] = array(
431 4
					'field' => $field,
432 4
					'input' => $error['input'],
433 4
					'function' => $error['function'],
434 4
					'param' => $error['param'],
435
				);
436
			}
437
		}
438
439 4
		return $result;
440
	}
441
442
	/**
443
	 * Data sanitation is a good thing
444
	 *
445
	 * @param mixed[] $input
446
	 * @param mixed[] $ruleset
447
	 * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
448
	 */
449 162
	private function _sanitize($input, $ruleset)
450
	{
451
		// For each field, run our set of rules against the data
452 162
		foreach ($ruleset as $field => $rules)
453
		{
454
			// Data for which we don't have rules
455 26
			if (!array_key_exists($field, $input))
456
			{
457
				if ($this->_strict)
458
					unset($input[$field]);
459
460
				continue;
461
			}
462
463
			// Is this a special processing field like csv or array?
464 26
			if (isset($this->_datatype[$field]) && in_array($this->_datatype[$field], array('csv', 'array')))
465 2
				$input[$field] = $this->_sanitize_recursive($input, $field, $rules);
466
			else
467
			{
468
				// Rules for which we do have data
469 26
				$rules = explode('|', $rules);
470 26
				foreach ($rules as $rule)
471
				{
472 26
					$sanitation_parameters = null;
473 26
					$sanitation_parameters_function = array();
474
475
					// Were any parameters provided for the rule, e.g. \ElkArte\Util::htmlspecialchars[ENT_QUOTES]
476 26
					if (preg_match('~(.*)\[(.*)\]~', $rule, $match))
477
					{
478 4
						$sanitation_method = '_sanitation_' . $match[1];
479 4
						$sanitation_parameters = $match[2];
480 4
						$sanitation_function = $match[1];
481 4
						$sanitation_parameters_function = explode(',', defined($match[2]) ? constant($match[2]) : $match[2]);
482
					}
483
					// Or just a predefined rule e.g. trim
484
					else
485
					{
486 22
						$sanitation_method = '_sanitation_' . $rule;
487 22
						$sanitation_function = $rule;
488
					}
489
490
					// Defined method to use?
491 26
					if (is_callable(array($this, $sanitation_method)))
492
						$input[$field] = $this->{$sanitation_method}($input[$field], $sanitation_parameters);
0 ignored issues
show
Security Code Execution introduced by
$sanitation_method can contain request data and is used in code execution context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST, and $_POST is passed to DataValidator::is_valid()
    in sources/ElkArte/Controller/Post.php on line 900
  2. $data is passed to DataValidator::validate()
    in sources/ElkArte/DataValidator.php on line 155
  3. $input is passed to DataValidator::_sanitize()
    in sources/ElkArte/DataValidator.php on line 268
  4. $input is passed to DataValidator::_sanitize_recursive()
    in sources/ElkArte/DataValidator.php on line 465
  5. $key is assigned
    in sources/ElkArte/DataValidator.php on line 546
  6. $sanitation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 548
  7. $sanitation_rules is passed to DataValidator::sanitation_rules()
    in sources/ElkArte/DataValidator.php on line 553
  8. DataValidator::$_sanitation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 214
  9. Tainted property DataValidator::$_sanitation_rules is read, and $this->_sanitation_rules is passed to DataValidator::_sanitize()
    in sources/ElkArte/DataValidator.php on line 268
  10. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 452
  11. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 469
  12. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 470
  13. $sanitation_method is assigned
    in sources/ElkArte/DataValidator.php on line 486

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
493
					// One of our static methods or even a built in php function like strtoupper, intval, etc?
494 26
					elseif (is_callable($sanitation_function))
495 26
						$input[$field] = call_user_func_array($sanitation_function, array_merge((array) $input[$field], $sanitation_parameters_function));
0 ignored issues
show
Security Code Execution introduced by
$sanitation_function can contain request data and is used in code execution context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST, and $_POST is passed to DataValidator::is_valid()
    in sources/ElkArte/Controller/Post.php on line 900
  2. $data is passed to DataValidator::validate()
    in sources/ElkArte/DataValidator.php on line 155
  3. $input is passed to DataValidator::_sanitize()
    in sources/ElkArte/DataValidator.php on line 268
  4. $input is passed to DataValidator::_sanitize_recursive()
    in sources/ElkArte/DataValidator.php on line 465
  5. $key is assigned
    in sources/ElkArte/DataValidator.php on line 546
  6. $sanitation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 548
  7. $sanitation_rules is passed to DataValidator::sanitation_rules()
    in sources/ElkArte/DataValidator.php on line 553
  8. DataValidator::$_sanitation_rules is assigned
    in sources/ElkArte/DataValidator.php on line 214
  9. Tainted property DataValidator::$_sanitation_rules is read, and $this->_sanitation_rules is passed to DataValidator::_sanitize()
    in sources/ElkArte/DataValidator.php on line 268
  10. $rules is assigned
    in sources/ElkArte/DataValidator.php on line 452
  11. $rules is passed through explode(), and $rules is assigned
    in sources/ElkArte/DataValidator.php on line 469
  12. $rule is assigned
    in sources/ElkArte/DataValidator.php on line 470
  13. $sanitation_function is assigned
    in sources/ElkArte/DataValidator.php on line 487

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
496
					// Or even a language construct?
497
					elseif (in_array($sanitation_function, array('empty', 'array', 'isset')))
498
					{
499
						// could be done as methods instead ...
500
						switch ($sanitation_function)
501
						{
502
							case 'empty':
503
								$input[$field] = empty($input[$field]);
504
								break;
505
							case 'array':
506
								$input[$field] = is_array($input[$field]) ? $input[$field] : array($input[$field]);
507
								break;
508
							case 'isset':
509
								$input[$field] = isset($input[$field]);
510
								break;
511
						}
512
					}
513
					else
514 12
					{
515
						// @todo fatal_error or other ? being asked to do something we don't know?
516
						// results in returning $input[$field] = $input[$field];
517
					}
518
				}
519
			}
520
		}
521
522 162
		return $input;
523
	}
524
525
	/**
526
	 * When the input field is an array or csv, this will build a new validator
527
	 * as if the fields were individual ones, each checked against the base rule
528
	 *
529
	 * @param mixed[] $input
530
	 * @param string $field
531
	 * @param string $rules
532
	 *
533
	 * @return mixed
534
	 */
535 2
	private function _sanitize_recursive($input, $field, $rules)
536
	{
537
		// create a new instance to run against this sub data
538 2
		$validator = new DataValidator();
539
540 2
		$fields = array();
541 2
		$sanitation_rules = array();
542
543 2
		if ($this->_datatype[$field] === 'array')
544
		{
545
			// Convert the array to individual values, they all use the same rules
546 View Code Duplication
			foreach ($input[$field] as $key => $value)
547
			{
548
				$sanitation_rules[$key] = $rules;
549
				$fields[$key] = $value;
550
			}
551
552
			// Sanitize each "new" field
553
			$validator->sanitation_rules($sanitation_rules);
554
			$validator->validate($fields);
555
556
			// Take the individual results and replace them in the original array
557
			$input[$field] = array_replace($input[$field], $validator->validation_data());
558
		}
559 2
		elseif ($this->_datatype[$field] === 'csv')
560
		{
561
			// Break up the CSV data so we have an array
562 2
			$temp = explode(',', $input[$field]);
563 2
			foreach ($temp as $key => $value)
564
			{
565 2
				$sanitation_rules[$key] = $rules;
566 2
				$fields[$key] = $value;
567
			}
568
569
			// Sanitize each "new" field
570 2
			$validator->sanitation_rules($sanitation_rules);
571 2
			$validator->validate($fields);
572
573
			// Put it back together with clean data
574 2
			$input[$field] = implode(',', $validator->validation_data());
575
		}
576
577 2
		return $input[$field];
578
	}
579
580
	/**
581
	 * Process any errors and return the error strings
582
	 *
583
	 * @param mixed[]|boolean $keys
584
	 *
585
	 * @return array|bool
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
586
	 */
587 2
	private function _get_error_messages($keys)
588
	{
589 2
		global $txt;
590
591 2
		if (empty($this->_validation_errors))
592 2
			return false;
593
594 2
		theme()->getTemplates()->loadLanguageFile('Validation');
595 2
		$result = array();
596
597
		// Just want specific errors then it must be an array
598 2
		if (!empty($keys) && !is_array($keys))
599 2
			$keys = array($keys);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $keys. This often makes code more readable.
Loading history...
600
601 2
		foreach ($this->_validation_errors as $error)
602
		{
603
			// Field name substitution supplied?
604 2
			$field = isset($this->_replacements[$error['field']]) ? $this->_replacements[$error['field']] : $error['field'];
605
606
			// Just want specific field errors returned?
607 2
			if (!empty($keys) && is_array($keys) && !in_array($error['field'], $keys))
608 2
				continue;
609
610
			// Set the error message for this validation failure
611 2
			if (isset($error['error']))
612 2
				$result[] = sprintf($txt[$error['error']], $field, $error['error_msg']);
613
			// Use our error text based on the function name itself
614 2
			elseif (isset($txt[$error['function']]))
615
			{
616 2
				if (!empty($error['param']))
617 2
					$result[] = sprintf($txt[$error['function']], $field, $error['param']);
618
				else
619 2
					$result[] = sprintf($txt[$error['function']], $field, $error['input']);
620
			}
621
			// can't find the function text, so set a generic one
622
			else
623 2
				$result[] = sprintf($txt['_validate_generic'], $field);
624
		}
625
626 2
		return empty($result) ? false : $result;
627
	}
628
629
	/**
630
	 * Contains ... Verify that a value is one of those provided (case insensitive)
631
	 *
632
	 * Usage: '[key]' => 'contains[value, value, value]'
633
	 *
634
	 * @param string $field
635
	 * @param mixed[] $input
636
	 * @param string|null $validation_parameters array or null
637
	 *
638
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
639
	 */
640 8 View Code Duplication
	protected function _validate_contains($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
641
	{
642 8
		$validation_parameters = array_map('trim', explode(',', strtolower($validation_parameters)));
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $validation_parameters. This often makes code more readable.
Loading history...
643 8
		$input[$field] = isset($input[$field]) ? $input[$field] : '';
644 8
		$value = trim(strtolower($input[$field]));
645
646 8
		if (in_array($value, $validation_parameters))
647 8
			return;
648
649
		return array(
650 2
			'field' => $field,
651 2
			'input' => $input[$field],
652
			'function' => __FUNCTION__,
653 2
			'param' => implode(',', $validation_parameters)
654
		);
655
	}
656
657
	/**
658
	 * NotEqual ... Verify that a value does equal any values in list (case insensitive)
659
	 *
660
	 * Usage: '[key]' => 'notequal[value, value, value]'
661
	 *
662
	 * @param string $field
663
	 * @param mixed[] $input
664
	 * @param string|null $validation_parameters array or null
665
	 *
666
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
667
	 */
668 6 View Code Duplication
	protected function _validate_notequal($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
669
	{
670 6
		$validation_parameters = explode(',', trim(strtolower($validation_parameters)));
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $validation_parameters. This often makes code more readable.
Loading history...
671 6
		$input[$field] = isset($input[$field]) ? $input[$field] : '';
672 6
		$value = trim(strtolower($input[$field]));
673
674 6
		if (!in_array($value, $validation_parameters))
675 6
			return;
676
677
		return array(
678 2
			'field' => $field,
679 2
			'input' => $input[$field],
680
			'function' => __FUNCTION__,
681 2
			'param' => implode(',', $validation_parameters)
682
		);
683
	}
684
685
	/**
686
	 * Limits ... Verify that a value is within the defined limits
687
	 *
688
	 * Usage: '[key]' => 'limits[min, max]'
689
	 * >= min and <= max
690
	 * Limits may be specified one sided
691
	 *  - limits[,10] means <=10 with no lower bound check
692
	 *  - limits[10,] means >= 10 with no upper bound
693
	 *
694
	 * @param string $field
695
	 * @param mixed[] $input
696
	 * @param string|null $validation_parameters array or null
697
	 *
698
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
699
	 */
700 4
	protected function _validate_limits($field, $input, $validation_parameters = null)
701
	{
702 4
		$validation_parameters = explode(',', $validation_parameters);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $validation_parameters. This often makes code more readable.
Loading history...
703 4
		$validation_parameters = array_filter($validation_parameters, 'strlen');
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $validation_parameters. This often makes code more readable.
Loading history...
704 4
		$input[$field] = isset($input[$field]) ? $input[$field] : '';
705 4
		$value = $input[$field];
706
707
		// Lower bound ?
708 4
		$passmin = true;
709 4
		if (isset($validation_parameters[0]))
710 4
			$passmin = $value >= $validation_parameters[0];
711
712
		// Upper bound ?
713 4
		$passmax = true;
714 4
		if (isset($validation_parameters[1]))
715 4
			$passmax = $value <= $validation_parameters[1];
716
717 4
		if ($passmax && $passmin)
718 4
			return;
719
720
		return array(
721 4
			'field' => $field,
722 4
			'input' => $input[$field],
723
			'function' => __FUNCTION__,
724 4
			'param' => implode(',', $validation_parameters)
725
		);
726
	}
727
728
	/**
729
	 * Without ... Verify that a value does contain any characters/values in list
730
	 *
731
	 * Usage: '[key]' => 'without[value, value, value]'
732
	 *
733
	 * @param string $field
734
	 * @param mixed[] $input
735
	 * @param mixed[]|null $validation_parameters array or null
736
	 *
737
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
738
	 */
739 4
	protected function _validate_without($field, $input, $validation_parameters = null)
740
	{
741 4
		$validation_parameters = explode(',', $validation_parameters);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $validation_parameters. This often makes code more readable.
Loading history...
742 4
		$input[$field] = isset($input[$field]) ? $input[$field] : '';
743 4
		$value = $input[$field];
744
745 4
		foreach ($validation_parameters as $dummy => $check)
746
		{
747 4
			if (strpos($value, $check) !== false)
748
				return array(
749 4
					'field' => $field,
750 4
					'input' => $input[$field],
751
					'function' => __FUNCTION__,
752 4
					'param' => implode(',', $validation_parameters)
753
				);
754
		}
755
756 4
		return;
757
	}
758
759
	/**
760
	 * required ... Check if the specified key is present and not empty
761
	 *
762
	 * Usage: '[key]' => 'required'
763
	 *
764
	 * @param string $field
765
	 * @param mixed[] $input
766
	 * @param mixed[]|null $validation_parameters array or null
767
	 *
768
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
769
	 */
770 12
	protected function _validate_required($field, $input, $validation_parameters = null)
771
	{
772 12
		if (isset($input[$field]) && trim($input[$field]) !== '')
773 12
			return;
774
775
		return array(
776 2
			'field' => $field,
777 2
			'input' => isset($input[$field]) ? $input[$field] : '',
778
			'function' => __FUNCTION__,
779 2
			'param' => $validation_parameters
780
		);
781
	}
782
783
	/**
784
	 * valid_email .... Determine if the provided email is valid
785
	 *
786
	 * Usage: '[key]' => 'valid_email'
787
	 *
788
	 * @param string $field
789
	 * @param mixed[] $input
790
	 * @param mixed[]|null $validation_parameters array or null
791
	 *
792
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
793
	 */
794 8
	protected function _validate_valid_email($field, $input, $validation_parameters = null)
795
	{
796 8
		if (!isset($input[$field]))
797
			return;
798
799
		// Quick check, no @ in the email
800 8
		if (strrpos($input[$field], '@') === false)
801 2
			$valid = false;
802
		else
803 8
			$valid = filter_var($input[$field], FILTER_VALIDATE_EMAIL) !== false;
804
805 8
		if ($valid)
806 8
			return;
807
808
		return array(
809 2
			'field' => $field,
810 2
			'input' => $input[$field],
811
			'function' => __FUNCTION__,
812 2
			'param' => $validation_parameters
813
		);
814
	}
815
816
	/**
817
	 * max_length ... Determine if the provided value length is less or equal to a specific value
818
	 *
819
	 * Usage: '[key]' => 'max_length[x]'
820
	 *
821
	 * @param string $field
822
	 * @param mixed[] $input
823
	 * @param mixed[]|null $validation_parameters array or null
824
	 *
825
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
826
	 */
827 8
	protected function _validate_max_length($field, $input, $validation_parameters = null)
828
	{
829 8
		if (!isset($input[$field]))
830
			return;
831
832 8
		if (Util::strlen($input[$field]) <= (int) $validation_parameters)
833 8
			return;
834
835
		return array(
836 2
			'field' => $field,
837 2
			'input' => $input[$field],
838
			'function' => __FUNCTION__,
839 2
			'param' => $validation_parameters
840
		);
841
	}
842
843
	/**
844
	 * min_length Determine if the provided value length is greater than or equal to a specific value
845
	 *
846
	 * Usage: '[key]' => 'min_length[x]'
847
	 *
848
	 * @param string $field
849
	 * @param mixed[] $input
850
	 * @param mixed[]|null $validation_parameters array or null
851
	 *
852
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
853
	 */
854 2
	protected function _validate_min_length($field, $input, $validation_parameters = null)
855
	{
856 2
		if (!isset($input[$field]))
857
			return;
858
859 2
		if (Util::strlen($input[$field]) >= (int) $validation_parameters)
860 2
			return;
861
862
		return array(
863 2
			'field' => $field,
864 2
			'input' => $input[$field],
865
			'function' => __FUNCTION__,
866 2
			'param' => $validation_parameters
867
		);
868
	}
869
870
	/**
871
	 * length ... Determine if the provided value length matches a specific value
872
	 *
873
	 * Usage: '[key]' => 'exact_length[x]'
874
	 *
875
	 * @param string $field
876
	 * @param mixed[] $input
877
	 * @param mixed[]|null $validation_parameters array or null
878
	 *
879
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
880
	 */
881 2
	protected function _validate_length($field, $input, $validation_parameters = null)
882
	{
883 2
		if (!isset($input[$field]))
884
			return;
885
886 2
		if (Util::strlen($input[$field]) == (int) $validation_parameters)
887 2
			return;
888
889
		return array(
890 2
			'field' => $field,
891 2
			'input' => $input[$field],
892
			'function' => __FUNCTION__,
893 2
			'param' => $validation_parameters
894
		);
895
	}
896
897
	/**
898
	 * alpha ... Determine if the provided value contains only alpha characters
899
	 *
900
	 * Usage: '[key]' => 'alpha'
901
	 *
902
	 * @param string $field
903
	 * @param mixed[] $input
904
	 * @param mixed[]|null $validation_parameters array or null
905
	 *
906
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
907
	 */
908 2 View Code Duplication
	protected function _validate_alpha($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
909
	{
910 2
		if (!isset($input[$field]))
911
			return;
912
913
		// A character with the Unicode property of letter (any kind of letter from any language)
914 2
		if (!preg_match('~^(\p{L})+$~iu', $input[$field]))
915
		{
916
			return array(
917 2
				'field' => $field,
918 2
				'input' => $input[$field],
919
				'function' => __FUNCTION__,
920 2
				'param' => $validation_parameters
921
			);
922
		}
923 2
	}
924
925
	/**
926
	 * alpha_numeric ... Determine if the provided value contains only alpha-numeric characters
927
	 *
928
	 * Usage: '[key]' => 'alpha_numeric'
929
	 * Allows letters, numbers dash and underscore characters
930
	 *
931
	 * @param string $field
932
	 * @param mixed[] $input
933
	 * @param mixed[]|null $validation_parameters array or null
934
	 *
935
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
936
	 */
937 2 View Code Duplication
	protected function _validate_alpha_numeric($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
938
	{
939 2
		if (!isset($input[$field]))
940
			return;
941
942
		// A character with the Unicode property of letter or number (any kind of letter or numeric 0-9 from any language)
943 2
		if (!preg_match('~^([-_\p{L}\p{Nd}])+$~iu', $input[$field]))
944
		{
945
			return array(
946 2
				'field' => $field,
947 2
				'input' => $input[$field],
948
				'function' => __FUNCTION__,
949 2
				'param' => $validation_parameters
950
			);
951
		}
952 2
	}
953
954
	/**
955
	 * alpha_dash ... Determine if the provided value contains only alpha characters plus dashed and underscores
956
	 *
957
	 * Usage: '[key]' => 'alpha_dash'
958
	 *
959
	 * @param string $field
960
	 * @param mixed[] $input
961
	 * @param mixed[]|null $validation_parameters array or null
962
	 *
963
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
964
	 */
965 2 View Code Duplication
	protected function _validate_alpha_dash($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
966
	{
967 2
		if (!isset($input[$field]))
968
			return;
969
970 2
		if (!preg_match('~^([-_\p{L}])+$~iu', $input[$field]))
971
		{
972
			return array(
973 2
				'field' => $field,
974 2
				'input' => $input[$field],
975
				'function' => __FUNCTION__,
976 2
				'param' => $validation_parameters
977
			);
978
		}
979 2
	}
980
981
	/**
982
	 * isarray ... Determine if the provided value exists and is an array
983
	 *
984
	 * Usage: '[key]' => 'isarray'
985
	 *
986
	 * @param string $field
987
	 * @param mixed[] $input
988
	 * @param mixed[]|null $validation_parameters array or null
989
	 *
990
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
991
	 */
992 4 View Code Duplication
	protected function _validate_isarray($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
993
	{
994 4
		if (!isset($input[$field]))
995
			return;
996
997 4
		if (!is_array($input[$field]))
998
		{
999
			return array(
1000
				'field' => $field,
1001
				'input' => $input[$field],
1002
				'function' => __FUNCTION__,
1003
				'param' => $validation_parameters
1004
			);
1005
		}
1006 4
	}
1007
1008
	/**
1009
	 * numeric ... Determine if the provided value is a valid number or numeric string
1010
	 *
1011
	 * Usage: '[key]' => 'numeric'
1012
	 *
1013
	 * @param string $field
1014
	 * @param mixed[] $input
1015
	 * @param mixed[]|null $validation_parameters array or null
1016
	 *
1017
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1018
	 */
1019 2 View Code Duplication
	protected function _validate_numeric($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1020
	{
1021 2
		if (!isset($input[$field]))
1022
			return;
1023
1024 2
		if (!is_numeric($input[$field]))
1025
		{
1026
			return array(
1027 2
				'field' => $field,
1028 2
				'input' => $input[$field],
1029
				'function' => __FUNCTION__,
1030 2
				'param' => $validation_parameters
1031
			);
1032
		}
1033 2
	}
1034
1035
	/**
1036
	 * integer ... Determine if the provided value is a valid integer
1037
	 *
1038
	 * Usage: '[key]' => 'integer'
1039
	 *
1040
	 * @param string $field
1041
	 * @param mixed[] $input
1042
	 * @param mixed[]|null $validation_parameters array or null
1043
	 *
1044
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1045
	 */
1046 42
	protected function _validate_integer($field, $input, $validation_parameters = null)
1047
	{
1048 42
		if (!isset($input[$field]))
1049 2
			return;
1050
1051 40
		$filter = filter_var($input[$field], FILTER_VALIDATE_INT);
1052
1053 40
		if ($filter === false)
1054
		{
1055
			return array(
1056 24
				'field' => $field,
1057 24
				'input' => $input[$field],
1058
				'function' => __FUNCTION__,
1059 24
				'param' => $validation_parameters
1060
			);
1061
		}
1062 18
	}
1063
1064
	/**
1065
	 * boolean ... Determine if the provided value is a boolean
1066
	 *
1067
	 * Usage: '[key]' => 'boolean'
1068
	 *
1069
	 * @param string $field
1070
	 * @param mixed[] $input
1071
	 * @param mixed[]|null $validation_parameters array or null
1072
	 *
1073
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1074
	 */
1075 56
	protected function _validate_boolean($field, $input, $validation_parameters = null)
1076
	{
1077 56
		if (!isset($input[$field]))
1078 2
			return;
1079
1080 54
		$filter = filter_var($input[$field], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
1081
1082 54
		if ($filter === null)
1083
		{
1084
			return array(
1085 30
				'field' => $field,
1086 30
				'input' => $input[$field],
1087
				'function' => __FUNCTION__,
1088 30
				'param' => $validation_parameters
1089
			);
1090
		}
1091 26
	}
1092
1093
	/**
1094
	 * float ... Determine if the provided value is a valid float
1095
	 *
1096
	 * Usage: '[key]' => 'float'
1097
	 *
1098
	 * @param string $field
1099
	 * @param mixed[] $input
1100
	 * @param mixed[]|null $validation_parameters array or null
1101
	 *
1102
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1103
	 */
1104 42 View Code Duplication
	protected function _validate_float($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1105
	{
1106 42
		if (!isset($input[$field]))
1107 2
			return;
1108
1109 40
		if (filter_var($input[$field], FILTER_VALIDATE_FLOAT) === false)
1110
		{
1111
			return array(
1112 18
				'field' => $field,
1113 18
				'input' => $input[$field],
1114
				'function' => __FUNCTION__,
1115 18
				'param' => $validation_parameters
1116
			);
1117
		}
1118 24
	}
1119
1120
	/**
1121
	 * valid_url ... Determine if the provided value is a valid-ish URL
1122
	 *
1123
	 * Usage: '[key]' => 'valid_url'
1124
	 *
1125
	 * @param string $field
1126
	 * @param mixed[] $input
1127
	 * @param mixed[]|null $validation_parameters array or null
1128
	 *
1129
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1130
	 */
1131 2 View Code Duplication
	protected function _validate_valid_url($field, $input, $validation_parameters = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1132
	{
1133 2
		if (!isset($input[$field]))
1134
			return;
1135
1136 2
		if (!preg_match('`^(https{0,1}?:(//([a-z0-9\-._~%]+)(:[0-9]+)?(/[a-z0-9\-._~%!$&\'()*+,;=:@]+)*/?))(\?[a-z0-9\-._~%!$&\'()*+,;=:@/?]*)?(\#[a-z0-9\-._~%!$&\'()*+,;=:@/?]*)?$`', $input[$field], $matches))
1137
		{
1138
			return array(
1139 2
				'field' => $field,
1140 2
				'input' => $input[$field],
1141
				'function' => __FUNCTION__,
1142 2
				'param' => $validation_parameters
1143
			);
1144
		}
1145 2
	}
1146
1147
	/**
1148
	 * valid_ipv6 ... Determine if the provided value is a valid IPv6 address
1149
	 *
1150
	 * Usage: '[key]' => 'valid_ipv6'
1151
	 *
1152
	 * @param string $field
1153
	 * @param mixed[] $input
1154
	 * @param mixed[]|null $validation_parameters array or null
1155
	 *
1156
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1157
	 */
1158 2
	protected function _validate_valid_ipv6($field, $input, $validation_parameters = null)
1159
	{
1160 2
		if (!isset($input[$field]))
1161
			return;
1162
1163 2
		if (filter_var($input[$field], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false)
1164
		{
1165
			return array(
1166 2
				'field' => $field,
1167 2
				'input' => $input[$field],
1168
				'function' => __FUNCTION__,
1169 2
				'param' => $validation_parameters
1170
			);
1171
		}
1172 2
	}
1173
1174
	/**
1175
	 * valid_ip ... Determine if the provided value is a valid IP4 address
1176
	 *
1177
	 * Usage: '[key]' => 'valid_ip'
1178
	 *
1179
	 * @param string $field
1180
	 * @param mixed[] $input
1181
	 * @param mixed[]|null $validation_parameters array or null
1182
	 *
1183
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1184
	 */
1185 2
	protected function _validate_valid_ip($field, $input, $validation_parameters = null)
1186
	{
1187 2
		if (!isset($input[$field]))
1188
			return;
1189
1190 2
		if (filter_var($input[$field], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false)
1191
		{
1192
			return array(
1193 2
				'field' => $field,
1194 2
				'input' => $input[$field],
1195
				'function' => __FUNCTION__,
1196 2
				'param' => $validation_parameters
1197
			);
1198
		}
1199 2
	}
1200
1201
	/**
1202
	 * Validate PHP syntax of an input.
1203
	 *
1204
	 * This approach to validation has been inspired by Compuart.
1205
	 *
1206
	 * Usage: '[key]' => 'php_syntax'
1207
	 *
1208
	 * @uses ParseError
1209
	 *
1210
	 * @param string $field
1211
	 * @param mixed[] $input
1212
	 * @param mixed[]|null $validation_parameters array or null
1213
	 *
1214
	 * @return array|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1215
	 */
1216 2
	protected function _validate_php_syntax($field, $input, $validation_parameters = null)
1217
	{
1218 2
		if (!isset($input[$field]))
1219
			return;
1220
1221
		// Check the depth.
1222 2
		$level = 0;
1223 2
		$tokens = @token_get_all($input[$field]);
1224 2
		foreach ($tokens as $token)
1225
		{
1226 2
			if ($token === '{' || (isset($token[1]) && $token[1] === '${'))
1227
				$level++;
1228 2
			elseif ($token === '}')
1229 1
				$level--;
1230
		}
1231
1232 2
		if (!empty($level))
1233
			$result = false;
1234
		else
1235
		{
1236
			// Check the validity of the syntax.
1237 2
			ob_start();
1238 2
			$errorReporting = error_reporting(0);
1239
			try
1240
			{
1241 2
				$result = @eval('
1242
					if (false)
1243
					{
1244 2
						' . preg_replace('~^(?:\s*<\\?(?:php)?|\\?>\s*$)~u', '', $input[$field]) . '
1245
					}
1246
				');
1247
			}
1248 2
			catch (\ParseError $e)
1249
			{
1250 2
				$result = false;
1251
			}
1252 2
			error_reporting($errorReporting);
1253 2
			@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1254
		}
1255
1256 2
		if ($result === false)
1257
		{
1258 2
			$errorMsg = error_get_last();
1259
1260
			return array(
1261 2
				'field' => $field,
1262 2
				'input' => $input[$field],
1263 2
				'error' => '_validate_php_syntax',
1264 2
				'error_msg' => $errorMsg['message'],
1265 2
				'param' => $validation_parameters
1266
			);
1267
		}
1268 2
	}
1269
1270
	/**
1271
	 * Checks if the input is a valid css-like color
1272
	 *
1273
	 * Usage: '[key]' => 'valid_color'
1274
	 *
1275
	 * @param string $field
1276
	 * @param mixed[] $input
1277
	 * @param mixed[]|null $validation_parameters array or null
1278
	 *
1279
	 * @return array|bool|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|boolean|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1280
	 */
1281 2
	protected function _validate_valid_color($field, $input, $validation_parameters = null)
1282
	{
1283 2
		if (!isset($input[$field]))
1284
			return;
1285
1286
		// A color can be a name: there are 140 valid, but a similar list is too long, so let's just use the basic 17
1287 2
		if (in_array(strtolower($input[$field]), array('aqua', 'black', 'blue', 'fuchsia', 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', 'red', 'silver', 'teal', 'white', 'yellow')))
1288
			return true;
1289
1290
		// An hex code
1291 2
		if (preg_match('~^#([a-f0-9]{3}|[a-f0-9]{6})$~i', $input[$field]) === 1)
1292 2
			return true;
1293
1294
		// RGB
1295 2 View Code Duplication
		if (preg_match('~^rgb\(\d{1,3},\d{1,3},\d{1,3}\)$~i', str_replace(' ', '', $input[$field])) === 1)
1296
			return true;
1297
1298
		// RGBA
1299 2 View Code Duplication
		if (preg_match('~^rgba\(\d{1,3},\d{1,3},\d{1,3},(0|0\.\d+|1(\.0*)|\.\d+)\)$~i', str_replace(' ', '', $input[$field])) === 1)
1300
			return true;
1301
1302
		// HSL
1303 2 View Code Duplication
		if (preg_match('~^hsl\(\d{1,3},\d{1,3}%,\d{1,3}%\)$~i', str_replace(' ', '', $input[$field])) === 1)
1304
			return true;
1305
1306
		// HSLA
1307 2 View Code Duplication
		if (preg_match('~^hsla\(\d{1,3},\d{1,3}%,\d{1,3}%,(0|0\.\d+|1(\.0*)|\.\d+)\)$~i', str_replace(' ', '', $input[$field])) === 1)
1308
			return true;
1309
1310
		return array(
1311 2
			'field' => $field,
1312 2
			'input' => $input[$field],
1313
			'function' => __FUNCTION__,
1314 2
			'param' => $validation_parameters
1315
		);
1316
	}
1317
1318
	/**
1319
	 * gmail_normalize ... Used to normalize a gmail address as many resolve to the same address
1320
	 *
1321
	 * - Gmail user can use @googlemail.com instead of @gmail.com
1322
	 * - Gmail ignores all characters after a + (plus sign) in the username
1323
	 * - Gmail ignores all . (dots) in username
1324
	 * - [email protected], [email protected], [email protected] and [email protected] are same email
1325
	 * address.
1326
	 *
1327
	 * @param string $input
1328
	 *
1329
	 * @return string|void
1330
	 */
1331
	protected function _sanitation_gmail_normalize($input)
1332
	{
1333
		if (!isset($input))
1334
			return;
1335
1336
		$at_index = strrpos($input, '@');
1337
1338
		// Time to do some checking on the local@domain parts
1339
		$local_name = substr($input, 0, $at_index);
1340
		$domain_name = strtolower(substr($input, $at_index + 1));
1341
1342
		// Gmail address?
1343
		if (in_array($domain_name, array('gmail.com', 'googlemail.com')))
1344
		{
1345
			// Gmail ignores all . (dot) in username
1346
			$local_name = str_replace('.', '', $local_name);
1347
1348
			// Gmail ignores all characters after a + (plus sign) in username
1349
			$temp = explode('+', $local_name);
1350
			$local_name = $temp[0];
1351
1352
			// @todo should we force gmail.com or use $domain_name, force is safest but perhaps most confusing
1353
		}
1354
1355
		return $local_name . '@' . $domain_name;
1356
	}
1357
1358
	/**
1359
	 * Uses \ElkArte\Util::htmlspecialchars to sanitize any html in the input
1360
	 *
1361
	 * @param string $input
1362
	 *
1363
	 * @return null|string|string[]
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|string.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1364
	 */
1365
	protected function _sanitation_cleanhtml($input)
1366
	{
1367
		if (!isset($input))
1368
			return;
1369
1370
		return Util::htmlspecialchars($input);
1371
	}
1372
}
1373