summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2006-01-19 01:43:10 +0000
committerWayne Davison <wayned@samba.org>2006-01-19 01:43:10 +0000
commit1902a7652f138e34519ed5b373d1532c91d3c5eb (patch)
tree236945431fb61122afe901fe75fb70844dd80dbe
parent6ab423a5b6486cd83487266952a5b36f4f34926c (diff)
downloadrsync-1902a7652f138e34519ed5b373d1532c91d3c5eb.tar.gz
When --relative is active, simply trim off trailing slashes and
dot dirs. Also, reject a ".." dir if it would be sent as part of the relative path.
-rw-r--r--flist.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/flist.c b/flist.c
index 389114c7..08ac3c92 100644
--- a/flist.c
+++ b/flist.c
@@ -1102,7 +1102,10 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
}
len = strlen(fbuf);
- if (!len || fbuf[len - 1] == '/') {
+ if (relative_paths) {
+ /* We clean up fbuf below. */
+ is_dot_dir = 0;
+ } else if (!len || fbuf[len - 1] == '/') {
if (len == 2 && fbuf[0] == '.') {
/* Turn "./" into just "." rather than "./." */
fbuf[1] = '\0';
@@ -1153,16 +1156,41 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
fn = p + 1;
} else
fn = fbuf;
- } else if ((p = strstr(fbuf, "/./")) != NULL) {
- *p = '\0';
- if (p == fbuf)
- dir = "/";
- else
- dir = fbuf;
- len -= p - fbuf + 3;
- fn = p + 3;
- } else
- fn = fbuf;
+ } else {
+ if ((p = strstr(fbuf, "/./")) != NULL) {
+ *p = '\0';
+ if (p == fbuf)
+ dir = "/";
+ else
+ dir = fbuf;
+ len -= p - fbuf + 3;
+ fn = p + 3;
+ } else
+ fn = fbuf;
+ /* Get rid of trailing "/" and "/.". */
+ while (len) {
+ if (fn[len - 1] == '/')
+ len--;
+ else if (len >= 2 && fn[len - 1] == '.'
+ && fn[len - 2] == '/') {
+ if (!(len -= 2) && !dir) {
+ len++;
+ break;
+ }
+ } else
+ break;
+ }
+ fn[len] = '\0';
+ /* Reject a ".." dir in the active part of the path. */
+ if ((p = strstr(fbuf, "..")) != NULL
+ && (p[2] == '/' || p[2] == '\0')
+ && (p == fbuf || p[-1] == '/')) {
+ rprintf(FERROR,
+ "using a \"..\" dir is invalid with --relative: %s\n",
+ fbuf);
+ exit_cleanup(RERR_SYNTAX);
+ }
+ }
if (!*fn) {
len = 1;