Overview
Comment:Fix Unicode LIKE to correctly handle _ and % characters
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | stable
Files: files | file ages | folders
SHA3-256: 00c271c4823f86ec3e6f3b3fc42e277fc7d68359b00df58d130a41181c40795b
User & Date: bohwaz on 2023-02-27 23:14:53
Other Links: manifest | tags
Context
2023-03-01
21:21
Improve search styling by using <mark> instead of check-in: a2f051cc22 user: bohwaz tags: trunk, stable
2023-02-27
23:14
Fix Unicode LIKE to correctly handle _ and % characters check-in: 00c271c482 user: bohwaz tags: trunk, stable
2023-02-26
21:46
Fix markdown help link check-in: 9353bd190e user: bohwaz tags: trunk, stable
Changes

Modified src/include/lib/Garradin/DB.php from [937dc0e057] to [b4bbb0ebf2].

390
391
392
393
394
395
396

397



398
399
400
401
402

403
404
405

406
407
408

409
410
411

412
413
414



415
416


417
418
419
420
421
422
423
424
425
        }

        $pattern = str_replace('’', '\'', $pattern); // Normalize French apostrophe
        $value = str_replace('’', '\'', $value);

        $id = md5($pattern . $escape);


        if (!array_key_exists($id, self::$unicode_patterns_cache)) {



            $escape = $escape ? '(?!' . preg_quote($escape, '/') . ')' : '';
            preg_match_all('/('.$escape.'[%_])|(\pL+)|(.+?)/iu', $pattern, $parts, PREG_SET_ORDER);
            $pattern = '';

            foreach ($parts as $part) {

                if (isset($part[3])) {
                    $pattern .= preg_quote(strtolower($part[0]), '/');
                }

                elseif (isset($part[2])) {
                    $pattern .= preg_quote(Utils::unicodeCaseFold($part[2]), '/');
                }

                elseif ($part[1] == '%') {
                    $pattern .= '.*';
                }

                elseif ($part[1] == '_') {
                    $pattern .= '.';
                }



            }



            $pattern = '/^' . $pattern . '$/im';
            self::$unicode_patterns_cache[$id] = $pattern;
        }

        $value = Utils::unicodeCaseFold($value);

        return (bool) preg_match(self::$unicode_patterns_cache[$id], $value);
    }
}







>

>
>
>
|
|



>
|


>
|
|

>
|


>
|


>
>
>
|
|
>
>









390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
        }

        $pattern = str_replace('’', '\'', $pattern); // Normalize French apostrophe
        $value = str_replace('’', '\'', $value);

        $id = md5($pattern . $escape);

        // Build regexp
        if (!array_key_exists($id, self::$unicode_patterns_cache)) {
            // Match escaped special chars | special chars | unicode characters | other
            $regexp = '/!([%_!])|([%_!])|(\pL+)|(.+?)/iu';
            $regexp = str_replace('!', preg_quote($escape, '/'), $regexp);

            preg_match_all($regexp, $pattern, $parts, PREG_SET_ORDER);
            $pattern = '';

            foreach ($parts as $part) {
                // Append other characters
                if (isset($part[4])) {
                    $pattern .= preg_quote(strtolower($part[0]), '/');
                }
                // Append unicode
                elseif (isset($part[3])) {
                    $pattern .= preg_quote(Utils::unicodeCaseFold($part[3]), '/');
                }
                // Append .*
                elseif (isset($part[2]) && $part[2] == '%') {
                    $pattern .= '.*';
                }
                // Append .
                elseif (isset($part[2]) && $part[2] == '_') {
                    $pattern .= '.';
                }
                // Append escaped special character
                else {
                    $pattern .= preg_quote($part[1], '/');
                }
            }

            // Store pattern in cache
            $pattern = '/^' . $pattern . '$/im';
            self::$unicode_patterns_cache[$id] = $pattern;
        }

        $value = Utils::unicodeCaseFold($value);

        return (bool) preg_match(self::$unicode_patterns_cache[$id], $value);
    }
}