|
|
|
@ -650,12 +650,17 @@ class Filesystem
|
|
|
|
|
*
|
|
|
|
|
* We test if the path is a directory and not an ordinary link, then check
|
|
|
|
|
* that the mode value returned from lstat (which gives the status of the
|
|
|
|
|
* link itself) is not a directory.
|
|
|
|
|
* link itself) is not a directory, by replicating the POSIX S_ISDIR test.
|
|
|
|
|
*
|
|
|
|
|
* This relies on the fact that PHP does not set this value because there is
|
|
|
|
|
* no universal file type flag for a junction or a mount point. However a
|
|
|
|
|
* bug in PHP can cause a random value to be returned and this could result
|
|
|
|
|
* in a junction not being detected: https://bugs.php.net/bug.php?id=77552
|
|
|
|
|
* This logic works because PHP does not set the mode value for a junction,
|
|
|
|
|
* since there is no universal file type flag for it. Unfortunately an
|
|
|
|
|
* uninitialized variable in PHP prior to 7.2.16 and 7.3.3 may cause a
|
|
|
|
|
* random value to be returned. See https://bugs.php.net/bug.php?id=77552
|
|
|
|
|
*
|
|
|
|
|
* If this random value passes the S_ISDIR test, then a junction will not be
|
|
|
|
|
* detected and a recursive delete operation could lead to loss of data in
|
|
|
|
|
* the target directory. Note that Windows rmdir can handle this situation
|
|
|
|
|
* and will only delete the junction (from Windows 7 onwards).
|
|
|
|
|
*
|
|
|
|
|
* @param string $junction Path to check.
|
|
|
|
|
* @return bool
|
|
|
|
@ -673,7 +678,7 @@ class Filesystem
|
|
|
|
|
clearstatcache(true, $junction);
|
|
|
|
|
$stat = lstat($junction);
|
|
|
|
|
|
|
|
|
|
// S_IFDIR is 0x4000, S_IFMT is the 0xF000 bitmask
|
|
|
|
|
// S_ISDIR test (S_IFDIR is 0x4000, S_IFMT is 0xF000 bitmask)
|
|
|
|
|
return $stat ? 0x4000 !== ($stat['mode'] & 0xF000) : false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|