aboutsummaryrefslogtreecommitdiff
path: root/src/port/path.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-01-31 13:53:38 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2022-01-31 13:53:38 -0500
commitb426bd48ee3f5a6890038421f81df7ed919d73dc (patch)
tree4dd6902ccd50a53d3e7555e7ce5d3924146106b0 /src/port/path.c
parentc10f830c511f0ba3e6f4c9d99f444d39e30440c8 (diff)
downloadpostgresql-b426bd48ee3f5a6890038421f81df7ed919d73dc.tar.gz
postgresql-b426bd48ee3f5a6890038421f81df7ed919d73dc.zip
Simplify coding around path_contains_parent_reference().
Given the existing stipulation that path_contains_parent_reference() must only be invoked on canonicalized paths, we can simplify things in the wake of commit c10f830c5. It is now only possible to see ".." at the start of a relative path. That means we can simplify path_contains_parent_reference() itself quite a bit, and it makes the two existing outside call sites dead code, since they'd already checked that the path is absolute. We could now fold path_contains_parent_reference() into its only remaining caller path_is_relative_and_below_cwd(). But it seems better to leave it as a separately callable function, in case any extensions are using it. Also document the pre-existing requirement for path_is_relative_and_below_cwd's input to be likewise canonicalized. Shenhao Wang and Tom Lane Discussion: https://postgr.es/m/OSBPR01MB4214FA221FFE046F11F2AD74F2D49@OSBPR01MB4214.jpnprd01.prod.outlook.com
Diffstat (limited to 'src/port/path.c')
-rw-r--r--src/port/path.c31
1 files changed, 13 insertions, 18 deletions
diff --git a/src/port/path.c b/src/port/path.c
index ea1d8f6ff58..05fe812f757 100644
--- a/src/port/path.c
+++ b/src/port/path.c
@@ -494,27 +494,21 @@ canonicalize_path(char *path)
* Detect whether a path contains any parent-directory references ("..")
*
* The input *must* have been put through canonicalize_path previously.
- *
- * This is a bit tricky because we mustn't be fooled by "..a.." (legal)
- * nor "C:.." (legal on Unix but not Windows).
*/
bool
path_contains_parent_reference(const char *path)
{
- int path_len;
-
- path = skip_drive(path); /* C: shouldn't affect our conclusion */
-
- path_len = strlen(path);
-
/*
- * ".." could be the whole path; otherwise, if it's present it must be at
- * the beginning, in the middle, or at the end.
+ * Once canonicalized, an absolute path cannot contain any ".." at all,
+ * while a relative path could contain ".."(s) only at the start. So it
+ * is sufficient to check the start of the path, after skipping any
+ * Windows drive/network specifier.
*/
- if (strcmp(path, "..") == 0 ||
- strncmp(path, "../", 3) == 0 ||
- strstr(path, "/../") != NULL ||
- (path_len >= 3 && strcmp(path + path_len - 3, "/..") == 0))
+ path = skip_drive(path); /* C: shouldn't affect our conclusion */
+
+ if (path[0] == '.' &&
+ path[1] == '.' &&
+ (path[2] == '\0' || path[2] == '/'))
return true;
return false;
@@ -522,10 +516,11 @@ path_contains_parent_reference(const char *path)
/*
* Detect whether a path is only in or below the current working directory.
+ *
+ * The input *must* have been put through canonicalize_path previously.
+ *
* 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).
+ * return false (we only want relative to the cwd).
*/
bool
path_is_relative_and_below_cwd(const char *path)