@@ -22,12 +22,28 @@ foreach (['NUL', 'nul:', '\\\\.\\NUL'] as $name) {
2222}
2323
2424echo "Reserved names in paths are rejected: \n" ;
25- foreach (['NUL ' , 'con ' , 'COM1 ' , 'LPT9 ' , 'CONIN$ ' , 'NUL.txt ' , ' con.php ' , ' aux:stream ' , ' NUL .txt ' , ' NUL :txt ' , ' . \\NUL ' ] as $ name ) {
25+ foreach (['NUL ' , 'con ' , 'COM1 ' , 'LPT9 ' , 'CONIN$ ' , '. \\NUL ' ] as $ name ) {
2626 $ blocked = $ dir . DIRECTORY_SEPARATOR . $ name ;
2727 var_dump (@fopen ($ blocked , 'wb ' ) === false );
2828 var_dump (file_exists ($ blocked ));
2929}
30- var_dump (@fopen ('NUL.txt ' , 'wb ' ) === false );
30+
31+ echo "Suffixed device names: \n" ;
32+ foreach (['NUL.txt ' , 'con.php ' , 'aux:stream ' , 'NUL .txt ' , 'NUL :txt ' ] as $ name ) {
33+ $ file = $ dir . DIRECTORY_SEPARATOR . $ name ;
34+ $ h = @fopen ($ file , 'wb ' );
35+ if (PHP_WINDOWS_VERSION_BUILD < 22000 ) {
36+ var_dump ($ h === false );
37+ } else {
38+ // Windows 11 treats these as regular files
39+ var_dump (is_resource ($ h ) && (fstat ($ h )['mode ' ] & 0170000 ) === 0100000 );
40+ fclose ($ h );
41+ // Delete the base file and its streams
42+ $ base = $ dir . DIRECTORY_SEPARATOR . explode (': ' , $ name )[0 ];
43+ unlink ('\\\\. \\' . $ base . '::$DATA ' );
44+ }
45+ var_dump (file_exists ($ file ));
46+ }
3147var_dump (@stat ($ dir . DIRECTORY_SEPARATOR . 'NUL ' ) === false );
3248var_dump (@mkdir ($ dir . DIRECTORY_SEPARATOR . 'NUL ' ) === false );
3349var_dump (@rename (__FILE__ , $ dir . DIRECTORY_SEPARATOR . 'PRN ' ) === false );
@@ -61,6 +77,7 @@ bool(true)
6177bool(false)
6278bool(true)
6379bool(false)
80+ Suffixed device names:
6481bool(true)
6582bool(false)
6683bool(true)
@@ -75,7 +92,6 @@ bool(true)
7592bool(true)
7693bool(true)
7794bool(true)
78- bool(true)
7995Similar names are fine:
8096bool(true)
8197bool(true)
0 commit comments