File: Rule.class.php

package info (click to toggle)
fusionforge 5.3.2%2B20141104-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 60,472 kB
  • sloc: php: 271,846; sql: 36,817; python: 14,575; perl: 6,406; sh: 5,980; xml: 4,294; pascal: 1,411; makefile: 911; cpp: 52; awk: 27
file content (361 lines) | stat: -rw-r--r-- 9,102 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
<?php
/**
 * Copyright (c) STMicroelectronics, 2007. All Rights Reserved.
 *
 * Originally written by Manuel VACELET, 2007.
 *
 * This file is a part of Fusionforge.
 *
 * Fusionforge is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Fusionforge is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Codendi. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @package Codendi
 */
class Rule {
	/**
	* @access private
	*/
	var $error;

	/**
	* Check if $val is a valid not.
	*
	* @param  String  $val Value to check.
	* @return Boolean
	*/
	function isValid($val) {
		trigger_error(get_class($this).'::isValid() => Not yet implemented', E_USER_ERROR);
	}

	/**
	* Default error message if rule is not apply on value.
	*
	* @param  string  $key Value to check.
	* @return boolean
	*/
	function getErrorMessage($key) {
		return $this->error;
	}
}

/**
 * Validate date provided by Codendi calendar.
 *
 * Note: this date format is more restrictive than php check date because in
 * this case, 2007-01-01 format (with zero in month or day) is not allowed.
 */
class Rule_Date extends Rule {
	function isValid($val) {
		if(preg_match('/^(\d{1,4})-(\d{1,2})-(\d{1,2}?)$/', $val, $m)) {
			return checkdate($m[2], $m[3], $m[1]);
		} else {
			return false;
		}
	}
}

/**
 * Abstract class that define left-hand operand for a comparison.
 */
class Rule_Comparator extends Rule {
	/**
	 * @access private
	 */
	var $ref;
	function Rule_Comparator($ref) {
		$this->ref = $ref;
	}
}

/**
 * Check that given value is strictly greater than the one defined in
 * constructor.
 */
class Rule_GreaterThan extends Rule_Comparator {
	function isValid($val) {
		if(is_numeric($val) && $val > $this->ref) {
			return true;
		}
		return false;
	}
}

/**
 * Check that given value is strictly less than the one defined in constructor.
 */
class Rule_LessThan extends Rule_Comparator {
	function isValid($val) {
		if(is_numeric($val) && $val < $this->ref) {
			return true;
		}
		return false;
	}
}

/**
 * Check that given value is greater or equal to the one defined in
 * constructor.
 */
class Rule_GreaterOrEqual extends Rule_Comparator {
	function isValid($val) {
		if(is_numeric($val) && $val >= $this->ref) {
			return true;
		}
		return false;
	}
}

/**
 * Check that given value is strictly less or equal to the one defined in
 * constructor.
 */
class Rule_lessOrEqual extends Rule_Comparator {
	function isValid($val) {
		if(is_numeric($val) && $val <= $this->ref) {
			return true;
		}
		return false;
	}
}

/**
 * Check that given value belong to the array defined in constructor.
 *
 * There is no type check.
 */
class Rule_WhiteList extends Rule_Comparator {
	function isValid($val) {
		if(is_array($this->ref) && count($this->ref) > 0 && in_array($val, $this->ref)) {
			return true;
		}
		return false;
	}
}

/**
 * Check that given value is a valid signed 32 bits decimal integer.
 */
class Rule_Int extends Rule {
	/**
	 * Check the format according to PHP definition of a decimal integer.
	 * @see http://php.net/int
	 * @access private
	 */
	function checkFormat($val) {
		if(preg_match('/^([+-]?[1-9][0-9]*|[+-]?0)$/', $val)) {
			return true;
		}
		return false;
	}

	function isValid($val) {
		// Need to check with the regexp because of octal form '0123' that is
		// equal to '123' with string '==' comparison.
		if($this->checkFormat($val)) {
			// Check (-2^31;2^31-1) range
			if(strval(intval($val)) == $val) {
				return true;
			} else {
				return false;
			}
		}
		return false;
	}
}

/**
 * Check that given value is a string.
 */
class Rule_String extends Rule {
	function isValid($val) {
		return is_string($val);
	}
}

/**
 * Check if given string contains neither a carrige return nor a null char.
 */
class Rule_NoCr extends Rule {
	function isValid($val) {
		if(is_string($val) && strpos($val, 0x0A) === false && strpos($val, 0x0D) === false && strpos($val, 0x00) === false) {
			return true;
		}
		return false;
	}
}

/**
 * Check if an email address is valid or not in Codendi context.
 *
 * This rule is influenced by a global variable 'sys_disable_subdomain'. If
 * this variable is set (no subdomain for codendi) and only in this case, emails
 * like 'user@codendi' are allowed.
 *
 * The faulty email address is available with $this->getErrorMessage();
 */
class Rule_Email extends Rule {
	var $separator;

	function Rule_Email($separator = null) {
		$this->separator = $separator;
	}

	function isValid($val) {
		if($this->separator !== null) {
			// If separator is defined, split the string and check each email.
			$emails = split($this->separator, $val);
			$valid = true;
			while((list($key,$email) = each($emails)) && $valid) {
				$valid = $valid & $this->validEmail(trim(rtrim($email)));
			}
		} else {
		// $val must contains only one email address
			$valid = $this->validEmail($val);
		}
		return $valid;
	}

	/**
	 * Check email validity
	 *
	 * Important note: this is very important to keep the 'D' regexp modifier
	 * as this is the only way not to be bothered by injections of \n into the
	 * email address.
	 *
	 * Spaces are allowed at the beginning and the end of the address.
	 */
	function validEmail($email) {
		$valid_chars='-!#$%&\'*+0-9=?A-Z^_`a-z{|}~\.';
		if (array_key_exists('sys_disable_subdomains', $GLOBALS) && $GLOBALS['sys_disable_subdomains']) {
			$valid_domain='['.$valid_chars.']+';
		} else {
			$valid_domain='['.$valid_chars.']+\.['.$valid_chars.']+';
		}
		$regexp = '/^['.$valid_chars.']+'.'@'.$valid_domain.'$/D';
		return preg_match($regexp, $email);
	}
}

/**
 * Check if value match Codendi user names format.
 *
 * This rule doesn't check that user actually exists.
 */
class Rule_UserNameFormat extends Rule {

	function containsIllegalChars($val) {
		return (strspn($val,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_") != strlen($val));
	}

	function isNotLegalName($val) {
		return preg_match('/^((root)|(bin)|(daemon)|(adm)|(lp)|(sync)|(shutdown)|(halt)|(mail)|(news)'
				.'|(uucp)|(operator)|(games)|(mysql)|(httpd)|(nobody)|(dummy)'
				.'|(www)|(cvs)|(shell)|(ftp)|(irc)|(debian)|(ns)|(download))$/i', $val);
	}

	function isCvsAccount($val) {
		return preg_match('/^anoncvs_/i', $val);
	}

	function lessThanMin($val) {
		return (strlen($val) < 3);
	}

	function greaterThanMax($val) {
		return (strlen($val) > 30);
	}

	function isValid($val) {
		return !$this->isNotLegalName($val)
			&& !$this->isCvsAccount($val)
			&& !$this->lessThanMin($val)
			&& !$this->greaterThanMax($val)
			&& !$this->containsIllegalChars($val);
	}
}

/**
 * Check that file was correctly uploaded doesn't by pass Codendi limits.
 *
 * Tests mainly rely on PHP $_FILES error code but add a double check of file
 * size because MAX_FILE_SIZE (used by PHP to check allowed size) is submitted
 * by the client.
 *
 * By default the maxSize is defined by 'sys_max_size_upload' Codendi
 * variable but may be customized with setMaxSize.
 */
//require_once("www/file/file_utils.php"); // Needed for 2 GB workaround
class Rule_File extends Rule {
	var $maxSize;
	var $i18nPageName;

	function Rule_File() {
		$this->maxSize = $GLOBALS['sys_max_size_upload'];
		$this->i18nPageName = 'rule_valid';
	}

	function setMaxSize($max) {
		$this->maxSize = $max;
	}

	function geti18nError($key, $params="") {
		return $GLOBALS['Language']->getText($this->i18nPageName, $key, $params);
	}

	/**
	 * Check file upload validity
	 *
	 * @param string $file
	 * @return boolean Is file upload valid or not.
	 */
	function isValid($file) {
		$ok = false;
		if(is_array($file)) {
			switch($file['error']) {
				case UPLOAD_ERR_OK:
					// all is OK
					$ok = true;
					break;
				case UPLOAD_ERR_INI_SIZE:
				case UPLOAD_ERR_FORM_SIZE:
					$this->error = $this->geti18nError('error_upload_size', $file['error']);
					break;
				case UPLOAD_ERR_PARTIAL:
					$this->error = $this->geti18nError('error_upload_partial', $file['error']);
					break;
				case UPLOAD_ERR_NO_FILE:
					$this->error = $this->geti18nError('error_upload_nofile', $file['error']);
					break;
				//case UPLOAD_ERR_NO_TMP_DIR: PHP 5.0.3
				//case UPLOAD_ERR_CANT_WRITE: PHP 5.1.0
				//case UPLOAD_ERR_EXTENSION: PHP 5.2.0
				default:
					$this->error = $this->geti18nError('error_upload_unknown', $file['error']);
			}
			if($ok && $file['name'] == '') {
				$ok = false;
				$this->error = $this->geti18nError('error_upload');
			}
			if($ok) {
				// Re-check filesize (do not trust uploaded MAX_FILE_SIZE)
				if(file_utils_get_size($file['tmp_name']) > $this->maxSize) {
					$ok = false;
					$this->error = $this->geti18nError('error_upload_size', 1);
				}
			}
		}
		return $ok;
	}
}