Simplified sanitize_path() logic a little.

This commit is contained in:
Wayne Davison committed 2004-08-12 09:32:16 +00:00
1 parent 82c6be7edf
commit 2d41264e9e
1 file changed
+20 -35
+20 -35
View File
@@ -740,7 +740,6 @@ unsigned int clean_fname(char *name)
char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth) char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
{ {
char *start, *sanp; char *start, *sanp;
int allowdotdot = 0;
int rlen = 0; int rlen = 0;
if (dest != p) { if (dest != p) {
@@ -765,59 +764,45 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
} }
start = sanp = dest + rlen; start = sanp = dest + rlen;
while (*p == '/') {
/* remove leading slashes */
p++;
}
while (*p != '\0') { while (*p != '\0') {
/* discard leading or extra slashes */
if (*p == '/') {
p++;
continue;
}
/* this loop iterates once per filename component in p. /* this loop iterates once per filename component in p.
* both p (and sanp if the original had a slash) should * both p (and sanp if the original had a slash) should
* always be left pointing after a slash * always be left pointing after a slash
*/ */
if (*p == '.' && (p[1] == '/' || p[1] == '\0')) { if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
/* skip "." component */ /* skip "." component */
while (*++p == '/') { p++;
/* skip following slashes */
;
}
continue; continue;
} }
allowdotdot = 0;
if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) { if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
/* ".." component followed by slash or end */ /* ".." component followed by slash or end */
if (depth > 0 && sanp == start) { if (depth > 0 && sanp == start) {
/* allow depth levels of .. at the beginning */ /* allow depth levels of .. at the beginning */
--depth; --depth;
allowdotdot = 1; *sanp++ = *p++;
} else { *sanp++ = *p++;
p += 2; /* move virtual beginning to leave .. alone */
while (*p == '/') p++; start = sanp;
if (sanp != start) {
/* back up sanp one level */
--sanp; /* now pointing at slash */
while (sanp > start && sanp[-1] != '/') {
/* skip back up to slash */
sanp--;
}
}
continue; continue;
} }
} p += 2;
while (1) { if (sanp != start) {
/* copy one component through next slash */ /* back up sanp one level */
*sanp++ = *p++; --sanp; /* now pointing at slash */
if (*p == '\0' || p[-1] == '/') { while (sanp > start && sanp[-1] != '/') {
while (*p == '/') { /* skip back up to slash */
/* skip multiple slashes */ sanp--;
p++;
} }
break;
} }
continue;
} }
if (allowdotdot) { /* copy one component through next slash */
/* move the virtual beginning to leave the .. alone */ while (*p && (*sanp++ = *p++) != '/') {}
start = sanp;
}
} }
if (sanp == dest) { if (sanp == dest) {
/* ended up with nothing, so put in "." component */ /* ended up with nothing, so put in "." component */