|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73797 __DIR__ !== getcwd() when starting php with a file in a junction
Submitted: 2016-12-21 03:32 UTC Modified: 2017-02-07 16:41 UTC
Avg. Score:3.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: anrdaemon at freemail dot ru Assigned:
Status: Not a bug Package: Filesystem function related
PHP Version: 7.1.0 OS: Windows
Private report: No CVE-ID: None
 [2016-12-21 03:32 UTC] anrdaemon at freemail dot ru
When running script from the current directory, you can't be sure if __DIR__ will match getcwd(), even if naive logic says they should be.

Test script:
mklink /J "%TEMP%\test.dir" "C:\Documents and Settings\Public\Desktop"
cd "%TEMP%\test.dir"
echo ^<^?php print __DIR__ . ^"\n^"; print getcwd() . ^"\n^"; > test.php
C:\php\php.exe -f test.php

Expected result:
I'm fully expecting equal output from both prints.

Actual result:
Actually, the output differs, as if __DIR__ is realpath()'d for some reason.


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-21 04:26 UTC] anrdaemon at freemail dot ru
Another interesting script to run in this directory:

print getcwd() . "\n";
print getcwd() . "\n";
print getcwd() . "\n";
print getcwd() . "\n";
 [2017-01-19 15:17 UTC] narf at devilix dot net
It might be helpful if you provide the actual/literal outputs that you get, as opposed to just describing them with words.

In my environment for example, all three of getcwd(), __DIR__ and realpath(__DIR__) return the same result, so it is unclear what you mean by "realpath()'d".
 [2017-01-24 10:34 UTC] anrdaemon at freemail dot ru
Literal output doesn't matter. (Though, you could easily predict it.)
The fact that the output differs - matters.
If "your environment" provides any different results, please describe exact steps you've made to set it up. As well as exact versions of OS and PHP used.
 [2017-01-24 10:43 UTC]
-Status: Open +Status: Feedback
 [2017-01-24 10:43 UTC]
C:\Users\*>mklink /j %temp%\test.dir C:\users\Public\Desktop
Junction created for C:\Users\*\AppData\Local\Temp\test.dir <<===>> C:\users\Public\Desktop

C:\Users\*>cd %temp%\test.dir

C:\Users\*\AppData\Local\Temp\test.dir>echo ^<^?php print __DIR__ . ^"\n^"; print getcwd() . ^"\n^"; > test.php
Access is denied.

C:\Users\*\AppData\Local\Temp\test.dir>*\php-7.1.0-nts-Win32-VC14-x64\php.exe -r "echo __DIR__; echo getcwd();"

The actual output does matter. You can redact portions if you want but only as long as it doesn't change the meaning of the path.

Your repro works fine for both me and @narf. *You* are the one with the unusual output so *you* must be the one who provides the exact details.
 [2017-01-26 06:26 UTC] anrdaemon at freemail dot ru
You did not set it up as described.
Your tests are not valid.
 [2017-02-05 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2017-02-05 08:44 UTC] anrdaemon at freemail dot ru
Just because you don't want to test it, doesn't mean it does not exist.
Please follow reproduction steps exactly as provided.
 [2017-02-05 08:51 UTC]
-Status: No Feedback +Status: Feedback
 [2017-02-05 08:51 UTC]
"Exactly as provided"? Okay.

C:\>mklink /J "%TEMP%\test.dir" "C:\Documents and Settings\Public\Desktop"
Junction created for C:\Users\*\AppData\Local\Temp\test.dir <<===>> C:\Documents and Settings\Public\Desktop

C:\>cd "%TEMP%\test.dir"

C:\Users\*\AppData\Local\Temp\test.dir>echo ^<^?php print __DIR__ . ^"\n^"; print getcwd() . ^"\n^"; > test.php
Access is denied.

C:\Users\*\AppData\Local\Temp\test.dir>C:\php\php.exe -f test.php
The system cannot find the path specified.

Now it's your turn:

What is the output when YOU run the steps exactly as provided?
 [2017-02-05 10:00 UTC] anrdaemon at freemail dot ru
> mklink /J "%TEMP%\test.dir" "C:\Documents and Settings\Public\Desktop"
соединение создано для C:\Users\ANRDAE~1\AppData\Local\Temp\test.dir <<===>> C:\Documents and Settings\Public\Desktop

> cd "%TEMP%\test.dir"

[SYSTEM@DAEMON-V7 C:\Users\ANRDAE~1\AppData\Local\Temp\test.dir]
> echo ^<^?php print __DIR__ . ^"\n^"; print getcwd() . ^"\n^"; > test.php

[SYSTEM@DAEMON-V7 C:\Users\ANRDAE~1\AppData\Local\Temp\test.dir]
> C:\php\php.exe -f test.php
C:\Documents and Settings\Public\Desktop

[SYSTEM@DAEMON-V7 C:\Users\ANRDAE~1\AppData\Local\Temp\test.dir]
> cd \ && del "%TEMP%\test.dir\test.php" && rd "%TEMP%\test.dir"

 [2017-02-05 10:17 UTC]
I'm not familiar with that "SYSTEM@DAEMON-V7" CLI. What is it? What if you try your steps from the regular cmd.exe?
 [2017-02-06 11:45 UTC] anrdaemon at freemail dot ru
You're not familiar with standard Windows CMD?

 [2017-02-06 11:58 UTC]
-Summary: __DIR__ !== getcwd() +Summary: __DIR__ !== getcwd() when starting php with a file in a junction -Status: Feedback +Status: Analyzed
 [2017-02-06 11:58 UTC]
I've never seen anyone modify it to look like Linux.

The repro is to start php.exe on a file that resides in a junction-ed directory. But I don't know whether this is a bug: __DIR__ reflects the actual path to the file (prevents symlink-type exploits) and getcwd() reflects the directory cmd was using when php.exe was started. I guess the latter could be modified to reflect the former?

But you shouldn't rely on __DIR__ == getcwd() anyways in case there's unexpected code that changes the working directory, as can happen when shutdown handlers are involved.

Is __DIR__ != getcwd() actually a problem for you (how so?) or did you just notice this was the case? If it is a problem then you simply chdir(__DIR__)?
 [2017-02-07 14:58 UTC] anrdaemon at freemail dot ru
If you think this behavior is by design, it may be worth explicitly mentioning this point in documentation.
I've seen such assumption (getcwd() == __DIR__) used in Composer code.
 [2017-02-07 15:01 UTC] anrdaemon at freemail dot ru
To clarify,
 [2017-02-07 15:08 UTC]
__FILE__ and __DIR__ being symlink-resolved is documented on getcwd() not being symlink-resolved is not explicitly mentioned, as this is the default assumption. To clarify your request, you wish the documentation to explicitly mention that getcwd() is not symlink-resolved, is that correct?

Note that the assumption of __DIR__ == getcwd() is meaningless regardless of symlink-resolution, because __DIR__ refers to the directory the current file resides in, which has *nothing* to do with the CWD.
 [2017-02-07 16:22 UTC] anrdaemon at freemail dot ru
No, __DIR__ is not symlink-resolved on Windows. Not fully, at least.

Also try the other script I provided.
Very… special experience, I'd say.

> type test.php
print getcwd() . "\n";
print getcwd() . "\n";
print getcwd() . "\n";
print getcwd() . "\n";

> test.php
C:\Documents and Settings\Public\Desktop
 [2017-02-07 16:41 UTC]
-Status: Analyzed +Status: Not a bug
 [2017-02-07 16:41 UTC]
It is symlink-resolved in the same way everything else is -- if the symlink-resolution itself is broken, that's a different issue. And as you point out, this issue is already tracked in another bug report.

As I don't see anything actionable in this report (as opposed to the other one), I'm closing this issue.
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sat May 15 12:01:23 2021 UTC