Completed
Push — master ( ec6ab3...598217 )
by Lorenzo
03:27
created

sanitize.php ➔ sanitize_phone()   C

Complexity

Conditions 8
Paths 4

Size

Total Lines 29
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 13
nc 4
nop 2
dl 0
loc 29
rs 5.3846
c 0
b 0
f 0
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
    $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 ()
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

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.

Loading history...
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