From c4dfd6bec8d741866def1adf48f65de8777f4e0c Mon Sep 17 00:00:00 2001 From: Andrew Mackrodt Date: Mon, 16 Jul 2018 01:32:59 +0100 Subject: [PATCH 1/2] Fixes EioDriver and UvDriver readlink implementation --- lib/EioDriver.php | 11 ++++++++++- lib/UvDriver.php | 8 ++++++-- test/DriverTest.php | 37 +++++++++++++++++++++++++++++++++++++ test/UvDriverTest.php | 9 +++++++++ 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/lib/EioDriver.php b/lib/EioDriver.php index e3e6d3f..5efc511 100644 --- a/lib/EioDriver.php +++ b/lib/EioDriver.php @@ -296,10 +296,19 @@ public function readlink(string $path): Promise { $this->poll->listen($deferred->promise()); $priority = \EIO_PRI_DEFAULT; - \eio_readlink($path, $priority, [$this, "onGenericResult"], $deferred); + \eio_readlink($path, $priority, [$this, "onReadlink"], $deferred); return $deferred->promise(); } + + private function onReadlink($deferred, $result, $req) { + if ($result === -1) { + $deferred->fail(new FilesystemException(\eio_get_last_error($req))); + } else { + $deferred->resolve($result); + } + } + private function onGenericResult($deferred, $result, $req) { if ($result === -1) { $deferred->fail(new FilesystemException(\eio_get_last_error($req))); diff --git a/lib/UvDriver.php b/lib/UvDriver.php index af698c2..392fc51 100644 --- a/lib/UvDriver.php +++ b/lib/UvDriver.php @@ -312,8 +312,12 @@ public function readlink(string $path): Promise { $deferred = new Deferred; $this->poll->listen($deferred->promise()); - \uv_fs_readlink($this->loop, $path, function ($fh) use ($deferred) { - $deferred->resolve((bool) $fh); + \uv_fs_readlink($this->loop, $path, function ($fh, $target) use ($deferred) { + if (!(bool) $fh) { + $deferred->fail(new FilesystemException("Could not read symbolic link")); + } + + $deferred->resolve($target); }); return $deferred->promise(); diff --git a/test/DriverTest.php b/test/DriverTest.php index b49435e..7537a2b 100644 --- a/test/DriverTest.php +++ b/test/DriverTest.php @@ -57,6 +57,43 @@ public function testSymlink() { }); } + public function testReadlink() { + $this->execute(function () { + $fixtureDir = Fixture::path(); + + $original = "{$fixtureDir}/small.txt"; + $link = "{$fixtureDir}/symlink.txt"; + \symlink($original, $link); + + $this->assertSame($original, yield File\readlink($link)); + }); + } + + public function readlinkPathProvider() { + return [ + 'nonExistingPath' => [function () { + return Fixture::path() . '/' . uniqid(); + }], + 'notLink' => [function () { + return Fixture::path(); + }], + ]; + } + + /** + * @dataProvider readlinkPathProvider + * @expectedException \Amp\File\FilesystemException + * + * @param \Closure $linkResolver + */ + public function testReadlinkError(\Closure $linkResolver) { + $this->execute(function () use ($linkResolver) { + $link = $linkResolver(); + + yield File\readlink($link); + }); + } + public function testLstat() { $this->execute(function () { $fixtureDir = Fixture::path(); diff --git a/test/UvDriverTest.php b/test/UvDriverTest.php index e2e6f33..47bf566 100644 --- a/test/UvDriverTest.php +++ b/test/UvDriverTest.php @@ -22,4 +22,13 @@ protected function execute(callable $cb) { asyncCall($cb); }); } + + /** + * @dataProvider readlinkPathProvider + * + * @param \Closure $linkResolver + */ + public function testReadlinkError(\Closure $linkResolver) { + $this->markTestSkipped('UvDriver Test Skipped: Causes Crash'); + } } From 120962cd3488c321efe085b64870cbbe674a14c1 Mon Sep 17 00:00:00 2001 From: Andrew Mackrodt Date: Fri, 27 Jul 2018 17:01:30 +0100 Subject: [PATCH 2/2] Return after failing deferred --- lib/UvDriver.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/UvDriver.php b/lib/UvDriver.php index 392fc51..42ddf95 100644 --- a/lib/UvDriver.php +++ b/lib/UvDriver.php @@ -315,6 +315,8 @@ public function readlink(string $path): Promise { \uv_fs_readlink($this->loop, $path, function ($fh, $target) use ($deferred) { if (!(bool) $fh) { $deferred->fail(new FilesystemException("Could not read symbolic link")); + + return; } $deferred->resolve($target);