summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2008-03-22 12:30:43 -0700
committerWayne Davison <wayned@samba.org>2008-03-22 12:30:43 -0700
commit4c74d44dabd887a5b865e95e8fca697f9084b40f (patch)
tree97ffa92517d40a9a56e666f0de73d520ed0c8ac6
parent4a86fbcda0f4514d13a1a93fa553d47ce139299e (diff)
downloadrsync-4c74d44dabd887a5b865e95e8fca697f9084b40f.tar.gz
rsync-4c74d44dabd887a5b865e95e8fca697f9084b40f.tar.bz2
rsync-4c74d44dabd887a5b865e95e8fca697f9084b40f.zip
A couple fixes in add_rule() for XFLG_ABS_IF_SLASH:
- Remove the trailing slash earlier, so that it doesn't affect the XFLG_ABS_IF_SLASH check. - Count the slashes earlier so that the XFLG_ABS_IF_SLASH can use it instead of using a strchr() all that could scan past the end of the input.
-rw-r--r--exclude.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/exclude.c b/exclude.c
index e796b2f5..4c7a8474 100644
--- a/exclude.c
+++ b/exclude.c
@@ -119,7 +119,7 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
{
struct filter_struct *ret;
const char *cp;
- unsigned int pre_len;
+ unsigned int pre_len, slash_cnt = 0;
if (verbose > 2) {
rprintf(FINFO, "[%s] add_rule(%s%.*s%s)%s\n",
@@ -145,9 +145,19 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
if (!(ret = new0(struct filter_struct)))
out_of_memory("add_rule");
+ if (pat_len > 1 && pat[pat_len-1] == '/') {
+ pat_len--;
+ mflags |= MATCHFLG_DIRECTORY;
+ }
+
+ for (cp = pat; cp < pat + pat_len; cp++) {
+ if (*cp == '/')
+ slash_cnt++;
+ }
+
if (!(mflags & (MATCHFLG_ABS_PATH | MATCHFLG_MERGE_FILE))
&& ((xflags & (XFLG_ANCHORED2ABS|XFLG_ABS_IF_SLASH) && *pat == '/')
- || (xflags & XFLG_ABS_IF_SLASH && strchr(pat, '/') != NULL))) {
+ || (xflags & XFLG_ABS_IF_SLASH && slash_cnt))) {
mflags |= MATCHFLG_ABS_PATH;
if (*pat == '/')
pre_len = dirbuf_len - module_dirlen - 1;
@@ -155,10 +165,16 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
pre_len = 0;
} else
pre_len = 0;
+
if (!(ret->pattern = new_array(char, pre_len + pat_len + 1)))
out_of_memory("add_rule");
- if (pre_len)
+ if (pre_len) {
memcpy(ret->pattern, dirbuf + module_dirlen, pre_len);
+ for (cp = ret->pattern; cp < ret->pattern + pre_len; cp++) {
+ if (*cp == '/')
+ slash_cnt++;
+ }
+ }
strlcpy(ret->pattern + pre_len, pat, pat_len + 1);
pat_len += pre_len;
@@ -178,11 +194,6 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
}
}
- if (pat_len > 1 && ret->pattern[pat_len-1] == '/') {
- ret->pattern[pat_len-1] = 0;
- mflags |= MATCHFLG_DIRECTORY;
- }
-
if (mflags & MATCHFLG_PERDIR_MERGE) {
struct filter_list_struct *lp;
unsigned int len;
@@ -226,10 +237,8 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
out_of_memory("add_rule");
}
mergelist_parents[mergelist_cnt++] = ret;
- } else {
- for (cp = ret->pattern; (cp = strchr(cp, '/')) != NULL; cp++)
- ret->u.slash_cnt++;
- }
+ } else
+ ret->u.slash_cnt = slash_cnt;
ret->match_flags = mflags;