diff --git a/io.c b/io.c index a99ac0e..bb60eec 100644 --- a/io.c +++ b/io.c @@ -55,6 +55,7 @@ extern int read_batch; extern int compat_flags; extern int protect_args; extern int checksum_seed; +extern int xfer_sum_len; extern int daemon_connection; extern int protocol_version; extern int remove_source_files; @@ -1977,7 +1978,7 @@ void read_sum_head(int f, struct sum_struct *sum) exit_cleanup(RERR_PROTOCOL); } sum->s2length = protocol_version < 27 ? csum_length : (int)read_int(f); - if (sum->s2length < 0 || sum->s2length > MAX_DIGEST_LEN) { + if (sum->s2length < 0 || sum->s2length > xfer_sum_len) { rprintf(FERROR, "Invalid checksum length %d [%s]\n", sum->s2length, who_am_i()); exit_cleanup(RERR_PROTOCOL); diff --git a/match.c b/match.c index cdb30a1..36e78ed 100644 --- a/match.c +++ b/match.c @@ -232,7 +232,7 @@ static void hash_search(int f,struct sum_struct *s, done_csum2 = 1; } - if (memcmp(sum2,s->sums[i].sum2,s->s2length) != 0) { + if (memcmp(sum2, sum2_at(s, i), s->s2length) != 0) { false_alarms++; continue; } @@ -252,7 +252,7 @@ static void hash_search(int f,struct sum_struct *s, if (i != aligned_i) { if (sum != s->sums[aligned_i].sum1 || l != s->sums[aligned_i].len - || memcmp(sum2, s->sums[aligned_i].sum2, s->s2length) != 0) + || memcmp(sum2, sum2_at(s, aligned_i), s->s2length) != 0) goto check_want_i; i = aligned_i; } @@ -271,7 +271,7 @@ static void hash_search(int f,struct sum_struct *s, if (sum != s->sums[i].sum1) goto check_want_i; get_checksum2((char *)map, l, sum2); - if (memcmp(sum2, s->sums[i].sum2, s->s2length) != 0) + if (memcmp(sum2, sum2_at(s, i), s->s2length) != 0) goto check_want_i; /* OK, we have a re-alignment match. Bump the offset * forward to the new match point. */ @@ -290,7 +290,7 @@ static void hash_search(int f,struct sum_struct *s, && (!updating_basis_file || s->sums[want_i].offset >= offset || s->sums[want_i].flags & SUMFLG_SAME_OFFSET) && sum == s->sums[want_i].sum1 - && memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) { + && memcmp(sum2, sum2_at(s, want_i), s->s2length) == 0) { /* we've found an adjacent match - the RLL coder * will be happy */ i = want_i; diff --git a/rsync.c b/rsync.c index cd288f5..b130aba 100644 --- a/rsync.c +++ b/rsync.c @@ -437,7 +437,10 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr, cha */ void free_sums(struct sum_struct *s) { - if (s->sums) free(s->sums); + if (s->sums) { + free(s->sums); + free(s->sum2_array); + } free(s); } diff --git a/rsync.h b/rsync.h index d3709fe..0f9e277 100644 --- a/rsync.h +++ b/rsync.h @@ -958,12 +958,12 @@ struct sum_buf { uint32 sum1; /**< simple checksum */ int32 chain; /**< next hash-table collision */ short flags; /**< flag bits */ - char sum2[SUM_LENGTH]; /**< checksum */ }; struct sum_struct { OFF_T flength; /**< total file length */ struct sum_buf *sums; /**< points to info for each chunk */ + char *sum2_array; /**< checksums of length xfer_sum_len */ int32 count; /**< how many chunks */ int32 blength; /**< block_length */ int32 remainder; /**< flength % block_length */ @@ -982,6 +982,8 @@ struct map_struct { int status; /* first errno from read errors */ }; +#define sum2_at(s, i) ((s)->sum2_array + ((size_t)(i) * xfer_sum_len)) + #define NAME_IS_FILE (0) /* filter name as a file */ #define NAME_IS_DIR (1<<0) /* filter name as a dir */ #define NAME_IS_XATTR (1<<2) /* filter name as an xattr */ diff --git a/sender.c b/sender.c index 3d4f052..2bbff2f 100644 --- a/sender.c +++ b/sender.c @@ -31,6 +31,7 @@ extern int log_before_transfer; extern int stdout_format_has_i; extern int logfile_format_has_i; extern int want_xattr_optim; +extern int xfer_sum_len; extern int csum_length; extern int append_mode; extern int copy_links; @@ -94,10 +95,11 @@ static struct sum_struct *receive_sums(int f) return(s); s->sums = new_array(struct sum_buf, s->count); + s->sum2_array = new_array(char, (size_t)s->count * xfer_sum_len); for (i = 0; i < s->count; i++) { s->sums[i].sum1 = read_int(f); - read_buf(f, s->sums[i].sum2, s->s2length); + read_buf(f, sum2_at(s, i), s->s2length); s->sums[i].offset = offset; s->sums[i].flags = 0;