diff options
Diffstat (limited to 'src/port/path.c')
-rw-r--r-- | src/port/path.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/port/path.c b/src/port/path.c index 5b0056dfe58..e01c7b8c0e5 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -359,6 +359,39 @@ path_contains_parent_reference(const char *path) } /* + * Detect whether a path is only in or below the current working directory. + * An absolute path that matches the current working directory should + * return false (we only want relative to the cwd). We don't allow + * "/../" even if that would keep us under the cwd (it is too hard to + * track that). + */ +bool +path_is_relative_and_below_cwd(const char *path) +{ + if (!is_absolute_path(path)) + return false; + /* don't allow anything above the cwd */ + else if (path_contains_parent_reference(path)) + return false; +#ifdef WIN32 + /* + * On Win32, a drive letter _not_ followed by a slash, e.g. 'E:abc', is + * relative to the cwd on that drive, or the drive's root directory + * if that drive has no cwd. Because the path itself cannot tell us + * which is the case, we have to assume the worst, i.e. that it is not + * below the cwd. We could use GetFullPathName() to find the full path + * but that could change if the current directory for the drive changes + * underneath us, so we just disallow it. + */ + else if (isalpha((unsigned char) path[0]) && path[1] == ':' && + !IS_DIR_SEP(path[2])) + return false; +#endif + else + return true; +} + +/* * Detect whether path1 is a prefix of path2 (including equality). * * This is pretty trivial, but it seems better to export a function than |