sanitize.php ➔ attre()   B
last analyzed

Complexity

Conditions 11
Paths 2

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 2
nop 1
dl 0
loc 37
rs 7.3166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 '&#xFFFD;';
102
                }
103
                $entities = array(
104
                    34 => '&quot;',
105
                    38 => '&amp;',
106
                    60 => '&lt;',
107
                    62 => '&gt;',
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
    if (class_exists('Normalizer', false)) {
174
        $s = normalizerUtf8Safe($s, Normalizer::FORM_D);
175
    }
176
177
    // possible errors in UTF8-regular-expressions
178
    if (isNullOrEmpty($s)) {
179
        return $original_string;
180
    }
181
182
    return $s;
183
}
184
185
/**
186
 * Normalize uft8 to various form with php normalizer function if exists,
187
 * otherwise return original string.
188
 * maps special characters (characters with diacritics) on their base-character
189
 * followed by the diacritical mark
190
 * exmaple:  Ú => U´,  á => a`
191
 * @param string $s
192
 * @param $normalizationForm UTF8 Normalization Form if empty Default Normalizer::FORM_D
193
 * @return string
194
 */
195
function normalizerUtf8Safe(string $s, $normalizationForm): string
196
{
197
    if (class_exists('Normalizer', false)) {
198
        $s = Normalizer::normalize($s, isNullOrEmpty($normalizationForm) ? Normalizer::FORM_D : $normalizationForm);
199
        return $s;
200
    }
201
    return $s;
202
}
203
204
/**
205
 * String Sanitizer for Filename
206
 * @param string $fileName
207
 * @param bool $sanitizeForPath if set to false (default) sanitize file name, otherwise file path name
208
 * @param string $charToReplaceWhiteSpace if empty (default) or ' ' then white space ' ' will be preservede
209
 * othrwise it will be replaced with $charToReplaceWhiteSpace.
210
 * @return string
211
 * @see for base script idea http://stackoverflow.com/a/2021729
212
 */
213
function sanitize_filename(
214
    string $fileName,
215
    bool $sanitizeForPath = false,
216
    string $charToReplaceWhiteSpace = ' '
217
): string {
218
    //check whitespace
219
    $fileName = str_replace(' ', $charToReplaceWhiteSpace, $fileName);
220
221
    // Remove any runs of periods - avoid Path Traversal Vulnerabilities OSWAP
222
    // https://www.owasp.org/index.php/Path_Traversal
223
    $notAllowedPath = [
224
        '//',
225
        '\\\\',
226
        '../',
227
        './',
228
        '..\\',
229
        '.\\',
230
        '%2e%2e%2f',
231
        '%2e%2e/',
232
        '..%2f',
233
        '%2e%2e%5c',
234
        '%2e%2e\\',
235
        '..%5c',
236
        '%252e%252e%255c',
237
        '..%255c',
238
        '..%c0%af',
239
        '..%c1%9c',
240
    ];
241
    while (str_contains_array($fileName, $notAllowedPath) !== false) {
242
        $fileName = str_replace($notAllowedPath, '', $fileName);
243
    }
244
245
    // Remove anything which isn't a word, whitespace, number
246
    // or any of the following caracters -_~,;[]().
247
    // If you don't need to handle multi-byte characters
248
    // you can use preg_replace rather than mb_ereg_replace
249
    // Thanks @Łukasz Rysiak!
250
    $fileName = mb_ereg_replace('([^\w\s\d\-_~,;\[\]\(\).' . ($sanitizeForPath ? '\\/' : '') . '])', '', $fileName);
251
252
    // remove exadecimal, non white space chars
253
    $fileName = mb_ereg_replace('([[:cntrl:]\b\0\n\r\t\f])', '', $fileName);
254
255
    //normalize and trim
256
    $fileName = trim(normalizeUtf8String($fileName));
257
258
    //do not start with ..
259
    while (starts_with($fileName, '..') !== false) {
260
        $fileName = substr($fileName, 2);
261
    }
262
263
    //do not end with ..
264
    while (ends_with($fileName, '..') !== false) {
265
        $fileName = substr($fileName, 0, -2);
266
    }
267
    //do not end with .
268
    while (ends_with($fileName, '.') !== false) {
269
        $fileName = substr($fileName, 0, -1);
270
    }
271
272
    return $fileName;
273
}
274
275
/**
276
 * String Sanitizer for Path name
277
 * @param string $pathName
278
 * @param string $charToReplaceWhiteSpace if empty (default) or ' ' then white space ' ' will be preservede
279
 * othrwise it will be replaced with $charToReplaceWhiteSpace.
280
 * @return string
281
 */
282
283
function sanitize_pathname(string $pathName, string $charToReplaceWhiteSpace): string
284
{
285
    return sanitize_filename($pathName, true, $charToReplaceWhiteSpace);
286
}
287
288
/**
289
 * Perform XSS clean to prevent cross site scripting.
290
 *
291
 * @param array $data
292
 *
293
 * @return array
294
 */
295
function sanitize_arr_string_xss(array $data): array
296
{
297
    foreach ($data as $k => $v) {
298
        $data[$k] = filter_var($v, FILTER_SANITIZE_STRING);
299
    }
300
    return $data;
301
}
302
303
/**
304
 * Perform XSS clean to prevent cross site scripting.
305
 *
306
 * @param string $data
307
 *
308
 * @return string
309
 *
310
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
311
 */
312
function sanitize_string_xss(string $data): string
313
{
314
    return filter_var($data, FILTER_SANITIZE_STRING);
315
}
316
317
/**
318
 * Sanitize the string by urlencoding characters.
319
 *
320
 * @param string $value
321
 *
322
 * @return string
323
 *
324
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
325
 */
326
function sanitize_urlencode($value)
327
{
328
    return filter_var($value, FILTER_SANITIZE_ENCODED);
329
}
330
331
/**
332
 * Sanitize the string by removing illegal characters from emails.
333
 *
334
 * @param string $value
335
 *
336
 * @return string
337
 *
338
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
339
 */
340
function sanitize_email($value)
341
{
342
    return filter_var($value, FILTER_SANITIZE_EMAIL);
343
}
344
345
/**
346
 * Sanitize the string by removing illegal characters from numbers.
347
 *
348
 * @param string $value
349
 *
350
 * @return string
351
 *
352
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
353
 */
354
function sanitize_numbers($value)
355
{
356
    return filter_var($value, FILTER_SANITIZE_NUMBER_INT);
357
}
358
359
/**
360
 * Sanitize the string by removing illegal characters from float numbers.
361
 *
362
 * @param string $value
363
 *
364
 * @return string
365
 *
366
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
367
 */
368
function sanitize_floats($value)
369
{
370
    return filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
371
}
372
373
/**
374
 * Sanitize the string by removing illegal characters from phone numbers
375
 * i.e.: optionally starts with +, optionally have prefix parenthesis and only number..
376
 * If preserveSpaces set to true, leave spaces and replace illegal chars with one space,
377
 * otherwise remove every spaces.
378
 *
379
 * @param string $value
380
 * @param bool $preserveSpaces If set to true, leave spaces and replace illegal chars with one space,
381
 * otherwise remove every spaces.
382
 *
383
 * @return string
384
 *
385
 */
386
function sanitize_phone($value, bool $preserveSpaces): string
387
{
388
    $startsWithPlus = starts_with($value, '+');
389
390
    $phone = mb_ereg_replace('([^\d\(\)' . ($preserveSpaces ? '[:space:]' : '') . '])', $preserveSpaces ? ' ' : '', $value);
391
    $phone = trim($phone);
392
393
    //revert initial + if needed
394
    if ($startsWithPlus) {
395
        $phone = '+' . $phone;
396
    }
397
398
    //check for illegal parenthesis
399
    if ((strpos($phone, '(') !== false || strpos($phone,
400
                ')') !== false) && !preg_match('/.*\([[:space:]0-9]{1,}\)[[:space:]0-9]{1,}/', $phone)
401
    ) {
402
        $phone = str_replace(['(', ')'], $preserveSpaces ? ' ' : '', $phone);
403
    }
404
405
    //remove multiple spaces
406
    $phone = str_replace_multiple_space($phone);
407
408
    //remove spaces into and around ()
409
    $phone = str_replace(['( ', ' )', ' (', ') '], ['(', ')', '(', ')'], $phone);
410
411
    $phone = trim($phone);
412
413
    return $phone;
414
}
415