mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-09-08 11:22:14 -04:00
Simplified sanitize_path() logic a little.
This commit is contained in:
1 parent
82c6be7edf
commit
2d41264e9e
1 file changed
+20
-35
@@ -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 */
|
||||||
|
|||||||
Reference in new issue
Block a user