diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 43a05659a26e9646d1f2f79a888c9e7df626300d..cbbf9ca1c37b0ffc583c3f553a596c46745baf82 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -9,7 +9,7 @@ * Author: Andreas Pflug * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/genfile.c,v 1.5 2005/08/15 23:00:14 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/genfile.c,v 1.6 2005/08/29 19:39:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,7 +41,7 @@ typedef struct * Validate a path and convert to absolute form. * * Argument may be absolute or relative to the DataDir (but we only allow - * absolute paths that match Log_directory). + * absolute paths that match DataDir or Log_directory). */ static char * check_and_make_absolute(text *arg) @@ -62,11 +62,12 @@ check_and_make_absolute(text *arg) if (is_absolute_path(filename)) { + /* Allow absolute references within DataDir */ + if (path_is_prefix_of_path(DataDir, filename)) + return filename; /* The log directory might be outside our datadir, but allow it */ - if (is_absolute_path(Log_directory) && - strncmp(filename, Log_directory, strlen(Log_directory)) == 0 && - (filename[strlen(Log_directory)] == '/' || - filename[strlen(Log_directory)] == '\0')) + if (is_absolute_path(Log_directory) && + path_is_prefix_of_path(Log_directory, filename)) return filename; ereport(ERROR, diff --git a/src/include/port.h b/src/include/port.h index ce261d9f050a357f15758cd1d81a0c4d147f11b3..7172ce5fb53f88054fb7fcdd4cc4660baa76ce38 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/port.h,v 1.81 2005/08/12 21:07:52 tgl Exp $ + * $PostgreSQL: pgsql/src/include/port.h,v 1.82 2005/08/29 19:39:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,6 +33,7 @@ extern void join_path_components(char *ret_path, extern void canonicalize_path(char *path); extern void make_native_path(char *path); extern bool path_contains_parent_reference(const char *path); +extern bool path_is_prefix_of_path(const char *path1, const char *path2); extern const char *get_progname(const char *argv0); extern void get_share_path(const char *my_exec_path, char *ret_path); extern void get_etc_path(const char *my_exec_path, char *ret_path); diff --git a/src/port/path.c b/src/port/path.c index 7e37bede7eaaeaebed51f3ea7f666c1997d354d2..41a505759e9a56b2aaab7246a27bdbe8e2225064 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/path.c,v 1.57 2005/08/12 21:07:53 tgl Exp $ + * $PostgreSQL: pgsql/src/port/path.c,v 1.58 2005/08/29 19:39:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -364,6 +364,22 @@ path_contains_parent_reference(const char *path) return false; } +/* + * Detect whether path1 is a prefix of path2 (including equality). + * + * This is pretty trivial, but it seems better to export a function than + * to export IS_DIR_SEP. + */ +bool +path_is_prefix_of_path(const char *path1, const char *path2) +{ + int path1_len = strlen(path1); + + if (strncmp(path1, path2, path1_len) == 0 && + (IS_DIR_SEP(path2[path1_len]) || path2[path1_len] == '\0')) + return true; + return false; +} /* * Extracts the actual name of the program as called -