Page MenuHomePhabricator

D20205.id48258.diff
No OneTemporary

D20205.id48258.diff

diff --git a/src/filesystem/Filesystem.php b/src/filesystem/Filesystem.php
--- a/src/filesystem/Filesystem.php
+++ b/src/filesystem/Filesystem.php
@@ -1118,11 +1118,46 @@
* @task assert
*/
public static function assertExists($path) {
- if (!self::pathExists($path)) {
- throw new FilesystemException(
- $path,
- pht("File system entity '%s' does not exist.", $path));
+ if (self::pathExists($path)) {
+ return;
+ }
+
+ // Before we claim that the path doesn't exist, try to find a parent we
+ // don't have "+x" on. If we find one, tailor the error message so we don't
+ // say "does not exist" in cases where the path does exist, we just don't
+ // have permission to test its existence.
+ foreach (self::walkToRoot($path) as $parent) {
+ if (!self::pathExists($parent)) {
+ continue;
+ }
+
+ if (!is_dir($parent)) {
+ continue;
+ }
+
+ if (phutil_is_windows()) {
+ // Do nothing. On Windows, there's no obvious equivalent to the
+ // check below because "is_executable(...)" always appears to return
+ // "false" for any directory.
+ } else if (!is_executable($parent)) {
+ // On Linux, note that we don't need read permission ("+r") on parent
+ // directories to determine that a path exists, only execute ("+x").
+ throw new FilesystemException(
+ $path,
+ pht(
+ 'Filesystem path "%s" can not be accessed because a parent '.
+ 'directory ("%s") is not executable (the current process does '.
+ 'not have "+x" permission).',
+ $path,
+ $parent));
+ }
}
+
+ throw new FilesystemException(
+ $path,
+ pht(
+ 'Filesystem path "%s" does not exist.',
+ $path));
}
diff --git a/src/future/exec/PhutilExecutableFuture.php b/src/future/exec/PhutilExecutableFuture.php
--- a/src/future/exec/PhutilExecutableFuture.php
+++ b/src/future/exec/PhutilExecutableFuture.php
@@ -126,13 +126,51 @@
* @task config
*/
final public function setCWD($cwd) {
- $cwd = (string)$cwd;
+ $cwd = phutil_string_cast($cwd);
+
+ try {
+ Filesystem::assertExists($cwd);
+ } catch (FilesystemException $ex) {
+ throw new PhutilProxyException(
+ pht(
+ 'Unable to run a command in directory "%s".',
+ $cwd),
+ $ex);
+ }
if (!is_dir($cwd)) {
throw new Exception(
pht(
- 'Preparing to run a command in directory "%s", but that '.
- 'directory does not exist.',
+ 'Preparing to run a command in directory "%s", but that path is '.
+ 'not a directory.',
+ $cwd));
+ }
+
+ // Although you don't technically need read permission to "chdir()" into
+ // a directory, it is almost certainly a mistake to execute a subprocess
+ // in a CWD we can't read. Refuse to do this. If callers have some
+ // exceptionally clever scheme up their sleeves they can always have the
+ // subprocess "cd" or "chdir()" explicitly.
+
+ if (!is_readable($cwd)) {
+ throw new Exception(
+ pht(
+ 'Preparing to run a command in directory "%s", but that directory '.
+ 'is not readable (the current process does not have "+r" '.
+ 'permission).',
+ $cwd));
+ }
+
+
+ if (phutil_is_windows()) {
+ // Do nothing. On Windows, calling "is_executable(...)" on a directory
+ // always appears to return "false". Skip this check under Windows.
+ } else if (!is_executable($cwd)) {
+ throw new Exception(
+ pht(
+ 'Preparing to run a command in directory "%s", but that directory '.
+ 'is not executable (the current process does not have "+x" '.
+ 'permission).',
$cwd));
}

File Metadata

Mime Type
text/plain
Expires
Sat, May 11, 8:01 PM (3 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6275183
Default Alt Text
D20205.id48258.diff (3 KB)

Event Timeline