I wrote: > I didn't much like the patch as-is; we should think a little harder > about fixing the logic properly.
Like, say, this. (Very poorly tested but I think it's right.) regards, tom lane *** src/port/path.c.orig Thu Aug 11 21:39:22 2005 --- src/port/path.c Thu Aug 11 22:46:05 2005 *************** *** 226,231 **** --- 226,232 ---- { char *p, *to_p; bool was_sep = false; + int pending_strips; #ifdef WIN32 /* *************** *** 277,296 **** /* * Remove any trailing uses of "." and process ".." ourselves */ for (;;) { int len = strlen(path); if (len > 2 && strcmp(path + len - 2, "/.") == 0) trim_directory(path); ! /* We can only deal with "/usr/local/..", not "/usr/local/../.." */ ! else if (len > 3 && strcmp(path + len - 3, "/..") == 0 && ! (len != 5 || strcmp(path, "../..") != 0) && ! (len < 6 || strcmp(path + len - 6, "/../..") != 0)) { trim_directory(path); ! trim_directory(path); /* remove directory above */ } else break; --- 278,302 ---- /* * Remove any trailing uses of "." and process ".." ourselves + * + * This is tricky because of the possibility of /foo/bar/baz/../.. */ + pending_strips = 0; for (;;) { int len = strlen(path); if (len > 2 && strcmp(path + len - 2, "/.") == 0) trim_directory(path); ! else if (len > 3 && strcmp(path + len - 3, "/..") == 0) { trim_directory(path); ! pending_strips++; /* must remove directory above */ ! } ! else if (pending_strips > 0) ! { ! trim_directory(path); ! pending_strips--; } else break; ---------------------------(end of broadcast)--------------------------- TIP 2: Don't 'kill -9' the postmaster