From: Wayne Davison Date: Tue, 16 Aug 2022 01:54:07 +0000 (-0700) Subject: Do more path cleaning in add_implied_include(); make u.slash_cnt more accurate. X-Git-Tag: v3.2.6~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=024bf1d83114d986b1644628f2bc907ccf4e0ef2;p=thirdparty%2Frsync.git Do more path cleaning in add_implied_include(); make u.slash_cnt more accurate. --- diff --git a/exclude.c b/exclude.c index adc82e2a..296d69df 100644 --- a/exclude.c +++ b/exclude.c @@ -371,9 +371,8 @@ void free_implied_include_partial_string() * that the receiver uses to validate the file list from the sender. */ void add_implied_include(const char *arg, int skip_daemon_module) { - filter_rule *rule; int arg_len, saw_wild = 0, saw_live_open_brkt = 0, backslash_cnt = 0; - int slash_cnt = 1; /* We know we're adding a leading slash. */ + int slash_cnt = 0; /* We know we're adding a leading slash. */ const char *cp; char *p; if (trust_sender_args) @@ -404,6 +403,7 @@ void add_implied_include(const char *arg, int skip_daemon_module) arg++; arg_len = strlen(arg); if (arg_len) { + char *new_pat; if (strpbrk(arg, "*[?")) { /* We need to add room to escape backslashes if wildcard chars are present. */ for (cp = arg; (cp = strchr(cp, '\\')) != NULL; cp++) @@ -411,16 +411,9 @@ void add_implied_include(const char *arg, int skip_daemon_module) saw_wild = 1; } arg_len++; /* Leave room for the prefixed slash */ - rule = new0(filter_rule); - if (!implied_filter_list.head) - implied_filter_list.head = implied_filter_list.tail = rule; - else { - rule->next = implied_filter_list.head; - implied_filter_list.head = rule; - } - rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0); - p = rule->pattern = new_array(char, arg_len + 1); + p = new_pat = new_array(char, arg_len + 1); *p++ = '/'; + slash_cnt++; for (cp = arg; *cp; ) { switch (*cp) { case '\\': @@ -436,15 +429,70 @@ void add_implied_include(const char *arg, int skip_daemon_module) break; case '/': if (p[-1] == '/') { /* This is safe because of the initial slash. */ + if (*++cp == '\0') { + slash_cnt--; + p--; + } + } else if (cp[1] == '\0') { cp++; - break; + } else { + slash_cnt++; + *p++ = *cp++; } - if (relative_paths) { - filter_rule const *ent; - int found = 0; + break; + case '.': + if (p[-1] == '/') { + if (cp[1] == '/') { + cp += 2; + if (!*cp) { + slash_cnt--; + p--; + } + } else if (cp[1] == '\0') { + cp++; + slash_cnt--; + p--; + break; + } + } else + *p++ = *cp++; + break; + case '[': + saw_live_open_brkt = 1; + *p++ = *cp++; + break; + default: + *p++ = *cp++; + break; + } + } + *p = '\0'; + arg_len = p - new_pat; + if (!arg_len) + free(new_pat); + else { + filter_rule *rule = new0(filter_rule); + rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0); + rule->u.slash_cnt = slash_cnt; + arg = rule->pattern = new_pat; + if (!implied_filter_list.head) + implied_filter_list.head = implied_filter_list.tail = rule; + else { + rule->next = implied_filter_list.head; + implied_filter_list.head = rule; + } + if (DEBUG_GTE(FILTER, 3)) + rprintf(FINFO, "[%s] add_IMPlied_include(%s)\n", who_am_i(), arg); + if (saw_live_open_brkt) + maybe_add_literal_brackets_rule(rule, arg_len); + if (relative_paths && slash_cnt) { + filter_rule const *ent; + int found = 0; + slash_cnt = 1; + for (p = new_pat + 1; (p = strchr(p, '/')) != NULL; p++) { *p = '\0'; for (ent = implied_filter_list.head; ent; ent = ent->next) { - if (ent != rule && strcmp(ent->pattern, rule->pattern) == 0) { + if (ent != rule && strcmp(ent->pattern, new_pat) == 0) { found = 1; break; } @@ -455,7 +503,7 @@ void add_implied_include(const char *arg, int skip_daemon_module) /* Check if our sub-path has wildcards or escaped backslashes */ if (saw_wild && strpbrk(rule->pattern, "*[?\\")) R_rule->rflags |= FILTRULE_WILD; - R_rule->pattern = strdup(rule->pattern); + R_rule->pattern = strdup(new_pat); R_rule->u.slash_cnt = slash_cnt; R_rule->next = implied_filter_list.head; implied_filter_list.head = R_rule; @@ -466,32 +514,16 @@ void add_implied_include(const char *arg, int skip_daemon_module) if (saw_live_open_brkt) maybe_add_literal_brackets_rule(R_rule, -1); } + *p = '/'; + slash_cnt++; } - slash_cnt++; - *p++ = *cp++; - break; - case '[': - saw_live_open_brkt = 1; - *p++ = *cp++; - break; - default: - *p++ = *cp++; - break; } } - *p = '\0'; - rule->u.slash_cnt = slash_cnt; - arg = rule->pattern; - arg_len = p - arg; /* We recompute it due to backslash weirdness. */ - if (DEBUG_GTE(FILTER, 3)) - rprintf(FINFO, "[%s] add_implied_include(%s)\n", who_am_i(), rule->pattern); - if (saw_live_open_brkt) - maybe_add_literal_brackets_rule(rule, arg_len); } if (recurse || xfer_dirs) { /* Now create a rule with an added "/" & "**" or "*" at the end */ - rule = new0(filter_rule); + filter_rule *rule = new0(filter_rule); rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD; if (recurse) rule->rflags |= FILTRULE_WILD2; @@ -499,7 +531,7 @@ void add_implied_include(const char *arg, int skip_daemon_module) if (!saw_wild && backslash_cnt) { /* We are appending a wildcard, so now the backslashes need to be escaped. */ p = rule->pattern = new_array(char, arg_len + backslash_cnt + 3 + 1); - for (cp = arg; *cp; ) { + for (cp = arg; *cp; ) { /* Note that arg_len != 0 because backslash_cnt > 0 */ if (*cp == '\\') *p++ = '\\'; *p++ = *cp++; @@ -511,13 +543,15 @@ void add_implied_include(const char *arg, int skip_daemon_module) p += arg_len; } } - if (p[-1] != '/') + if (p[-1] != '/') { *p++ = '/'; + slash_cnt++; + } *p++ = '*'; if (recurse) *p++ = '*'; *p = '\0'; - rule->u.slash_cnt = slash_cnt + 1; + rule->u.slash_cnt = slash_cnt; rule->next = implied_filter_list.head; implied_filter_list.head = rule; if (DEBUG_GTE(FILTER, 3))