Completed
Push — master ( bf43fb...335c4e )
by Lorenzo
02:11
created

sanitize.php ➔ she()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 9.4285
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 texts before.
144
 * The following function removes all diacritics (marks like accents) from a given UTF8-encoded
145
 * texts and returns ASCii-text.
146
 * @param string $s
147
 * @return string
148
 * @see http://php.net/manual/en/normalizer.normalize.php#92592
149
 */
150
function normalizeUtf8String(string $s) : string
151
{
152
    $original_string = $s;
153
154
    // Normalizer-class missing!
155
    if (!class_exists("Normalizer", false)) {
156
        return $original_string;
157
    }
158
159
    // maps German (umlauts) and other European characters onto two characters before just removing diacritics
160
    $s = preg_replace('/\x{00c4}/u', "AE", $s);    // umlaut Ä => AE
161
    $s = preg_replace('/\x{00d6}/u', "OE", $s);    // umlaut Ö => OE
162
    $s = preg_replace('/\x{00dc}/u', "UE", $s);    // umlaut Ü => UE
163
    $s = preg_replace('/\x{00e4}/u', "ae", $s);    // umlaut ä => ae
164
    $s = preg_replace('/\x{00f6}/u', "oe", $s);    // umlaut ö => oe
165
    $s = preg_replace('/\x{00fc}/u', "ue", $s);    // umlaut ü => ue
166
    $s = preg_replace('/\x{00f1}/u', "ny", $s);    // ñ => ny
167
    $s = preg_replace('/\x{00ff}/u', "yu", $s);    // ÿ => yu
168
169
    // maps special characters (characters with diacritics) on their base-character followed by the diacritical mark
170
    // exmaple:  Ú => U´,  á => a`
171
    $s = Normalizer::normalize($s, Normalizer::FORM_D);
172
173
    $s = preg_replace('/\pM/u', "", $s);    // removes diacritics
174
175
    $s = preg_replace('/\x{00df}/u', "ss", $s);    // maps German ß onto ss
176
    $s = preg_replace('/\x{00c6}/u', "AE", $s);    // Æ => AE
177
    $s = preg_replace('/\x{00e6}/u', "ae", $s);    // æ => ae
178
    $s = preg_replace('/\x{0132}/u', "IJ", $s);    // ? => IJ
179
    $s = preg_replace('/\x{0133}/u', "ij", $s);    // ? => ij
180
    $s = preg_replace('/\x{0152}/u', "OE", $s);    // Œ => OE
181
    $s = preg_replace('/\x{0153}/u', "oe", $s);    // œ => oe
182
183
    $s = preg_replace('/\x{00d0}/u', "D", $s);    // Ð => D
184
    $s = preg_replace('/\x{0110}/u', "D", $s);    // Ð => D
185
    $s = preg_replace('/\x{00f0}/u', "d", $s);    // ð => d
186
    $s = preg_replace('/\x{0111}/u', "d", $s);    // d => d
187
    $s = preg_replace('/\x{0126}/u', "H", $s);    // H => H
188
    $s = preg_replace('/\x{0127}/u', "h", $s);    // h => h
189
    $s = preg_replace('/\x{0131}/u', "i", $s);    // i => i
190
    $s = preg_replace('/\x{0138}/u', "k", $s);    // ? => k
191
    $s = preg_replace('/\x{013f}/u', "L", $s);    // ? => L
192
    $s = preg_replace('/\x{0141}/u', "L", $s);    // L => L
193
    $s = preg_replace('/\x{0140}/u', "l", $s);    // ? => l
194
    $s = preg_replace('/\x{0142}/u', "l", $s);    // l => l
195
    $s = preg_replace('/\x{014a}/u', "N", $s);    // ? => N
196
    $s = preg_replace('/\x{0149}/u', "n", $s);    // ? => n
197
    $s = preg_replace('/\x{014b}/u', "n", $s);    // ? => n
198
    $s = preg_replace('/\x{00d8}/u', "O", $s);    // Ø => O
199
    $s = preg_replace('/\x{00f8}/u', "o", $s);    // ø => o
200
    $s = preg_replace('/\x{017f}/u', "s", $s);    // ? => s
201
    $s = preg_replace('/\x{00de}/u', "T", $s);    // Þ => T
202
    $s = preg_replace('/\x{0166}/u', "T", $s);    // T => T
203
    $s = preg_replace('/\x{00fe}/u', "t", $s);    // þ => t
204
    $s = preg_replace('/\x{0167}/u', "t", $s);    // t => t
205
206
    // remove all non-ASCii characters
207
    $s = preg_replace('/[^\0-\x80]/u', "", $s);
208
209
    // possible errors in UTF8-regular-expressions
210
    if (isNullOrEmpty($s)) {
211
        return $original_string;
212
    }
213
    return $s;
214
}
215
216
/**
217
 * String Sanitizer for Filename
218
 * @param string $fileName
219
 * @param bool $sanitizeForPath if set to false (default) sanitize file name, otherwise file path name
220
 * @param string $charToReplaceWhiteSpace if empty (default) or ' ' then white space ' ' will be preservede
221
 * othrwise it will be replaced with $charToReplaceWhiteSpace.
222
 * @return string
223
 * @see for base script idea http://stackoverflow.com/a/2021729
224
 */
225
function sanitize_filename(
226
    string $fileName,
227
    bool $sanitizeForPath = false,
228
    string $charToReplaceWhiteSpace = ' '
229
) : string
230
{
231
    //check whitespace
232
    $fileName = str_replace(' ', $charToReplaceWhiteSpace, $fileName);
233
234
    // Remove any runs of periods - avoid Path Traversal Vulnerabilities OSWAP
235
    // https://www.owasp.org/index.php/Path_Traversal
236
    $notAllowedPath = [
237
        '//',
238
        '\\\\',
239
        '../',
240
        './',
241
        '..\\',
242
        '.\\',
243
        '%2e%2e%2f',
244
        '%2e%2e/',
245
        '..%2f',
246
        '%2e%2e%5c',
247
        '%2e%2e\\',
248
        '..%5c',
249
        '%252e%252e%255c',
250
        '..%255c',
251
        '..%c0%af',
252
        '..%c1%9c',
253
    ];
254
    while (str_contains($fileName, $notAllowedPath) !== false) {
255
        $fileName = str_replace($notAllowedPath, '', $fileName);
256
    }
257
258
    // Remove anything which isn't a word, whitespace, number
259
    // or any of the following caracters -_~,;[]().
260
    // If you don't need to handle multi-byte characters
261
    // you can use preg_replace rather than mb_ereg_replace
262
    // Thanks @Łukasz Rysiak!
263
    $fileName = mb_ereg_replace('([^\w\s\d\-_~,;\[\]\(\).' . ($sanitizeForPath ? '\\/' : '') . '])', '', $fileName);
264
265
    // remove exadecimal, non white space chars
266
    $fileName = mb_ereg_replace('([[:cntrl:]\b\0\n\r\t\f])', '', $fileName);
267
268
    //normalize and trim
269
    $fileName = trim(normalizeUtf8String($fileName));
270
271
    //do not start with ..
272
    while (starts_with($fileName, '..') !== false) {
273
        $fileName = substr($fileName, 2);
274
    }
275
276
    //do not end with ..
277
    while (ends_with($fileName, '..') !== false) {
278
        $fileName = substr($fileName, 0, -2);
279
    }
280
    //do not end with .
281
    while (ends_with($fileName, '.') !== false) {
282
        $fileName = substr($fileName, 0, -1);
283
    }
284
285
    return $fileName;
286
}
287
288
/**
289
 * String Sanitizer for Path name
290
 * @param string $pathName
291
 * @param string $charToReplaceWhiteSpace if empty (default) or ' ' then white space ' ' will be preservede
292
 * othrwise it will be replaced with $charToReplaceWhiteSpace.
293
 * @return string
294
 */
295
296
function sanitize_pathname(string $pathName, string $charToReplaceWhiteSpace) : string
297
{
298
    return sanitize_filename($pathName, true, $charToReplaceWhiteSpace);
299
}
300
301
/**
302
 * Perform XSS clean to prevent cross site scripting.
303
 *
304
 * @param array $data
305
 *
306
 * @return array
307
 */
308
function sanitize_arr_string_xss(array $data) : array
309
{
310
    foreach ($data as $k => $v) {
311
        $data[$k] = filter_var($v, FILTER_SANITIZE_STRING);
312
    }
313
    return $data;
314
}
315
316
/**
317
 * Perform XSS clean to prevent cross site scripting.
318
 *
319
 * @param string $data
320
 *
321
 * @return string
322
 *
323
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
324
 */
325
function sanitize_string_xss(string $data) : string
326
{
327
    return filter_var($data, FILTER_SANITIZE_STRING);
328
}
329
330
/**
331
 * Sanitize the string by urlencoding characters.
332
 *
333
 * @param string $value
334
 *
335
 * @return string
336
 *
337
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
338
 */
339
function sanitize_urlencode($value)
340
{
341
    return filter_var($value, FILTER_SANITIZE_ENCODED);
342
}
343
344
/**
345
 * Sanitize the string by removing illegal characters from emails.
346
 *
347
 * @param string $value
348
 *
349
 * @return string
350
 *
351
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
352
 */
353
function sanitize_email($value)
354
{
355
    return filter_var($value, FILTER_SANITIZE_EMAIL);
356
}
357
358
/**
359
 * Sanitize the string by removing illegal characters from numbers.
360
 *
361
 * @param string $value
362
 *
363
 * @return string
364
 *
365
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
366
 */
367
function sanitize_numbers($value)
368
{
369
    return filter_var($value, FILTER_SANITIZE_NUMBER_INT);
370
}
371
372
/**
373
 * Sanitize the string by removing illegal characters from float numbers.
374
 *
375
 * @param string $value
376
 *
377
 * @return string
378
 *
379
 * @see https://github.com/Wixel/GUMP/blob/master/gump.class.php
380
 */
381
function sanitize_floats($value)
382
{
383
    return filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
384
}
385