php / php/php-src

directory functions doesn't support IO_REPARSE_TAG_LX_SYMLINK reparse points (Unix/WSL symlinks)

Open
#15,588 4 comments 0 reactions 1 assignee View on GitHub

@cmb69 is already working on this.

Since Aug 25, 2024.

Bug Category: Engine OS: Windows Status: Needs Triage
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

builtin (extension "standard") function is_file and is_dir doesn't work properly if the path I'm trying to use these files on contains a unix symlink (IO_REPARSE_TAG_LX_SYMLINK reparse points).

These functions, before trying to detect if the path point to a file or directory try to get the real path of the path using the function
tsrm_realpath_r inside zend_vritual_cwd.c where t traverse all path component backwards, opening all encountered paths.
If one of these paths get a FILE_ATTRIBUTE_REPARSE_POINT attribute, the function try to resolve the reparse point using FSCTL_GET_REPARSE_POINT DeviceIOControl. It breaks here as the returned type IO_REPARSE_TAG_LX_SYMLINK isn't handled, exiting the function.

This is a serious issue with "wine" as all native symlinks are treated as IO_REPARSE_TAG_LX_SYMLINK, and I confirmed that treating the resulting symlink as IO_REPARSE_TAG_SYMLINK is correcting the issue. It's however a risky change on wine side, as both symlinks can have a different implementation on filesystem, and I'm not sure if is always transparent to the application.

tsrm_realpath_r should support IO_REPARSE_TAG_LX_SYMLINK (support should be more trivial then IO_REPARSE_TAG_SYMLINK, but I'm also finding strange that these functions do traverse the path in this way. It doesn't seem to add some value at first glance, at least for paths that contains symlinks, but don't end in symlinks themselves.

I'm bound to using wine here, as I'm using an application Windows only, and it use php for various operations. But the way the application is starting php don't allow me to replace the windows version with a native linux version.

Resulted in this output (call done inside the interactive shell):

php > $path = "C:\\users\\lorenzo\\Scrivania\\Fanbox";
php > $ret =  is_dir($path);
php > var_dump($ret);
bool(false)

Scrivania is a symlink to Z:\home\lorenzo\Desktop

But I expected this output instead:

php > $path = "C:\\users\\lorenzo\\Scrivania\\Fanbox";
php > $ret =  is_dir($path);
php > var_dump($ret);
bool(true)
PHP Version

PHP 8.2.7

Operating System

ArchLinux (WINE Staging 9.15)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.