diff options
Diffstat (limited to 'tests/lib/Files/FilenameValidatorTest.php')
-rw-r--r-- | tests/lib/Files/FilenameValidatorTest.php | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/tests/lib/Files/FilenameValidatorTest.php b/tests/lib/Files/FilenameValidatorTest.php index 45f681bd453..c5361e2c648 100644 --- a/tests/lib/Files/FilenameValidatorTest.php +++ b/tests/lib/Files/FilenameValidatorTest.php @@ -374,4 +374,138 @@ class FilenameValidatorTest extends TestCase { [['AuX', 'COM1'], ['aux', 'com1']], ]; } + + /** + * @dataProvider dataSanitizeFilename + */ + public function testSanitizeFilename( + string $filename, + array $forbiddenNames, + array $forbiddenBasenames, + array $forbiddenExtensions, + array $forbiddenCharacters, + string $expected, + ): void { + /** @var FilenameValidator&MockObject */ + $validator = $this->getMockBuilder(FilenameValidator::class) + ->onlyMethods([ + 'getForbiddenBasenames', + 'getForbiddenExtensions', + 'getForbiddenFilenames', + 'getForbiddenCharacters', + ]) + ->setConstructorArgs([$this->l10n, $this->database, $this->config, $this->logger]) + ->getMock(); + + $validator->method('getForbiddenBasenames') + ->willReturn($forbiddenBasenames); + $validator->method('getForbiddenCharacters') + ->willReturn($forbiddenCharacters); + $validator->method('getForbiddenExtensions') + ->willReturn($forbiddenExtensions); + $validator->method('getForbiddenFilenames') + ->willReturn($forbiddenNames); + + $this->assertEquals($expected, $validator->sanitizeFilename($filename)); + } + + public function dataSanitizeFilename(): array { + return [ + 'valid name' => [ + 'a * b.txt', ['.htaccess'], [], [], [], 'a * b.txt' + ], + 'forbidden name in the middle is ok' => [ + 'a.htaccess.txt', ['.htaccess'], [], [], [], 'a.htaccess.txt' + ], + 'forbidden name on the beginning' => [ + '.htaccess.sample', ['.htaccess'], [], [], [], '.htaccess.sample' + ], + 'forbidden name' => [ + '.htaccess', ['.htaccess'], [], [], [], '.htaccess (renamed)' + ], + 'forbidden name - name is case insensitive' => [ + 'COM1', ['.htaccess', 'com1'], [], [], [], 'COM1 (renamed)' + ], + 'forbidden basename' => [ + 'com1.suffix', ['.htaccess'], ['com1'], [], [], 'com1 (renamed).suffix' + ], + 'forbidden basename case insensitive' => [ + // needed for Windows namespaces + 'COM1.suffix', ['.htaccess'], ['com1'], [], [], 'COM1 (renamed).suffix' + ], + 'forbidden basename for hidden files' => [ + // needed for Windows namespaces + '.thumbs.db', ['.htaccess'], ['.thumbs'], [], [], '.thumbs (renamed).db' + ], + 'invalid character' => [ + 'a: b.txt', ['.htaccess'], [], [], [':'], 'a b.txt', + ], + 'invalid extension' => [ + 'a: b.txt', ['.htaccess'], [], ['.txt'], [], 'a: b' + ], + 'invalid extension case insensitive' => [ + 'a: b.TXT', ['.htaccess'], [], ['.txt'], [], 'a: b' + ], + 'empty filename' => [ + '', [], [], [], [], 'renamed file' + ], + ]; + } + + /** + * @dataProvider dataSanitizeFilenameCharacterReplacement + */ + public function testSanitizeFilenameCharacterReplacement( + string $filename, + array $forbiddenCharacters, + ?string $characterReplacement, + ?string $expected, + ): void { + /** @var FilenameValidator&MockObject */ + $validator = $this->getMockBuilder(FilenameValidator::class) + ->onlyMethods([ + 'getForbiddenBasenames', + 'getForbiddenExtensions', + 'getForbiddenFilenames', + 'getForbiddenCharacters', + ]) + ->setConstructorArgs([$this->l10n, $this->database, $this->config, $this->logger]) + ->getMock(); + + $validator->method('getForbiddenBasenames') + ->willReturn([]); + $validator->method('getForbiddenCharacters') + ->willReturn($forbiddenCharacters); + $validator->method('getForbiddenExtensions') + ->willReturn([]); + $validator->method('getForbiddenFilenames') + ->willReturn([]); + + if ($expected === null) { + $this->expectException(\InvalidArgumentException::class); + $validator->sanitizeFilename($filename, $characterReplacement); + } else { + $this->assertEquals($expected, $validator->sanitizeFilename($filename, $characterReplacement)); + } + } + + public static function dataSanitizeFilenameCharacterReplacement(): array { + return [ + 'default' => [ + 'foo*bar', ['*'], null, 'foo bar' + ], + 'default - space not allowed' => [ + 'foo*bar', ['*', ' '], null, 'foo_bar' + ], + 'default - space and underscore not allowed' => [ + 'foo*bar', ['*', ' ', '_'], null, 'foo-bar' + ], + 'default - no replacement' => [ + 'foo*bar', ['*', ' ', '_', '-'], null, null + ], + 'custom replacement' => [ + 'foo*bar', ['*'], 'x', 'fooxbar' + ], + ]; + } } |