diff options
Diffstat (limited to 'src/port/path.c')
-rw-r--r-- | src/port/path.c | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/src/port/path.c b/src/port/path.c index 2095db40165..ee8475fccda 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -8,12 +8,16 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/path.c,v 1.54 2005/08/12 03:07:45 momjian Exp $ + * $PostgreSQL: pgsql/src/port/path.c,v 1.55 2005/08/12 19:42:45 momjian Exp $ * *------------------------------------------------------------------------- */ -#include "c.h" +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif #include <ctype.h> #include <sys/stat.h> @@ -226,6 +230,7 @@ canonicalize_path(char *path) { char *p, *to_p; bool was_sep = false; + int pending_strips = 0; #ifdef WIN32 /* @@ -284,19 +289,38 @@ canonicalize_path(char *path) if (len > 2 && strcmp(path + len - 2, "/.") == 0) trim_directory(path); - /* - * Process only a single trailing "..", and only if ".." does - * not preceed it. - * So, we only deal with "/usr/local/..", not with "/usr/local/../..". - * We don't handle the even more complex cases, like - * "usr/local/../../..". - */ - else if (len > 3 && strcmp(path + len - 3, "/..") == 0 && - (len != 5 || strcmp(path, "../..") != 0) && - (len < 6 || strcmp(path + len - 6, "/../..") != 0)) + else if (len > 3 && strcmp(path + len - 3, "/..") == 0) { trim_directory(path); - trim_directory(path); /* remove directory above */ + pending_strips++; + } + else if (pending_strips > 0) + { + /* If path is not "", we can keep trimming. Even if path is + * "/", we can keep trimming because trim_directory never removes + * the leading separator, and the parent directory of "/" is "/". + */ + if (*path != '\0') + { + trim_directory(path); + pending_strips--; + } + else + { + /* + * If we still have pending_strips, it means the supplied path + * was exhausted and we still have more directories to move up. + * This means that the resulting path is only parents, like + * ".." or "../..". If so, callers can not handle trailing "..", + * so we exit. + */ +#ifndef FRONTEND + elog(ERROR, "relative paths (\"..\") not supported"); +#else + fprintf(stderr, _("relative paths (\"..\") not supported\n")); + exit(1); +#endif + } } else break; @@ -305,8 +329,10 @@ canonicalize_path(char *path) /* - * Extracts the actual name of the program as called - - * stripped of .exe suffix if any + * Extracts the actual name of the program as called - + * stripped of .exe suffix if any. + * The server calling this must check for NULL return + * and report the error. */ const char * get_progname(const char *argv0) @@ -329,8 +355,16 @@ get_progname(const char *argv0) progname = strdup(nodir_name); if (progname == NULL) { +#ifndef FRONTEND + /* + * No elog() support in postmaster at this stage, + * so return NULL and print error at the call. + */ + return NULL; +#else fprintf(stderr, "%s: out of memory\n", nodir_name); - exit(1); /* This could exit the postmaster */ + exit(1); +#endif } progname[strlen(progname) - (sizeof(EXE) - 1)] = '\0'; nodir_name = progname; |