Bug #73758 [Com]: is_dir Drive:Folder returns true - unexpected behavior
| From: | steve dot baldwin at publisure dot com | Date: | Fri, 16 Dec 2016 13:54:38 +0000 |
| Subject: | Bug #73758 [Com]: is_dir Drive:Folder returns true - unexpected behavior | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-206062@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73758&edit=1
ID: 73758
Comment by: steve dot baldwin at publisure dot com
Reported by: steve dot baldwin at publisure dot com
Summary: is_dir Drive:Folder returns true - unexpected
behavior
Status: Not a bug
Type: Bug
Package: Directory function related
Operating System: Windows 8.1
PHP Version: 5.6.29
Block user comment: N
Private report: N
New Comment:
ab@php.net;
Regardless of the escape sequence it will not resolve to the correct path.
var_dump(dirname("C:PHP\Welcome")); #C:PHP
var_dump(dirname("C:PHP\\Welcome")); #C:PHP
var_dump(dirname("C:PHP\\Help\\Me")); #C:PHP\Help
If anything, the escape \ should resolve it to C:PHPelcome.
I am running this directly using CLI so IIS and Apache has no influence on how this is resolved.
Previous Comments:
------------------------------------------------------------------------
[2016-12-16 13:04:03] ab@php.net
@requinix https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#fully_qualified_vs._relative_paths
Otherwise yes, not all the path variants are currently supported across PHP implementation.
Thanks.
------------------------------------------------------------------------
[2016-12-16 12:38:05] requinix@php.net
Given that I have a copy of PHP runnable at E:\php56, from the command line:
C:\Windows>E:\php56 -r "var_dump(is_dir('C:Windows'));"
bool(false)
C:\Windows>E:
E:\>E:\php56 -r "var_dump(is_dir('C:Windows'));"
bool(false)
E:\>cd /d C:\
C:\>E:\php56 -r "var_dump(is_dir('C:Windows'));"
bool(true)
C:\>E:
E:\>E:\php56 -r "var_dump(is_dir('C:Windows'));"
bool(true)
Additionally,
E:\>E:\php56 -r "chdir('C:/Windows');
var_dump(is_dir('C:Windows'));"
bool(false)
E:\>E:\php56 -r "chdir('C:/'); var_dump(is_dir('C:Windows'));"
bool(true)
E:\>E:\php56 -r "chdir('C:/Windows'); chdir('E:/');
var_dump(is_dir('C:Windows'));"
bool(false)
E:\>E:\php56 -r "chdir('C:/'); chdir('E:/');
var_dump(is_dir('C:Windows'));"
bool(true)
All of those outputs are correct. I can't easily test is what happens from with IIS or Apache,
but the only change in behavior that I would expect is that C: is always interpreted to be the root
of the drive - "or the drive alone if none is set" clause from that link. But whatever
happens, it is Windows making the decision. At least as far as this code is concerned...
@ab: "Documented scenario"? Where?
That's probably related to this: realpath isn't aware of drive-relative paths.
C:\Windows>E:
E:\>E:\php56 -r "var_dump(is_dir('C:System32'));
var_dump(realpath('C:System32'));"
bool(true)
bool(false)
The bug is the inconsistency. Whether PHP enforces that C:foo is strictly equal to C:\foo or whether
it obeys the rules of the operating system, all of the filesystem functions should work the same
way.
https://github.com/php/php-src/blob/PHP-5.6.29/Zend/zend_virtual_cwd.c#L1260
------------------------------------------------------------------------
[2016-12-16 12:20:42] ab@php.net
You can read "c:php" as ".\php on drive C:", this is documented scenario. Note,
that "C:PHP\Test" is wrong, because '\t' is an escape sequence. Either
DIRECTORY_SEPARATOR, manually doubled backslashes or single quotes have to be used.
Thanks.
------------------------------------------------------------------------
[2016-12-16 12:02:21] steve dot baldwin at publisure dot com
Sorry, I meant to say, PHP is not correct with is_dir. Even if PHP is resolving this as a
'valid path' its not because windows cannot resolve it. Allowing this logic to proceed as
'working' means that further interactions with windows may cause further issues such as
broken file paths such as I have witnessed.
Please re-open this ticket.
------------------------------------------------------------------------
[2016-12-16 11:55:47] steve dot baldwin at publisure dot com
Actually I'm not sure that's correct. In the blog you linked to, in the test script an
environment variable is set;
// A hidden environment variable will be kept for each drive where a current directory is set
// (need to set via P/Invoke as .NET blocks this)
SetEnvironmentVariableW(@"=C:", @"C:\Program Files");
I believe this is what allows 'C:Foo' to resolve to C:\Program Files\Foo. If you use
dirname("C:PHP") it returns C:. however if you use dirname("C:PHP\Test") it will
return C:PHP. Either way it does look like PHP is actually correct regarding is_dir but windows has
some odd functionality regarding how this resolves.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=73758
--
Edit this bug report at https://bugs.php.net/bug.php?id=73758&edit=1