Completed
Push — master ( d0cfcf...43547c )
by Lorenzo
02:02
created

sanitize.php ➔ csse()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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