@@ -146,6 +146,10 @@ public function dataValidateFilename(): array {
146146 // needed for Windows namespaces
147147 'com1.suffix ' , ['.htaccess ' ], ['com1 ' ], [], [], ReservedWordException::class
148148 ],
149+ 'forbidden basename case insensitive ' => [
150+ // needed for Windows namespaces
151+ 'COM1.suffix ' , ['.htaccess ' ], ['com1 ' ], [], [], ReservedWordException::class
152+ ],
149153 'forbidden basename for hidden files ' => [
150154 // needed for Windows namespaces
151155 '.thumbs.db ' , ['.htaccess ' ], ['.thumbs ' ], [], [], ReservedWordException::class
@@ -159,6 +163,9 @@ public function dataValidateFilename(): array {
159163 'invalid extension ' => [
160164 'a: b.txt ' , ['.htaccess ' ], [], ['.txt ' ], [], InvalidPathException::class
161165 ],
166+ 'invalid extension case insensitive ' => [
167+ 'a: b.TXT ' , ['.htaccess ' ], [], ['.txt ' ], [], InvalidPathException::class
168+ ],
162169 'empty filename ' => [
163170 '' , [], [], [], [], EmptyFileNameException::class
164171 ],
@@ -199,7 +206,6 @@ public function data4ByteUnicode(): array {
199206 return [
200207 ['plane 1 𐪅 ' ],
201208 ['emoji 😶🌫️ ' ],
202-
203209 ];
204210 }
205211
@@ -284,4 +290,88 @@ public function dataIsForbidden(): array {
284290 ],
285291 ];
286292 }
293+
294+ /**
295+ * @dataProvider dataGetForbiddenExtensions
296+ */
297+ public function testGetForbiddenExtensions (array $ configValue , array $ expectedValue ): void {
298+ $ validator = new FilenameValidator ($ this ->l10n , $ this ->database , $ this ->config , $ this ->logger );
299+ $ this ->config
300+ // only once - then cached
301+ ->expects (self ::once ())
302+ ->method ('getSystemValue ' )
303+ ->with ('forbidden_filename_extensions ' , ['.filepart ' ])
304+ ->willReturn ($ configValue );
305+
306+ self ::assertEqualsCanonicalizing ($ expectedValue , $ validator ->getForbiddenExtensions ());
307+ }
308+
309+ public static function dataGetForbiddenExtensions (): array {
310+ return [
311+ // default
312+ [['.filepart ' ], ['.filepart ' , '.part ' ]],
313+ // always include .part
314+ [[], ['.part ' ]],
315+ // handle case insensitivity
316+ [['.TXT ' ], ['.txt ' , '.part ' ]],
317+ ];
318+ }
319+
320+ /**
321+ * @dataProvider dataGetForbiddenFilenames
322+ */
323+ public function testGetForbiddenFilenames (array $ configValue , array $ legacyValue , array $ expectedValue ): void {
324+ $ validator = new FilenameValidator ($ this ->l10n , $ this ->database , $ this ->config , $ this ->logger );
325+ $ this ->config
326+ // only once - then cached
327+ ->expects (self ::exactly (2 ))
328+ ->method ('getSystemValue ' )
329+ ->willReturnMap ([
330+ ['forbidden_filenames ' , ['.htaccess ' ], $ configValue ],
331+ ['blacklisted_files ' , [], $ legacyValue ],
332+ ]);
333+
334+ $ this ->logger
335+ ->expects (empty ($ legacyValue ) ? self ::never () : self ::once ())
336+ ->method ('warning ' );
337+
338+ self ::assertEqualsCanonicalizing ($ expectedValue , $ validator ->getForbiddenFilenames ());
339+ }
340+
341+ public static function dataGetForbiddenFilenames (): array {
342+ return [
343+ // default
344+ [['.htaccess ' ], [], ['.htaccess ' ]],
345+ // with legacy values
346+ [['.htaccess ' ], ['legacy ' ], ['.htaccess ' , 'legacy ' ]],
347+ // handle case insensitivity
348+ [['FileName ' , '.htaccess ' ], ['LegAcy ' ], ['.htaccess ' , 'filename ' , 'legacy ' ]],
349+ ];
350+ }
351+
352+ /**
353+ * @dataProvider dataGetForbiddenBasenames
354+ */
355+ public function testGetForbiddenBasenames (array $ configValue , array $ expectedValue ): void {
356+ $ validator = new FilenameValidator ($ this ->l10n , $ this ->database , $ this ->config , $ this ->logger );
357+ $ this ->config
358+ // only once - then cached
359+ ->expects (self ::once ())
360+ ->method ('getSystemValue ' )
361+ ->with ('forbidden_filename_basenames ' , [])
362+ ->willReturn ($ configValue );
363+
364+ self ::assertEqualsCanonicalizing ($ expectedValue , $ validator ->getForbiddenBasenames ());
365+ }
366+
367+ public static function dataGetForbiddenBasenames (): array {
368+ return [
369+ // default
370+ [[], []],
371+ // with values
372+ [['aux ' , 'com0 ' ], ['aux ' , 'com0 ' ]],
373+ // handle case insensitivity
374+ [['AuX ' , 'COM1 ' ], ['aux ' , 'com1 ' ]],
375+ ];
376+ }
287377}
0 commit comments