X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/b41c3f92738709adf79a1d77f8e7e75752bd1adf..375a4556c7a1ffb9a4e7117f33fc42ed2bc4c026:/util.c diff --git a/util.c b/util.c index 6e0fbaba..3c23cb7a 100644 --- a/util.c +++ b/util.c @@ -752,3 +752,50 @@ int unsafe_symlink(char *dest, char *src) free(dest); return (depth < 0); } + +/* + * Make path appear as if a chroot had occurred: + * 1. remove leading "/" (or replace with "." if at end) + * 2. remove leading ".." components + * 3. delete any other "/.." (recursively) + * Return a malloc'ed copy. + * Contributed by Dave Dykstra + */ + +char *sanitize_path(char *p) +{ + char *copy, *copyp; + + copy = (char *) malloc(strlen(p)+1); + copyp = copy; + while (*p != '\0') { + if ((*p == '/') && (copyp == copy)) { + /* remove leading slash */ + p++; + } + else if ((*p == '.') && (*(p+1) == '.') && + ((*(p+2) == '/') || (*(p+2) == '\0'))) { + /* remove .. followed by slash or end */ + p += 2; + if (copyp != copy) { + /* backup the copy one level */ + while ((--copyp != copy) && (*copyp == '/')) + /* skip trailing slashes */ + ; + while ((copyp != copy) && (*copyp != '/')) + /* skip back through slash */ + copyp--; + } + } else { + /* copy one component */ + while (1) { + *copyp++ = *p++; + if ((*p == '\0') || (*(p-1) == '/')) + break; + } + } + } + *copyp = '\0'; + return(copy); +} +