Re: Bug in canonicalize_path() - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: Bug in canonicalize_path()
Date
Msg-id 200508120451.j7C4pDm02199@candle.pha.pa.us
Whole thread Raw
In response to Re: Bug in canonicalize_path()  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Bug in canonicalize_path()
List pgsql-patches
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I figured it would be best to leave it alone if we can't process it, but
> > if you think it is more imporant to trim in cases like ../.., go ahead.
>
> My recollection of this patch:
>
> 2004-08-09 16:20  tgl
>
>     * src/: port/exec.c, port/path.c, bin/initdb/initdb.c:
>     Path-mangling logic was failing to account for paths containing
>     mentions of '.' or '..'.  Extend canonicalize_path() to trim off
>     trailing occurrences of these things, and use it to fix up paths
>     where needed (which I think is only after places where we trim the
>     last path component, but maybe some others will turn up).  Fixes
>     Josh's complaint that './initdb' does not work.
>
> is that it's part of the API contract of canonicalize_path() that it
> will not return something with trailing "." or "..".  It's not just
> neatnik-ism to strip those, it's necessary to allow higher-level
> path-mangling routines to reason about how to do what they need.
> The entire concept of "trim the last directory" fails if you have
> to account for "." or "..".

OK, new patch which I think handles all cases.

--
  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
Index: src/port/path.c
===================================================================
RCS file: /cvsroot/pgsql/src/port/path.c,v
retrieving revision 1.54
diff -c -c -r1.54 path.c
*** src/port/path.c    12 Aug 2005 03:07:45 -0000    1.54
--- src/port/path.c    12 Aug 2005 04:47:59 -0000
***************
*** 226,231 ****
--- 226,232 ----
  {
      char       *p, *to_p;
      bool        was_sep = false;
+     int            pending_strips = 0;

  #ifdef WIN32
      /*
***************
*** 284,306 ****

          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))
          {
              trim_directory(path);
!             trim_directory(path);    /* remove directory above */
          }
          else
              break;
      }
  }


--- 285,311 ----

          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++;
!         }
!         /* for absolute paths, we just keep trimming */
!         else if (*path != '\0' && pending_strips > 0)
!         {
!             trim_directory(path);
!             pending_strips--;
          }
          else
              break;
      }
+
+     if (pending_strips > 0)
+     {
+         for (; pending_strips > 0; pending_strips--)
+             strcat(path, "../");
+         trim_trailing_separator(path);
+     }
  }



pgsql-patches by date:

Previous
From: Tom Lane
Date:
Subject: Re: Bug in canonicalize_path()
Next
From: Tom Lane
Date:
Subject: Re: remove BufferBlockPointers for speed and space