From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> |
Cc: | William ZHANG <uniware(at)zedware(dot)org>, pgsql-patches(at)postgresql(dot)org |
Subject: | Re: Bug in canonicalize_path() |
Date: | 2005-08-12 21:14:49 |
Message-ID: | 23841.1123881289@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-patches |
Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> In my first attempt, I counted the number of ".." groups, then went up
> to remove each "..", and them remove a regular directory for each "..".
> And then you have this case:
> /usr/local/../bin/../..
> Here you hit the first ".." as you are going up. It just seemed like a
> lost cause.
BTW, you were right: this is a *lot* harder than it looks at first
glance. Here's what I ended up with:
/*
* Remove any trailing uses of "." and process ".." ourselves
*
* Note that "/../.." should reduce to just "/", while "../.." has to
* be kept as-is. In the latter case we put back mistakenly trimmed
* ".." components below. Also note that we want a Windows drive spec
* to be visible to trim_directory(), but it's not part of the logic
* that's looking at the name components; hence distinction between
* path and spath.
*/
spath = skip_drive(path);
pending_strips = 0;
for (;;)
{
int len = strlen(spath);
if (len >= 2 && strcmp(spath + len - 2, "/.") == 0)
trim_directory(path);
else if (strcmp(spath, ".") == 0)
{
/* Want to leave "." alone, but "./.." has to become ".." */
if (pending_strips > 0)
*spath = '\0';
break;
}
else if ((len >= 3 && strcmp(spath + len - 3, "/..") == 0) ||
strcmp(spath, "..") == 0)
{
trim_directory(path);
pending_strips++;
}
else if (pending_strips > 0 && *spath != '\0')
{
/* trim a regular directory name cancelled by ".." */
trim_directory(path);
pending_strips--;
/* foo/.. should become ".", not empty */
if (*spath == '\0')
strcpy(spath, ".");
}
else
break;
}
if (pending_strips > 0)
{
/*
* We could only get here if path is now totally empty (other than
* a possible drive specifier on Windows).
* We have to put back one or more ".."'s that we took off.
*/
while (--pending_strips > 0)
strcat(path, "../");
strcat(path, "..");
}
}
regards, tom lane
From | Date | Subject | |
---|---|---|---|
Next Message | Bruce Momjian | 2005-08-12 21:20:39 | Re: [HACKERS] Duplicate object names in GRANT |
Previous Message | Bruce Momjian | 2005-08-12 21:12:30 | Re: Bitmap index AM |