Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15415727
D20205.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Referenced Files
None
Subscribers
None
D20205.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 21, 7:41 AM (1 d, 14 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7370118
Default Alt Text
D20205.diff (3 KB)
Attached To
Mode
D20205: Refine checks against "cwd" before "proc_open()"
Attached
Detach File
Event Timeline
Log In to Comment