|
|
|
@ -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' |
|
|
|
|
], |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|