Re: Bug in canonicalize_path()
От | Tom Lane |
---|---|
Тема | Re: Bug in canonicalize_path() |
Дата | |
Msg-id | 23841.1123881289@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: Bug in canonicalize_path() (Bruce Momjian <pgman@candle.pha.pa.us>) |
Список | pgsql-patches |
Bruce Momjian <pgman@candle.pha.pa.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
В списке pgsql-patches по дате отправления: