From 5a8213a08456ebd470e570902d20862af17c8982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Mon, 16 Mar 2026 23:42:29 +0100 Subject: [PATCH] Relax allowed characters in file names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows all unicode letters and all unicode numbers instead of only a-z, A-Z, 0-9. Signed-off-by: Maximilian Krög --- libraries/classes/Sanitize.php | 10 ++-------- test/classes/SanitizeTest.php | 28 ++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/libraries/classes/Sanitize.php b/libraries/classes/Sanitize.php index f8366aec60..3797db4cdd 100644 --- a/libraries/classes/Sanitize.php +++ b/libraries/classes/Sanitize.php @@ -247,14 +247,8 @@ class Sanitize */ public static function sanitizeFilename($filename, $replaceDots = false) { - $pattern = '/[^A-Za-z0-9_'; - // if we don't have to replace dots - if (! $replaceDots) { - // then add the dot to the list of legit characters - $pattern .= '.'; - } - - $pattern .= '-]/'; + // Keep only numbers (N), letters (L), dash, underbar, and maybe dot + $pattern = '/[^\p{N}\p{L}' . ($replaceDots ? '' : '.') . '_-]/u'; $filename = preg_replace($pattern, '_', $filename); return $filename; diff --git a/test/classes/SanitizeTest.php b/test/classes/SanitizeTest.php index f99c8db0dc..b760e4173e 100644 --- a/test/classes/SanitizeTest.php +++ b/test/classes/SanitizeTest.php @@ -6,6 +6,10 @@ namespace PhpMyAdmin\Tests; use PhpMyAdmin\Sanitize; +use function implode; +use function range; +use function str_repeat; + /** * @covers \PhpMyAdmin\Sanitize */ @@ -158,10 +162,30 @@ class SanitizeTest extends AbstractTestCase /** * Test for Sanitize::sanitizeFilename + * + * @dataProvider providerTestSanitizeFileName */ - public function testSanitizeFilename(): void + public function testSanitizeFilename(string $expected, string $input, bool $replaceDot): void { - self::assertSame('File_name_123', Sanitize::sanitizeFilename('File_name 123')); + self::assertSame($expected, Sanitize::sanitizeFilename($input, $replaceDot)); + } + + /** @psalm-return list */ + public static function providerTestSanitizeFileName(): array + { + return [ + ['Hello123', 'Hello123', false], + ['宮保雞丁', '宮保雞丁', false], + ['Україна', 'Україна', false], + ['-_-', '-.-', true], + ['-.-', '-.-', false], + ['___', '"\'"', false], + ['_test_', '', false], + ['Hello__World_', "Hello\r\nWorld!", false], + ['_', "\u{fffd}", false], + ['_', '🚀', false], + [str_repeat('_', 32), implode('', range("\0", "\x1f")), false], + ]; } /**