Page MenuHomePhabricator

D13202.id32092.diff
No OneTemporary

D13202.id32092.diff

diff --git a/src/filesystem/Filesystem.php b/src/filesystem/Filesystem.php
--- a/src/filesystem/Filesystem.php
+++ b/src/filesystem/Filesystem.php
@@ -731,19 +731,24 @@
/**
- * Return all directories between a path and "/". Iterating over them walks
- * from the path to the root.
+ * Return all directories between a path and the specified root directory
+ * (defaulting to "/"). Iterating over them walks from the path to the root.
*
- * @param string Path, absolute or relative to PWD.
- * @return list List of parent paths, including the provided path.
+ * @param string Path, absolute or relative to PWD.
+ * @param string The root directory.
+ * @return list<string> List of parent paths, including the provided path.
* @task directory
*/
- public static function walkToRoot($path) {
+ public static function walkToRoot($path, $root = '/') {
$path = self::resolvePath($path);
+ $root = self::resolvePath($root);
if (is_link($path)) {
$path = realpath($path);
}
+ if (is_link($root)) {
+ $root = realpath($root);
+ }
$walk = array();
$parts = explode(DIRECTORY_SEPARATOR, $path);
@@ -752,17 +757,25 @@
unset($parts[$k]);
}
}
- do {
+
+ if (!self::isDescendant($path, $root)) {
+ return array();
+ }
+
+ while ($parts) {
if (phutil_is_windows()) {
- $walk[] = implode(DIRECTORY_SEPARATOR, $parts);
+ $next = implode(DIRECTORY_SEPARATOR, $parts);
} else {
- $walk[] = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts);
+ $next = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts);
}
- if (empty($parts)) {
+
+ $walk[] = $next;
+ if ($next == $root) {
break;
}
+
array_pop($parts);
- } while (true);
+ }
return $walk;
}
@@ -851,7 +864,6 @@
* @task path
*/
public static function isDescendant($path, $root) {
-
try {
self::assertExists($path);
self::assertExists($root);
diff --git a/src/filesystem/__tests__/FilesystemTestCase.php b/src/filesystem/__tests__/FilesystemTestCase.php
--- a/src/filesystem/__tests__/FilesystemTestCase.php
+++ b/src/filesystem/__tests__/FilesystemTestCase.php
@@ -73,4 +73,94 @@
$this->assertTrue($caught instanceof Exception);
}
+ public function testWalkToRoot() {
+ $test_cases = array(
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt/test',
+ dirname(__FILE__),
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt/test',
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ dirname(__FILE__).'/data/include_dir.txt',
+ dirname(__FILE__).'/data',
+ dirname(__FILE__),
+ ),
+ ),
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ dirname(__FILE__),
+ array(
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ dirname(__FILE__).'/data/include_dir.txt',
+ dirname(__FILE__).'/data',
+ dirname(__FILE__),
+ ),
+ ),
+
+ 'root and path are identical' => array(
+ dirname(__FILE__),
+ dirname(__FILE__),
+ array(
+ dirname(__FILE__),
+ ),
+ ),
+
+ 'root is not an ancestor of path' => array(
+ dirname(__FILE__),
+ dirname(__FILE__).'/data/include_dir.txt/subdir.txt',
+ array(),
+ ),
+ );
+
+ foreach ($test_cases as $test_case) {
+ list($path, $root, $expected) = $test_case;
+
+ $this->assertEqual(
+ $expected,
+ Filesystem::walkToRoot($path, $root));
+ }
+ }
+
+ public function testisDescendant() {
+ $test_cases = array(
+ array(
+ __FILE__,
+ dirname(__FILE__),
+ true,
+ ),
+ array(
+ dirname(__FILE__),
+ dirname(dirname(__FILE__)),
+ true,
+ ),
+ array(
+ dirname(__FILE__),
+ phutil_get_library_root_for_path(__FILE__),
+ true,
+ ),
+ array(
+ dirname(dirname(__FILE__)),
+ dirname(__FILE__),
+ false,
+ ),
+ array(
+ dirname(__FILE__).'/quack',
+ dirname(__FILE__),
+ false,
+ ),
+ );
+
+ foreach ($test_cases as $test_case) {
+ list($path, $root, $expected) = $test_case;
+
+ $this->assertEqual(
+ $expected,
+ Filesystem::isDescendant($path, $root),
+ sprintf(
+ 'Filesystem::isDescendant(%s, %s)',
+ phutil_var_export($path),
+ phutil_var_export($root)));
+ }
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Mon, May 20, 6:15 PM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6293859
Default Alt Text
D13202.id32092.diff (4 KB)

Event Timeline