php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72364 SplFileInfo->isFile() returns true for symlinks
Submitted: 2016-06-08 21:59 UTC Modified: 2016-06-09 18:11 UTC
Votes:3
Avg. Score:3.7 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (50.0%)
From: kevin dot boyd at gmail dot com Assigned:
Status: Verified Package: SPL related
PHP Version: 5.5.36 OS: OS X and Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kevin dot boyd at gmail dot com
New email:
PHP Version: OS:

 

 [2016-06-08 21:59 UTC] kevin dot boyd at gmail dot com
Description:
------------
The documentation for ->isFile() says that it should not return true for links, but I was not able to observe this behaviour.

http://php.net/manual/en/splfileinfo.isfile.php

(This was encountered on PHP 5.5.35 and 5.3.10 on OS X and Ubuntu 12.04.5)

Test script:
---------------
<?php

touch('test.txt');
symlink('test.txt', 'link.txt');

$file = new SplFileInfo('link.txt');
if ($file->isFile()) {
    echo "Expected isFile to return false, but it returned true!\n";
}
unlink('test.txt');
unlink('link.txt');

Expected result:
----------------
I expect it to return no output. ->isFile() should return false for symbolic links.

Actual result:
--------------
$ php repro.php
Expected isFile to return false, but it returned true!

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-06-09 06:25 UTC] kevin dot boyd at gmail dot com
I've done some poking around and found that this appears to be the way lstat() behaves in C - either that or there's some funky bitshifting going on that I don't fully grok.

Theoretically, if the "case FS_IS_FILE:" block were modified in ext/standard/filestat.c (around line 991), that could potentially bring the behaviour in line with what has been documented.

Current logic:

  RETURN_BOOL(S_ISREG(ssb.sb.st_mode));

Proposed change:

  RETURN_BOOL(S_ISREG(ssb.sb.st_mode) && !S_ISLNK(ssb.sb.st_mode));

I don't know what the potential ramifications of this change might be.
 [2016-06-09 18:11 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2016-06-09 18:11 UTC] cmb@php.net
I can confirm the issue for Windows (PHP 7.0.7).

> Theoretically, if the "case FS_IS_FILE:" block were modified in
> ext/standard/filestat.c (around line 991), that could
> potentially bring the behaviour in line with what has been
> documented.

Well, in this case I'd rather fix the documentation to match the
actual behavior. That avoids any BC break, and there is already
SplFileInfo::isLink().
 [2016-06-15 21:48 UTC] kevin dot boyd at gmail dot com
> Well, in this case I'd rather fix the documentation to match the
> actual behavior. That avoids any BC break, and there is already
> SplFileInfo::isLink().

This certainly seems like the pragmatic approach. I wouldn't want
to change it in a way that makes it behave differently than it
does in other C-based implementations. Still, I wonder if the
ordering of the cases in the switch statement is done some other
way in other libraries - such as with link first. That could prove
to be the difference, if the bit-shifted value was matching both
file and link.
 [2019-06-20 09:44 UTC] dev at mike dot pp dot ua
The described is only true for symlinks of files.

But the exact same bug/behavior exists for the isDir() method if called on symlinks of directories.

This all is also true for other classes, e.g. the DirectoryIterator.

P.S. I checked with php7.2 on linux.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 18:01:29 2024 UTC