|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
if (!function_exists('strip_nl')) { |
|
4
|
|
|
|
|
5
|
|
|
/** |
|
6
|
|
|
* Strip new line breaks from a string |
|
7
|
|
|
* @param $str |
|
8
|
|
|
* @return string|array |
|
9
|
|
|
*/ |
|
10
|
|
|
function strip_nl($str) |
|
11
|
|
|
{ |
|
12
|
|
|
return str_replace("\n", "", str_replace("\r", "", $str)); |
|
13
|
|
|
} |
|
14
|
|
|
} |
|
15
|
|
|
|
|
16
|
|
|
if (!function_exists('jse')) { |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Javascript escape |
|
20
|
|
|
* @param string $str |
|
21
|
|
|
* @return string |
|
22
|
|
|
* @source https://github.com/rtconner/laravel-plusplus/blob/laravel-5/src/plus-functions.php |
|
23
|
|
|
*/ |
|
24
|
|
|
function jse(string $str): string |
|
25
|
|
|
{ |
|
26
|
|
|
if (isNullOrEmpty($str)) { |
|
27
|
|
|
return ''; |
|
28
|
|
|
} |
|
29
|
|
|
$str = str_replace("\n", "", str_replace("\r", "", $str)); |
|
30
|
|
|
return addslashes($str); |
|
31
|
|
|
} |
|
32
|
|
|
} |
|
33
|
|
|
|
|
34
|
|
|
if (!function_exists('e')) { |
|
35
|
|
|
/** |
|
36
|
|
|
* Escape HTML entities in a string. |
|
37
|
|
|
* |
|
38
|
|
|
* @param string $value |
|
39
|
|
|
* @return string |
|
40
|
|
|
*/ |
|
41
|
|
|
function e($value) |
|
42
|
|
|
{ |
|
43
|
|
|
return htmlentities($value, ENT_QUOTES, 'UTF-8', false); |
|
44
|
|
|
} |
|
45
|
|
|
} |
|
46
|
|
|
|
|
47
|
|
|
if (!function_exists('csse')) { |
|
48
|
|
|
/** |
|
49
|
|
|
* Escape CSS entities in a string. |
|
50
|
|
|
* |
|
51
|
|
|
* @param string $value |
|
52
|
|
|
* @return string |
|
53
|
|
|
* @see https://github.com/auraphp/Aura.Html/blob/2.x/src/Escaper/CssEscaper.php |
|
54
|
|
|
*/ |
|
55
|
|
|
function csse($value) |
|
56
|
|
|
{ |
|
57
|
|
|
// pre-empt replacement |
|
58
|
|
|
if ($value === '' || ctype_digit($value)) { |
|
59
|
|
|
return $value; |
|
60
|
|
|
} |
|
61
|
|
|
return preg_replace_callback( |
|
62
|
|
|
'/[^a-z0-9]/iSu', |
|
63
|
|
|
function ($matches) { |
|
64
|
|
|
// get the character |
|
65
|
|
|
$chr = $matches[0]; |
|
66
|
|
|
// is it UTF-8? |
|
67
|
|
|
if (strlen($chr) == 1) { |
|
68
|
|
|
// yes |
|
69
|
|
|
$ord = ord($chr); |
|
70
|
|
|
return sprintf('\\%X ', $ord); |
|
71
|
|
|
} |
|
72
|
|
|
}, |
|
73
|
|
|
$value |
|
74
|
|
|
); |
|
75
|
|
|
} |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
if (!function_exists('attre')) { |
|
79
|
|
|
/** |
|
80
|
|
|
* Escape HTML Attribute entities in a string. |
|
81
|
|
|
* |
|
82
|
|
|
* @param string $value |
|
83
|
|
|
* @return string |
|
84
|
|
|
* @see https://github.com/auraphp/Aura.Html/blob/2.x/src/Escaper/AttrEscaper.php |
|
85
|
|
|
*/ |
|
86
|
|
|
function attre($value) |
|
87
|
|
|
{ |
|
88
|
|
|
// pre-empt replacement |
|
89
|
|
|
if ($value === '' || ctype_digit($value)) { |
|
90
|
|
|
return $value; |
|
91
|
|
|
} |
|
92
|
|
|
return preg_replace_callback( |
|
93
|
|
|
'/[^a-z0-9,\.\-_]/iSu', |
|
94
|
|
|
function ($matches) { |
|
95
|
|
|
$chr = $matches[0]; |
|
96
|
|
|
$ord = ord($chr); |
|
97
|
|
|
if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") |
|
98
|
|
|
|| ($ord >= 0x7f && $ord <= 0x9f) |
|
99
|
|
|
) { |
|
100
|
|
|
// use the Unicode replacement char |
|
101
|
|
|
return '�'; |
|
102
|
|
|
} |
|
103
|
|
|
$entities = array( |
|
104
|
|
|
34 => '"', |
|
105
|
|
|
38 => '&', |
|
106
|
|
|
60 => '<', |
|
107
|
|
|
62 => '>', |
|
108
|
|
|
); |
|
109
|
|
|
// is this a mapped entity? |
|
110
|
|
|
if (isset($entities[$ord])) { |
|
111
|
|
|
return $entities[$ord]; |
|
112
|
|
|
} |
|
113
|
|
|
// is this an upper-range hex entity? |
|
114
|
|
|
if ($ord > 255) { |
|
115
|
|
|
return sprintf('&#x%04X;', $ord); |
|
116
|
|
|
} |
|
117
|
|
|
// everything else |
|
118
|
|
|
return sprintf('&#x%02X;', $ord); |
|
119
|
|
|
}, |
|
120
|
|
|
$value |
|
121
|
|
|
); |
|
122
|
|
|
} |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
if (!function_exists('she')) { |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* Escape Shell argument. |
|
129
|
|
|
* @param string $input |
|
130
|
|
|
* @return string |
|
131
|
|
|
*/ |
|
132
|
|
|
function she(string $input): string |
|
133
|
|
|
{ |
|
134
|
|
|
if (windows_os()) { |
|
135
|
|
|
return '"' . addcslashes($input, '\\"') . '"'; |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
return escapeshellarg($input); |
|
139
|
|
|
} |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* Normalize the string. |
|
144
|
|
|
* The following function removes all diacritics (marks like accents) from a given UTF8-encoded |
|
145
|
|
|
* texts and returns ASCii-text. |
|
146
|
|
|
* WARNING: if you have a non UTF8 encoded string try this: |
|
147
|
|
|
* @example if (ini_get('default_charset')!='UTF-8'){ $s=mb_convert_encoding($s,'UTF-8',ini_get('default_charset'));} |
|
148
|
|
|
* @param string $s |
|
149
|
|
|
* @return string |
|
150
|
|
|
* @see https://github.com/illuminate/support/blob/master/Str.php#L38 |
|
151
|
|
|
* @see http://php.net/manual/en/normalizer.normalize.php#92592 |
|
152
|
|
|
*/ |
|
153
|
|
|
function normalizeUtf8String(string $s): string |
|
154
|
|
|
{ |
|
155
|
|
|
$original_string = $s; |
|
156
|
|
|
|
|
157
|
|
|
//Transliterate UTF-8 value to ASCII with chars array map. |
|
158
|
|
|
$charsArray = charsArray(); |
|
159
|
|
|
array_walk($charsArray, function ($val, $key) use (&$s) { |
|
160
|
|
|
$s = str_replace($val, $key, $s); |
|
161
|
|
|
}); |
|
162
|
|
|
|
|
163
|
|
|
//replace non ASCII chars with array regex map. |
|
164
|
|
|
$charsRegExArray = charsArrayRegEx(); |
|
165
|
|
|
array_walk($charsRegExArray, function ($val, $key) use (&$s) { |
|
166
|
|
|
$s = preg_replace($val, $key, $s); |
|
167
|
|
|
}); |
|
168
|
|
|
|
|
169
|
|
|
// Normalize utf8 in form D |
|
170
|
|
|
// if exists use Normalizer-class to maps remaining special characters |
|
171
|
|
|
// (characters with diacritics) on their base-character followed by the diacritical mark |
|
172
|
|
|
// exmaple: Ú => U´, á => a` |
|
173
|
|
|
$s = normalizerUtf8Safe($s, Normalizer::FORM_D); |
|
174
|
|
|
|
|
175
|
|
|
// possible errors in UTF8-regular-expressions |
|
176
|
|
|
if (isNullOrEmpty($s)) { |
|
177
|
|
|
return $original_string; |
|
178
|
|
|
} |
|
179
|
|
|
|
|
180
|
|
|
return $s; |
|
181
|
|
|
} |
|
182
|
|
|
|
|
183
|
|
|
/** |
|
184
|
|
|
* Normalize uft8 to various form with php normalizer function if exists, |
|
185
|
|
|
* otherwise return original string. |
|
186
|
|
|
* maps special characters (characters with diacritics) on their base-character |
|
187
|
|
|
* followed by the diacritical mark |
|
188
|
|
|
* exmaple: Ú => U´, á => a` |
|
189
|
|
|
* @param string $s |
|
190
|
|
|
* @param $normalizationForm UTF8 Normalization Form if empty Default Normalizer::FORM_D |
|
191
|
|
|
* @return string |
|
192
|
|
|
*/ |
|
193
|
|
|
function normalizerUtf8Safe(string $s, $normalizationForm): string |
|
194
|
|
|
{ |
|
195
|
|
|
if (class_exists("Normalizer", false)) { |
|
196
|
|
|
$s = Normalizer::normalize($s, isNullOrEmpty($normalizationForm) ? Normalizer::FORM_D : $normalizationForm); |
|
197
|
|
|
return $s; |
|
198
|
|
|
} |
|
199
|
|
|
return $s; |
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
/** |
|
203
|
|
|
* String Sanitizer for Filename |
|
204
|
|
|
* @param string $fileName |
|
205
|
|
|
* @param bool $sanitizeForPath if set to false (default) sanitize file name, otherwise file path name |
|
206
|
|
|
* @param string $charToReplaceWhiteSpace if empty (default) or ' ' then white space ' ' will be preservede |
|
207
|
|
|
* othrwise it will be replaced with $charToReplaceWhiteSpace. |
|
208
|
|
|
* @return string |
|
209
|
|
|
* @see for base script idea http://stackoverflow.com/a/2021729 |
|
210
|
|
|
*/ |
|
211
|
|
|
function sanitize_filename( |
|
212
|
|
|
string $fileName, |
|
213
|
|
|
bool $sanitizeForPath = false, |
|
214
|
|
|
string $charToReplaceWhiteSpace = ' ' |
|
215
|
|
|
): string { |
|
216
|
|
|
//check whitespace |
|
217
|
|
|
$fileName = str_replace(' ', $charToReplaceWhiteSpace, $fileName); |
|
218
|
|
|
|
|
219
|
|
|
// Remove any runs of periods - avoid Path Traversal Vulnerabilities OSWAP |
|
220
|
|
|
// https://www.owasp.org/index.php/Path_Traversal |
|
221
|
|
|
$notAllowedPath = [ |
|
222
|
|
|
'//', |
|
223
|
|
|
'\\\\', |
|
224
|
|
|
'../', |
|
225
|
|
|
'./', |
|
226
|
|
|
'..\\', |
|
227
|
|
|
'.\\', |
|
228
|
|
|
'%2e%2e%2f', |
|
229
|
|
|
'%2e%2e/', |
|
230
|
|
|
'..%2f', |
|
231
|
|
|
'%2e%2e%5c', |
|
232
|
|
|
'%2e%2e\\', |
|
233
|
|
|
'..%5c', |
|
234
|
|
|
'%252e%252e%255c', |
|
235
|
|
|
'..%255c', |
|
236
|
|
|
'..%c0%af', |
|
237
|
|
|
'..%c1%9c', |
|
238
|
|
|
]; |
|
239
|
|
|
while (str_contains($fileName, $notAllowedPath) !== false) { |
|
240
|
|
|
$fileName = str_replace($notAllowedPath, '', $fileName); |
|
241
|
|
|
} |
|
242
|
|
|
|
|
243
|
|
|
// Remove anything which isn't a word, whitespace, number |
|
244
|
|
|
// or any of the following caracters -_~,;[](). |
|
245
|
|
|
// If you don't need to handle multi-byte characters |
|
246
|
|
|
// you can use preg_replace rather than mb_ereg_replace |
|
247
|
|
|
// Thanks @Łukasz Rysiak! |
|
248
|
|
|
$fileName = mb_ereg_replace('([^\w\s\d\-_~,;\[\]\(\).' . ($sanitizeForPath ? '\\/' : '') . '])', '', $fileName); |
|
249
|
|
|
|
|
250
|
|
|
// remove exadecimal, non white space chars |
|
251
|
|
|
$fileName = mb_ereg_replace('([[:cntrl:]\b\0\n\r\t\f])', '', $fileName); |
|
252
|
|
|
|
|
253
|
|
|
//normalize and trim |
|
254
|
|
|
$fileName = trim(normalizeUtf8String($fileName)); |
|
255
|
|
|
|
|
256
|
|
|
//do not start with .. |
|
257
|
|
|
while (starts_with($fileName, '..') !== false) { |
|
258
|
|
|
$fileName = substr($fileName, 2); |
|
259
|
|
|
} |
|
260
|
|
|
|
|
261
|
|
|
//do not end with .. |
|
262
|
|
|
while (ends_with($fileName, '..') !== false) { |
|
263
|
|
|
$fileName = substr($fileName, 0, -2); |
|
264
|
|
|
} |
|
265
|
|
|
//do not end with . |
|
266
|
|
|
while (ends_with($fileName, '.') !== false) { |
|
267
|
|
|
$fileName = substr($fileName, 0, -1); |
|
268
|
|
|
} |
|
269
|
|
|
|
|
270
|
|
|
return $fileName; |
|
271
|
|
|
} |
|
272
|
|
|
|
|
273
|
|
|
/** |
|
274
|
|
|
* String Sanitizer for Path name |
|
275
|
|
|
* @param string $pathName |
|
276
|
|
|
* @param string $charToReplaceWhiteSpace if empty (default) or ' ' then white space ' ' will be preservede |
|
277
|
|
|
* othrwise it will be replaced with $charToReplaceWhiteSpace. |
|
278
|
|
|
* @return string |
|
279
|
|
|
*/ |
|
280
|
|
|
|
|
281
|
|
|
function sanitize_pathname(string $pathName, string $charToReplaceWhiteSpace): string |
|
282
|
|
|
{ |
|
283
|
|
|
return sanitize_filename($pathName, true, $charToReplaceWhiteSpace); |
|
284
|
|
|
} |
|
285
|
|
|
|
|
286
|
|
|
/** |
|
287
|
|
|
* Perform XSS clean to prevent cross site scripting. |
|
288
|
|
|
* |
|
289
|
|
|
* @param array $data |
|
290
|
|
|
* |
|
291
|
|
|
* @return array |
|
292
|
|
|
*/ |
|
293
|
|
|
function sanitize_arr_string_xss(array $data): array |
|
294
|
|
|
{ |
|
295
|
|
|
foreach ($data as $k => $v) { |
|
296
|
|
|
$data[$k] = filter_var($v, FILTER_SANITIZE_STRING); |
|
297
|
|
|
} |
|
298
|
|
|
return $data; |
|
299
|
|
|
} |
|
300
|
|
|
|
|
301
|
|
|
/** |
|
302
|
|
|
* Perform XSS clean to prevent cross site scripting. |
|
303
|
|
|
* |
|
304
|
|
|
* @param string $data |
|
305
|
|
|
* |
|
306
|
|
|
* @return string |
|
307
|
|
|
* |
|
308
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
|
309
|
|
|
*/ |
|
310
|
|
|
function sanitize_string_xss(string $data): string |
|
311
|
|
|
{ |
|
312
|
|
|
return filter_var($data, FILTER_SANITIZE_STRING); |
|
313
|
|
|
} |
|
314
|
|
|
|
|
315
|
|
|
/** |
|
316
|
|
|
* Sanitize the string by urlencoding characters. |
|
317
|
|
|
* |
|
318
|
|
|
* @param string $value |
|
319
|
|
|
* |
|
320
|
|
|
* @return string |
|
321
|
|
|
* |
|
322
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
|
323
|
|
|
*/ |
|
324
|
|
|
function sanitize_urlencode($value) |
|
325
|
|
|
{ |
|
326
|
|
|
return filter_var($value, FILTER_SANITIZE_ENCODED); |
|
327
|
|
|
} |
|
328
|
|
|
|
|
329
|
|
|
/** |
|
330
|
|
|
* Sanitize the string by removing illegal characters from emails. |
|
331
|
|
|
* |
|
332
|
|
|
* @param string $value |
|
333
|
|
|
* |
|
334
|
|
|
* @return string |
|
335
|
|
|
* |
|
336
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
|
337
|
|
|
*/ |
|
338
|
|
|
function sanitize_email($value) |
|
339
|
|
|
{ |
|
340
|
|
|
return filter_var($value, FILTER_SANITIZE_EMAIL); |
|
341
|
|
|
} |
|
342
|
|
|
|
|
343
|
|
|
/** |
|
344
|
|
|
* Sanitize the string by removing illegal characters from numbers. |
|
345
|
|
|
* |
|
346
|
|
|
* @param string $value |
|
347
|
|
|
* |
|
348
|
|
|
* @return string |
|
349
|
|
|
* |
|
350
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
|
351
|
|
|
*/ |
|
352
|
|
|
function sanitize_numbers($value) |
|
353
|
|
|
{ |
|
354
|
|
|
return filter_var($value, FILTER_SANITIZE_NUMBER_INT); |
|
355
|
|
|
} |
|
356
|
|
|
|
|
357
|
|
|
/** |
|
358
|
|
|
* Sanitize the string by removing illegal characters from float numbers. |
|
359
|
|
|
* |
|
360
|
|
|
* @param string $value |
|
361
|
|
|
* |
|
362
|
|
|
* @return string |
|
363
|
|
|
* |
|
364
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
|
365
|
|
|
*/ |
|
366
|
|
|
function sanitize_floats($value) |
|
367
|
|
|
{ |
|
368
|
|
|
return filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); |
|
369
|
|
|
} |
|
370
|
|
|
|
|
371
|
|
|
/** |
|
372
|
|
|
* Sanitize the string by removing illegal characters from phone numbers |
|
373
|
|
|
* i.e.: optionally starts with +, optionally have prefix parenthesis and only number.. |
|
374
|
|
|
* If preserveSpaces set to true, leave spaces and replace illegal chars with one space, |
|
375
|
|
|
* otherwise remove every spaces. |
|
376
|
|
|
* |
|
377
|
|
|
* @param string $value |
|
378
|
|
|
* @param bool $preserveSpaces If set to true, leave spaces and replace illegal chars with one space, |
|
379
|
|
|
* otherwise remove every spaces. |
|
380
|
|
|
* |
|
381
|
|
|
* @return string |
|
382
|
|
|
* |
|
383
|
|
|
*/ |
|
384
|
|
|
function sanitize_phone($value, bool $preserveSpaces): string |
|
385
|
|
|
{ |
|
386
|
|
|
$startsWithPlus = starts_with($value, '+'); |
|
387
|
|
|
|
|
388
|
|
|
$phone = mb_ereg_replace('([^\d\(\)' . ($preserveSpaces ? '[:space:]' : '') . '])', $preserveSpaces ? ' ' : '', $value); |
|
389
|
|
|
$phone = trim($phone); |
|
390
|
|
|
|
|
391
|
|
|
//revert initial + if needed |
|
392
|
|
|
if ($startsWithPlus) { |
|
393
|
|
|
$phone = '+' . $phone; |
|
394
|
|
|
} |
|
395
|
|
|
|
|
396
|
|
|
//check for illegal () |
|
|
|
|
|
|
397
|
|
|
if ((strpos($phone, '(') !== false || strpos($phone, |
|
398
|
|
|
')') !== false) && !preg_match('/.*\([[:space:]0-9]{1,}\)[[:space:]0-9]{1,}/', $phone) |
|
399
|
|
|
) { |
|
400
|
|
|
$phone = str_replace(['(', ')'], $preserveSpaces ? ' ' : '', $phone); |
|
401
|
|
|
} |
|
402
|
|
|
|
|
403
|
|
|
//remove multiple spaces |
|
404
|
|
|
$phone = str_replace_multiple_space($phone); |
|
405
|
|
|
|
|
406
|
|
|
//remove spaces into and around () |
|
407
|
|
|
$phone = str_replace(['( ', ' )', ' (', ') '], ['(', ')', '(', ')'], $phone); |
|
408
|
|
|
|
|
409
|
|
|
$phone = trim($phone); |
|
410
|
|
|
|
|
411
|
|
|
return $phone; |
|
412
|
|
|
} |
|
413
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.