I found that in port/path.c::canonicalize_path, that if the path was
supplied as "/usr/local/bin/../.." we would return /usr/local/bin. The
problem is then when we saw a trailing ".." we stripped it off and the
previous directory, but we never checked if the previous directory was
itself "..".
Patch applied to suppress trimming of ".." if ".." is above it. I tried
coding something that would handle "../.." but is started to look too
messy and not worth the effort.
I don't see a need to backpatch this, but it could produce errors with
weird supplied paths. Comments?
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
? pg_config_paths.h
Index: path.c
===================================================================
RCS file: /cvsroot/pgsql/src/port/path.c,v
retrieving revision 1.51
diff -c -r1.51 path.c
*** path.c 26 Jan 2005 19:24:03 -0000 1.51
--- path.c 11 Aug 2005 03:52:06 -0000
***************
*** 284,290 ****
if (len > 2 && strcmp(path + len - 2, "/.") == 0)
trim_directory(path);
! else if (len > 3 && strcmp(path + len - 3, "/..") == 0)
{
trim_directory(path);
trim_directory(path); /* remove directory above */
--- 284,293 ----
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 */