[php-src] Issue #14779: Trailing multi dots in filenames are ignored in Windows
| From: | tsybot | Date: | Wed, 03 Jul 2024 06:08:46 +0000 |
| Subject: | [php-src] Issue #14779: Trailing multi dots in filenames are ignored in Windows | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-247213@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/14779
Author: tsybot
### Description
Additional dots ignored windows [Windows treats filenames with trailing dots in a special
way](https://docs.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/file-folder-name-whitespace-characters),
namely that these are basically ignored by most APIs.
But, anyway on windows we can create this files with prefix "\\\\?\\", for example:
```
ECHO 123> \\?\C:\app\flag.txt....
```
Check file is created
```
C:\app>dir
Volume in drive C has no label.
Volume Serial Number is F6CA-D975
Directory of C:\app
07/03/2024 07:53 AM <DIR> .
06/23/2024 03:03 PM <DIR> ..
07/03/2024 07:53 AM 5 flag.txt....
```
So file exists but realpath function not find it, and functions who use VCWD_REALPATH iside same not
found it and open_basedir check can not passed because use VCWD_REALPATH
```php
<?php
var_dump(realpath("C:\\app\\flag.txt...."));
var_dump(bindtextdomain('xxx', "C:\\app\\flag.txt...."));
var_dump(file_get_contents("C:\\app\\flag.txt...."));
```
try to use "\\\\?\\" prefix
```php
<?php
var_dump(realpath("\\\\?\\C:\\app\\flag.txt...."));
var_dump(bindtextdomain('xxx', "\\\\?\\C:\\app\\flag.txt...."));
var_dump(file_get_contents("\\\\?\\C:\\app\\flag.txt...."));
```
Resulted in this output:
```
bool(false)
bool(false)
Warning: file_get_contents(C:\app\flag.txt....): Failed to open stream: No such file or directory in
C:\app\test.php on line 3
bool(false)
bool(false)
bool(false)
Warning: file_get_contents(\\?\C:\app\flag.txt....): Failed to open stream: No such file or
directory in C:\app\test.php on line 3
bool(false)
```
But I expected this output instead:
```
string(19) "C:\app\flag.txt...."
string(19) "C:\app\flag.txt...."
string(3) "123"
string(19) "C:\app\flag.txt...."
string(19) "C:\app\flag.txt...."
string(3) "123"
```
If we enable open_basedir and set it to C:\\app\\ it falied on open_basedir check with prefix
"\\\\?\\"
```php
<?php
var_dump(file_get_contents("C:\\app\\flag.txt...."));
var_dump(file_get_contents("\\\\?\\C:\\app\\flag.txt...."));
```
```
Warning: file_get_contents(C:\app\flag.txt....): Failed to open stream: No such file or directory in
C:\app\test.php on line 1
bool(false)
Warning: file_get_contents(): open_basedir restriction in effect. File(\\?\C:\app\flag.txt....) is
not within the allowed path(s): (C:\\app\\) in C:\app\test.php on line 2
Warning: file_get_contents(\\?\C:\app\flag.txt....): Failed to open stream: Operation not permitted
in C:\app\test.php on line 2
bool(false)
```
All function who use open_basedir check fail to check if use "\\\\?\\" prefix, but if
open_basedir not set functions: is_readable,file_exists,is_writable,filesize,fileatime .. maybe more
- is working prefect with "\\\\?\\" prefix,, im not check all functions.
Not working functions: realpath,file_get_contents,bindtextdomain,readfile,file ... maybe more
[Fix GH-9227: Trailing dots and spaces in filenames are
ignored](https://github.com/php/php-src/commit/a1f5c8a587ff6dfa309ccf34c1508a8977e77f82) this fix
fixed only one dot after filename but not fixed a multi dots
### PHP Version
PHP 8.3.6
### Operating System
Windows Server 2022