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
 [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 13:01:31 2024 UTC