Bug #73758 [Com]: is_dir Drive:Folder returns true - unexpected behavior

From: 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

« previous php.bugs (#206062) next »