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

Reply via email to