1 | <?php |
||
2 | /* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/lib/validateurlsyntax.php under GNU/GPL license */ |
||
3 | |||
4 | /** |
||
5 | * BEGINNING OF validateUrlSyntax() function. |
||
6 | */ |
||
7 | function validateUrlSyntax($urladdr, $options = "") |
||
8 | { |
||
9 | // Force Options parameter to be lower case |
||
10 | // DISABLED PERMAMENTLY - OK to remove from code |
||
11 | // $options = strtolower($options); |
||
12 | |||
13 | // Check Options Parameter |
||
14 | if (!preg_match('/^([sHSEFRuPaIpfqr][+?-])*$/', $options)) { |
||
15 | trigger_error("Options attribute malformed", E_USER_ERROR); |
||
16 | } |
||
17 | |||
18 | // Set Options Array, set defaults if options are not specified |
||
19 | // Scheme |
||
20 | if (strpos($options, 's') === false) { |
||
21 | $aOptions['s'] = '?'; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Loading history...
|
|||
22 | } else { |
||
23 | $aOptions['s'] = substr($options, strpos($options, 's') + 1, 1); |
||
24 | } |
||
25 | // http:// |
||
26 | if (strpos($options, 'H') === false) { |
||
27 | $aOptions['H'] = '?'; |
||
28 | } else { |
||
29 | $aOptions['H'] = substr($options, strpos($options, 'H') + 1, 1); |
||
30 | } |
||
31 | // https:// (SSL) |
||
32 | if (strpos($options, 'S') === false) { |
||
33 | $aOptions['S'] = '?'; |
||
34 | } else { |
||
35 | $aOptions['S'] = substr($options, strpos($options, 'S') + 1, 1); |
||
36 | } |
||
37 | // mailto: (email) |
||
38 | if (strpos($options, 'E') === false) { |
||
39 | $aOptions['E'] = '-'; |
||
40 | } else { |
||
41 | $aOptions['E'] = substr($options, strpos($options, 'E') + 1, 1); |
||
42 | } |
||
43 | // ftp:// |
||
44 | if (strpos($options, 'F') === false) { |
||
45 | $aOptions['F'] = '-'; |
||
46 | } else { |
||
47 | $aOptions['F'] = substr($options, strpos($options, 'F') + 1, 1); |
||
48 | } |
||
49 | // rtmp:// |
||
50 | if (strpos($options, 'R') === false) { |
||
51 | $aOptions['R'] = '-'; |
||
52 | } else { |
||
53 | $aOptions['R'] = substr($options, strpos($options, 'R') + 1, 1); |
||
54 | } |
||
55 | // User section |
||
56 | if (strpos($options, 'u') === false) { |
||
57 | $aOptions['u'] = '?'; |
||
58 | } else { |
||
59 | $aOptions['u'] = substr($options, strpos($options, 'u') + 1, 1); |
||
60 | } |
||
61 | // Password in user section |
||
62 | if (strpos($options, 'P') === false) { |
||
63 | $aOptions['P'] = '?'; |
||
64 | } else { |
||
65 | $aOptions['P'] = substr($options, strpos($options, 'P') + 1, 1); |
||
66 | } |
||
67 | // Address Section |
||
68 | if (strpos($options, 'a') === false) { |
||
69 | $aOptions['a'] = '+'; |
||
70 | } else { |
||
71 | $aOptions['a'] = substr($options, strpos($options, 'a') + 1, 1); |
||
72 | } |
||
73 | // IP Address in address section |
||
74 | if (strpos($options, 'I') === false) { |
||
75 | $aOptions['I'] = '?'; |
||
76 | } else { |
||
77 | $aOptions['I'] = substr($options, strpos($options, 'I') + 1, 1); |
||
78 | } |
||
79 | // Port number |
||
80 | if (strpos($options, 'p') === false) { |
||
81 | $aOptions['p'] = '?'; |
||
82 | } else { |
||
83 | $aOptions['p'] = substr($options, strpos($options, 'p') + 1, 1); |
||
84 | } |
||
85 | // File Path |
||
86 | if (strpos($options, 'f') === false) { |
||
87 | $aOptions['f'] = '?'; |
||
88 | } else { |
||
89 | $aOptions['f'] = substr($options, strpos($options, 'f') + 1, 1); |
||
90 | } |
||
91 | // Query Section |
||
92 | if (strpos($options, 'q') === false) { |
||
93 | $aOptions['q'] = '?'; |
||
94 | } else { |
||
95 | $aOptions['q'] = substr($options, strpos($options, 'q') + 1, 1); |
||
96 | } |
||
97 | // Fragment (Anchor) |
||
98 | if (strpos($options, 'r') === false) { |
||
99 | $aOptions['r'] = '?'; |
||
100 | } else { |
||
101 | $aOptions['r'] = substr($options, strpos($options, 'r') + 1, 1); |
||
102 | } |
||
103 | |||
104 | // Loop through options array, to search for and replace "-" to "{0}" and "+" to "" |
||
105 | foreach ($aOptions as $key => $value) { |
||
106 | if ($value == '-') { |
||
107 | $aOptions[$key] = '{0}'; |
||
108 | } |
||
109 | if ($value == '+') { |
||
110 | $aOptions[$key] = ''; |
||
111 | } |
||
112 | } |
||
113 | |||
114 | // DEBUGGING - Unescape following line to display to screen current option values |
||
115 | // echo '<pre>'; print_r($aOptions); echo '</pre>'; |
||
116 | |||
117 | // Preset Allowed Characters |
||
118 | $alphanum = '[a-zA-Z0-9]'; // Alpha Numeric |
||
119 | $unreserved = '[a-zA-Z0-9_.!~*'.'\''.'()-]'; |
||
120 | $escaped = '(%[0-9a-fA-F]{2})'; // Escape sequence - In Hex - %6d would be a 'm' |
||
121 | $reserved = '[;/?:@&=+$,]'; // Special characters in the URI |
||
122 | |||
123 | // Beginning Regular Expression |
||
124 | // Scheme - Allows for 'http://', 'https://', 'mailto:', 'ftp://' or 'rtmp://' |
||
125 | $scheme = '('; |
||
126 | if ($aOptions['H'] === '') { |
||
127 | $scheme .= 'http://'; |
||
128 | } elseif ($aOptions['S'] === '') { |
||
129 | $scheme .= 'https://'; |
||
130 | } elseif ($aOptions['E'] === '') { |
||
131 | $scheme .= 'mailto:'; |
||
132 | } elseif ($aOptions['F'] === '') { |
||
133 | $scheme .= 'ftp://'; |
||
134 | } elseif ($aOptions['R'] === '') { |
||
135 | $scheme .= 'rtmp://'; |
||
136 | } else { |
||
137 | if ($aOptions['H'] === '?') { |
||
138 | $scheme .= '|(http://)'; |
||
139 | } |
||
140 | if ($aOptions['S'] === '?') { |
||
141 | $scheme .= '|(https://)'; |
||
142 | } |
||
143 | if ($aOptions['E'] === '?') { |
||
144 | $scheme .= '|(mailto:)'; |
||
145 | } |
||
146 | if ($aOptions['F'] === '?') { |
||
147 | $scheme .= '|(ftp://)'; |
||
148 | } |
||
149 | if ($aOptions['R'] === '?') { |
||
150 | $scheme .= '|(rtmp://)'; |
||
151 | } |
||
152 | $scheme = str_replace('(|', '(', $scheme); // fix first pipe |
||
153 | } |
||
154 | $scheme .= ')'.$aOptions['s']; |
||
155 | // End setting scheme |
||
156 | |||
157 | // User Info - Allows for 'username@' or 'username:password@'. Note: contrary to rfc, I removed ':' from username section, allowing it only in password. |
||
158 | // /---------------- Username -----------------------\ /-------------------------------- Password ------------------------------\ |
||
159 | $userinfo = '(('.$unreserved.'|'.$escaped.'|[;&=+$,]'.')+(:('.$unreserved.'|'.$escaped.'|[;:&=+$,]'.')+)'.$aOptions['P'].'@)'.$aOptions['u']; |
||
160 | |||
161 | // IP ADDRESS - Allows 0.0.0.0 to 255.255.255.255 |
||
162 | $ipaddress = '((((2(([0-4][0-9])|(5[0-5])))|([01]?[0-9]?[0-9]))\.){3}((2(([0-4][0-9])|(5[0-5])))|([01]?[0-9]?[0-9])))'; |
||
163 | |||
164 | // Tertiary Domain(s) - Optional - Multi - Although some sites may use other characters, the RFC says tertiary domains have the same naming restrictions as second level domains |
||
165 | $domain_tertiary = '('.$alphanum.'(([a-zA-Z0-9-]{0,62})'.$alphanum.')?\.)*'; |
||
166 | $domain_toplevel = '([a-zA-Z](([a-zA-Z0-9-]*)[a-zA-Z0-9])?)'; |
||
167 | |||
168 | if ($aOptions['I'] === '{0}') { // IP Address Not Allowed |
||
169 | $address = '('.$domain_tertiary. /* MDL-9295 $domain_secondary . */ $domain_toplevel.')'; |
||
170 | } elseif ($aOptions['I'] === '') { // IP Address Required |
||
171 | $address = '('.$ipaddress.')'; |
||
172 | } else { // IP Address Optional |
||
173 | $address = '(('.$ipaddress.')|('.$domain_tertiary. /* MDL-9295 $domain_secondary . */ $domain_toplevel.'))'; |
||
174 | } |
||
175 | $address = $address.$aOptions['a']; |
||
176 | |||
177 | // Port Number - :80 or :8080 or :65534 Allows range of :0 to :65535 |
||
178 | // (0-59999) |(60000-64999) |(65000-65499) |(65500-65529) |(65530-65535) |
||
179 | $port_number = '(:(([0-5]?[0-9]{1,4})|(6[0-4][0-9]{3})|(65[0-4][0-9]{2})|(655[0-2][0-9])|(6553[0-5])))'.$aOptions['p']; |
||
180 | |||
181 | // Path - Can be as simple as '/' or have multiple folders and filenames |
||
182 | $path = '(/((;)?('.$unreserved.'|'.$escaped.'|'.'[:@&=+$,]'.')+(/)?)*)'.$aOptions['f']; |
||
183 | |||
184 | // Query Section - Accepts ?var1=value1&var2=value2 or ?2393,1221 and much more |
||
185 | $querystring = '(\?('.$reserved.'|'.$unreserved.'|'.$escaped.')*)'.$aOptions['q']; |
||
186 | |||
187 | // Fragment Section - Accepts anchors such as #top |
||
188 | $fragment = '(\#('.$reserved.'|'.$unreserved.'|'.$escaped.')*)'.$aOptions['r']; |
||
189 | |||
190 | // Building Regular Expression |
||
191 | $regexp = '#^'.$scheme.$userinfo.$address.$port_number.$path.$querystring.$fragment.'$#i'; |
||
192 | |||
193 | // DEBUGGING - Uncomment Line Below To Display The Regular Expression Built |
||
194 | // echo '<pre>' . htmlentities(wordwrap($regexp,70,"\n",1)) . '</pre>'; |
||
195 | |||
196 | // Running the regular expression |
||
197 | if (preg_match($regexp, $urladdr)) { |
||
198 | return true; // The domain passed |
||
199 | } else { |
||
200 | return false; // The domain didn't pass the expression |
||
201 | } |
||
202 | } // END Function validateUrlSyntax() |
||
203 | |||
204 | /** |
||
205 | * About ValidateEmailSyntax(): |
||
206 | * This function uses the ValidateUrlSyntax() function to easily check the |
||
207 | * syntax of an email address. It accepts the same options as ValidateURLSyntax |
||
208 | * but defaults them for email addresses. |
||
209 | * |
||
210 | * Released under same license as validateUrlSyntax() |
||
211 | */ |
||
212 | function validateEmailSyntax($emailaddr, $options = "") |
||
213 | { |
||
214 | // Check Options Parameter |
||
215 | if (!preg_match('/^([sHSEFuPaIpfqr][+?-])*$/', $options)) { |
||
216 | trigger_error("Options attribute malformed", E_USER_ERROR); |
||
217 | } |
||
218 | |||
219 | // Set Options Array, set defaults if options are not specified |
||
220 | // Scheme |
||
221 | if (strpos($options, 's') === false) { |
||
222 | $aOptions['s'] = '-'; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
223 | } else { |
||
224 | $aOptions['s'] = substr($options, strpos($options, 's') + 1, 1); |
||
225 | } |
||
226 | // http:// |
||
227 | if (strpos($options, 'H') === false) { |
||
228 | $aOptions['H'] = '-'; |
||
229 | } else { |
||
230 | $aOptions['H'] = substr($options, strpos($options, 'H') + 1, 1); |
||
231 | } |
||
232 | // https:// (SSL) |
||
233 | if (strpos($options, 'S') === false) { |
||
234 | $aOptions['S'] = '-'; |
||
235 | } else { |
||
236 | $aOptions['S'] = substr($options, strpos($options, 'S') + 1, 1); |
||
237 | } |
||
238 | // mailto: (email) |
||
239 | if (strpos($options, 'E') === false) { |
||
240 | $aOptions['E'] = '?'; |
||
241 | } else { |
||
242 | $aOptions['E'] = substr($options, strpos($options, 'E') + 1, 1); |
||
243 | } |
||
244 | // ftp:// |
||
245 | if (strpos($options, 'F') === false) { |
||
246 | $aOptions['F'] = '-'; |
||
247 | } else { |
||
248 | $aOptions['F'] = substr($options, strpos($options, 'F') + 1, 1); |
||
249 | } |
||
250 | // User section |
||
251 | if (strpos($options, 'u') === false) { |
||
252 | $aOptions['u'] = '+'; |
||
253 | } else { |
||
254 | $aOptions['u'] = substr($options, strpos($options, 'u') + 1, 1); |
||
255 | } |
||
256 | // Password in user section |
||
257 | if (strpos($options, 'P') === false) { |
||
258 | $aOptions['P'] = '-'; |
||
259 | } else { |
||
260 | $aOptions['P'] = substr($options, strpos($options, 'P') + 1, 1); |
||
261 | } |
||
262 | // Address Section |
||
263 | if (strpos($options, 'a') === false) { |
||
264 | $aOptions['a'] = '+'; |
||
265 | } else { |
||
266 | $aOptions['a'] = substr($options, strpos($options, 'a') + 1, 1); |
||
267 | } |
||
268 | // IP Address in address section |
||
269 | if (strpos($options, 'I') === false) { |
||
270 | $aOptions['I'] = '-'; |
||
271 | } else { |
||
272 | $aOptions['I'] = substr($options, strpos($options, 'I') + 1, 1); |
||
273 | } |
||
274 | // Port number |
||
275 | if (strpos($options, 'p') === false) { |
||
276 | $aOptions['p'] = '-'; |
||
277 | } else { |
||
278 | $aOptions['p'] = substr($options, strpos($options, 'p') + 1, 1); |
||
279 | } |
||
280 | // File Path |
||
281 | if (strpos($options, 'f') === false) { |
||
282 | $aOptions['f'] = '-'; |
||
283 | } else { |
||
284 | $aOptions['f'] = substr($options, strpos($options, 'f') + 1, 1); |
||
285 | } |
||
286 | // Query Section |
||
287 | if (strpos($options, 'q') === false) { |
||
288 | $aOptions['q'] = '-'; |
||
289 | } else { |
||
290 | $aOptions['q'] = substr($options, strpos($options, 'q') + 1, 1); |
||
291 | } |
||
292 | // Fragment (Anchor) |
||
293 | if (strpos($options, 'r') === false) { |
||
294 | $aOptions['r'] = '-'; |
||
295 | } else { |
||
296 | $aOptions['r'] = substr($options, strpos($options, 'r') + 1, 1); |
||
297 | } |
||
298 | |||
299 | // Generate options |
||
300 | $newoptions = ''; |
||
301 | foreach ($aOptions as $key => $value) { |
||
302 | $newoptions .= $key.$value; |
||
303 | } |
||
304 | |||
305 | // DEBUGGING - Uncomment line below to display generated options |
||
306 | // echo '<pre>' . $newoptions . '</pre>'; |
||
307 | |||
308 | // Send to validateUrlSyntax() and return result |
||
309 | return validateUrlSyntax($emailaddr, $newoptions); |
||
310 | } // END Function validateEmailSyntax() |
||
311 | |||
312 | /** |
||
313 | * About ValidateFtpSyntax(): |
||
314 | * This function uses the ValidateUrlSyntax() function to easily check the |
||
315 | * syntax of an FTP address. It accepts the same options as ValidateURLSyntax |
||
316 | * but defaults them for FTP addresses. |
||
317 | * |
||
318 | * Usage: |
||
319 | * <code> |
||
320 | * validateFtpSyntax( url_to_check[, options]) |
||
321 | * </code> |
||
322 | * url_to_check - string - The url to check |
||
323 | * |
||
324 | * options - string - A optional string of options to set which parts of |
||
325 | * the url are required, optional, or not allowed. Each option |
||
326 | * must be followed by a "+" for required, "?" for optional, or |
||
327 | * "-" for not allowed. See ValidateUrlSyntax() docs for option list. |
||
328 | * |
||
329 | * The default options are changed to: |
||
330 | * s?H-S-E-F+u?P?a+I?p?f?q-r- |
||
331 | * |
||
332 | * Examples: |
||
333 | * <code> |
||
334 | * validateFtpSyntax('ftp://netscape.com') |
||
335 | * validateFtpSyntax('moz:[email protected]') |
||
336 | * validateFtpSyntax('ftp://netscape.com:2121/browsers/ns7/', 'u-') |
||
337 | * </code> |
||
338 | * |
||
339 | * Author(s): |
||
340 | * Rod Apeldoorn - rod(at)canowhoopass(dot)com |
||
341 | * |
||
342 | * |
||
343 | * Homepage: |
||
344 | * http://www.canowhoopass.com/ |
||
345 | * |
||
346 | * |
||
347 | * License: |
||
348 | * Copyright 2004 - Rod Apeldoorn |
||
349 | * |
||
350 | * Released under same license as validateUrlSyntax(). For details, contact me. |
||
351 | */ |
||
352 | function validateFtpSyntax($ftpaddr, $options = "") |
||
353 | { |
||
354 | // Check Options Parameter |
||
355 | if (!preg_match('/^([sHSEFuPaIpfqr][+?-])*$/', $options)) { |
||
356 | trigger_error("Options attribute malformed", E_USER_ERROR); |
||
357 | } |
||
358 | |||
359 | // Set Options Array, set defaults if options are not specified |
||
360 | // Scheme |
||
361 | if (strpos($options, 's') === false) { |
||
362 | $aOptions['s'] = '?'; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
363 | } else { |
||
364 | $aOptions['s'] = substr($options, strpos($options, 's') + 1, 1); |
||
365 | } |
||
366 | // http:// |
||
367 | if (strpos($options, 'H') === false) { |
||
368 | $aOptions['H'] = '-'; |
||
369 | } else { |
||
370 | $aOptions['H'] = substr($options, strpos($options, 'H') + 1, 1); |
||
371 | } |
||
372 | // https:// (SSL) |
||
373 | if (strpos($options, 'S') === false) { |
||
374 | $aOptions['S'] = '-'; |
||
375 | } else { |
||
376 | $aOptions['S'] = substr($options, strpos($options, 'S') + 1, 1); |
||
377 | } |
||
378 | // mailto: (email) |
||
379 | if (strpos($options, 'E') === false) { |
||
380 | $aOptions['E'] = '-'; |
||
381 | } else { |
||
382 | $aOptions['E'] = substr($options, strpos($options, 'E') + 1, 1); |
||
383 | } |
||
384 | // ftp:// |
||
385 | if (strpos($options, 'F') === false) { |
||
386 | $aOptions['F'] = '+'; |
||
387 | } else { |
||
388 | $aOptions['F'] = substr($options, strpos($options, 'F') + 1, 1); |
||
389 | } |
||
390 | // User section |
||
391 | if (strpos($options, 'u') === false) { |
||
392 | $aOptions['u'] = '?'; |
||
393 | } else { |
||
394 | $aOptions['u'] = substr($options, strpos($options, 'u') + 1, 1); |
||
395 | } |
||
396 | // Password in user section |
||
397 | if (strpos($options, 'P') === false) { |
||
398 | $aOptions['P'] = '?'; |
||
399 | } else { |
||
400 | $aOptions['P'] = substr($options, strpos($options, 'P') + 1, 1); |
||
401 | } |
||
402 | // Address Section |
||
403 | if (strpos($options, 'a') === false) { |
||
404 | $aOptions['a'] = '+'; |
||
405 | } else { |
||
406 | $aOptions['a'] = substr($options, strpos($options, 'a') + 1, 1); |
||
407 | } |
||
408 | // IP Address in address section |
||
409 | if (strpos($options, 'I') === false) { |
||
410 | $aOptions['I'] = '?'; |
||
411 | } else { |
||
412 | $aOptions['I'] = substr($options, strpos($options, 'I') + 1, 1); |
||
413 | } |
||
414 | // Port number |
||
415 | if (strpos($options, 'p') === false) { |
||
416 | $aOptions['p'] = '?'; |
||
417 | } else { |
||
418 | $aOptions['p'] = substr($options, strpos($options, 'p') + 1, 1); |
||
419 | } |
||
420 | // File Path |
||
421 | if (strpos($options, 'f') === false) { |
||
422 | $aOptions['f'] = '?'; |
||
423 | } else { |
||
424 | $aOptions['f'] = substr($options, strpos($options, 'f') + 1, 1); |
||
425 | } |
||
426 | // Query Section |
||
427 | if (strpos($options, 'q') === false) { |
||
428 | $aOptions['q'] = '-'; |
||
429 | } else { |
||
430 | $aOptions['q'] = substr($options, strpos($options, 'q') + 1, 1); |
||
431 | } |
||
432 | // Fragment (Anchor) |
||
433 | if (strpos($options, 'r') === false) { |
||
434 | $aOptions['r'] = '-'; |
||
435 | } else { |
||
436 | $aOptions['r'] = substr($options, strpos($options, 'r') + 1, 1); |
||
437 | } |
||
438 | |||
439 | // Generate options |
||
440 | $newoptions = ''; |
||
441 | foreach ($aOptions as $key => $value) { |
||
442 | $newoptions .= $key.$value; |
||
443 | } |
||
444 | |||
445 | // Send to validateUrlSyntax() and return result |
||
446 | return validateUrlSyntax($ftpaddr, $newoptions); |
||
447 | } // END Function validateFtpSyntax() |
||
448 |