From ee1c6bbdd02f3d115a59dfdcda48a00b596af089 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Fri, 7 Aug 2020 08:57:36 +0200 Subject: [PATCH] Respect symlinks in url_stat url_stat is called with an additional $flags argument by PHP. This includes an flag whether info about sylimk or symlink target should be returned. Prior to this change, stat was used all the time, delivering results for the target of symlinks. Respecting the flag, lstat is used to return info about the symlink instead, when requested. This will properly return infos for is_link() calls. --- src/IncludeInterceptor.php | 12 ++++++++++-- tests/IncludeInterceptorTest.php | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/IncludeInterceptor.php b/src/IncludeInterceptor.php index 91955c0..84121d8 100644 --- a/src/IncludeInterceptor.php +++ b/src/IncludeInterceptor.php @@ -374,12 +374,20 @@ public function unlink($path) return $return; } - public function url_stat($path) + public function url_stat($path, $flags) { self::disable(); try { - return is_readable($path) ? stat($path) : false; + if (is_readable($path) === false) { + return false; + } + + if ($flags & STREAM_URL_STAT_LINK) { + return lstat($path); + } + + return stat($path); } finally { self::enable(); } diff --git a/tests/IncludeInterceptorTest.php b/tests/IncludeInterceptorTest.php index 04a64cc..7b8900d 100644 --- a/tests/IncludeInterceptorTest.php +++ b/tests/IncludeInterceptorTest.php @@ -418,4 +418,19 @@ public function test_it_re_enables_interceptor_after_file_not_found_with_url_sta $this->fail('Badly set up test, exception was not thrown'); } + + public function test_it_respects_symlinks_in_url_stat(): void + { + $expected = include self::$files[2]; + + IncludeInterceptor::intercept(self::$files[1], self::$files[2]); + IncludeInterceptor::enable(); + + $symlink = sys_get_temp_dir() . '/symlink-intercept'; + self::$files[] = $symlink; + + symlink(self::$files[2], $symlink); + + $this->assertTrue(is_link($symlink)); + } }