Fix normabspath() to handle consecutive '..'s properly
The approach with lastp only works if we only go back one dir at a time. Of course, this cannot be assumed, so we traverse the path backwards looking for the previous /.
This commit is contained in:
parent
58450ffced
commit
bd2e9e66ff
1 changed files with 22 additions and 10 deletions
32
quark.c
32
quark.c
|
@ -460,8 +460,8 @@ static int
|
|||
normabspath(char *path)
|
||||
{
|
||||
size_t len;
|
||||
int done = 0;
|
||||
char *p, *q, *lastp;
|
||||
int last = 0;
|
||||
char *p, *q;
|
||||
|
||||
/* require and skip first slash */
|
||||
if (path[0] != '/') {
|
||||
|
@ -472,25 +472,37 @@ normabspath(char *path)
|
|||
/* get length of path */
|
||||
len = strlen(p);
|
||||
|
||||
for (lastp = p; !done; ) {
|
||||
for (; !last; ) {
|
||||
/* bound path component within (p,q) */
|
||||
if (!(q = strchr(p, '/'))) {
|
||||
q = strchr(p, '\0');
|
||||
done = 1;
|
||||
last = 1;
|
||||
}
|
||||
|
||||
if (p == q || (q - p == 1 && p[0] == '.')) {
|
||||
/* "/" or "./" */
|
||||
memcpy(p, q + 1, len - ((q + 1) - path) + 2);
|
||||
len -= (q + 1) - p;
|
||||
goto squash;
|
||||
} else if (q - p == 2 && p[0] == '.' && p[1] == '.') {
|
||||
/* "../" */
|
||||
memcpy(lastp, q + 1, len - ((q + 1) - path) + 2);
|
||||
len -= (q + 1) - lastp;
|
||||
p = lastp;
|
||||
if (p != path + 1) {
|
||||
/* place p right after the previous / */
|
||||
for (p -= 2; p > path && *p != '/'; p--);
|
||||
p++;
|
||||
}
|
||||
goto squash;
|
||||
} else {
|
||||
lastp = p;
|
||||
/* move on */
|
||||
p = q + 1;
|
||||
continue;
|
||||
}
|
||||
squash:
|
||||
/* squash (p,q) into void */
|
||||
if (last) {
|
||||
*p = '\0';
|
||||
len = p - path;
|
||||
} else {
|
||||
memcpy(p, q + 1, len - ((q + 1) - path) + 2);
|
||||
len -= (q + 1) - p;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue