From 7a5804c2e789ace81eb8949fb1930ce1d3dd093e Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 6 Jul 2021 16:44:53 -0600 Subject: [PATCH] Fix symlink directory problem from 2a64e79 and add a unit test to avoid that in the future --- api/src/Vfs/Base.php | 2 +- api/tests/Vfs/VfsTest.php | 99 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 api/tests/Vfs/VfsTest.php diff --git a/api/src/Vfs/Base.php b/api/src/Vfs/Base.php index 73191c236c..5765ee6bad 100644 --- a/api/src/Vfs/Base.php +++ b/api/src/Vfs/Base.php @@ -315,7 +315,7 @@ class Base { $old_url = $url; $_url = self::symlinkCache_resolve($url); - $url = @readlink($url) ?: ($_url != $parts['path'] ? + $url = @readlink($url) ?: (Vfs::parse_url($_url,PHP_URL_PATH) != $parts['path'] ? str_replace([$parts['path'],Vfs::parse_url($old_url,PHP_URL_SCHEME)],[$_url,Vfs::parse_url(Vfs::resolve_url($_url),PHP_URL_SCHEME)],$url) : null) ?:$url; $is_link = $old_url == $url; } diff --git a/api/tests/Vfs/VfsTest.php b/api/tests/Vfs/VfsTest.php new file mode 100644 index 0000000000..04cc6e29d8 --- /dev/null +++ b/api/tests/Vfs/VfsTest.php @@ -0,0 +1,99 @@ +files as $file) + { + if(Vfs::is_dir($file) && !Vfs::is_link($file)) + { + Vfs::rmdir($file); + } + else + { + Vfs::unlink($file); + } + } + } + + /** + * Test that if we create a symlink to a folder, we can actually access + * that folder and its contents through the symlink. + * + * @throws \EGroupware\Api\Exception\AssertionFailed + */ + public function testSymlinkFromFolder() + { + // Setup + $test_base_dir = Vfs::get_home_dir(); + $source_dir = $test_base_dir . "/link_test"; + $link_dir = $test_base_dir . "/link_target"; + + Vfs::mkdir($source_dir); + + // Add something into the directory + $test_file_name = '/test.txt'; + $this->files[] = $test_file = $source_dir.$test_file_name; + $contents = $this->getName() . "\nJust a test ;)\n"; + $this->assertNotFalse( + file_put_contents(Vfs::PREFIX . $test_file, $contents), + "Could not write file $test_file" + ); + + // Add into files list after test file, to make sure test file is removed + // first during cleanup. Order matters: link first, dir last + $this->files[] = $link_dir; + $this->files[] = $source_dir; + + // Create the link + $this->assertTrue( + Vfs::symlink($source_dir, $link_dir), + "Could not create symlink to test ('$link_dir')" + ); + + Vfs::clearstatcache(); + + // Test - is a link + $this->assertTrue(Vfs::is_link($link_dir), "Link directory was not a link"); + + // Test - directory is a directory + $this->assertTrue(Vfs::is_dir($link_dir), "Link directory was not a directory"); + + // Test - Folder is what we expect + $stat = Vfs::stat($link_dir); + $this->assertEquals(2,$stat['nlink'], "Link target is not a folder"); + $this->assertStringEndsWith($source_dir,$stat['url'], "Looks like link is wrong"); + + // Test - File is where we expect + $files = Vfs::find($link_dir,['type'=>'F']); + $this->assertEquals(1,Vfs::$find_total, "Unexpected file count"); + $this->assertEquals($link_dir.$test_file_name, $files[0], "File name mismatch"); + + + // Test - File is what we expect + Vfs::stat($files[0]); + $this->assertEquals($contents, file_get_contents(Vfs::PREFIX . $files[0]), "File contents are wrong"); + } +}