return 0;
}
+/* Returns 0 if the checksum is not canonical (i.e. it includes a seed value).
+ * Returns 1 if the public sum order matches our internal sum order.
+ * Returns -1 if the public sum order is the reverse of our internal sum order.
+ */
int canonical_checksum(int csum_type)
{
- return csum_type >= CSUM_MD4 ? 1 : 0;
+ switch (csum_type) {
+ case CSUM_NONE:
+ case CSUM_MD4_ARCHAIC:
+ case CSUM_MD4_OLD:
+ case CSUM_MD4_BUSTED:
+ break;
+ case CSUM_MD4:
+ case CSUM_MD5:
+ return -1;
+#ifdef SUPPORT_XXHASH
+ case CSUM_XXH64:
+ return 1;
+#endif
+ default: /* paranoia to prevent missing case values */
+ exit_cleanup(RERR_UNSUPPORTED);
+ }
+ return 0;
}
#ifndef HAVE_SIMD /* See simd-checksum-*.cpp. */
case 'C':
n = NULL;
if (S_ISREG(file->mode)) {
- if (always_checksum && canonical_checksum(checksum_type))
+ if (always_checksum)
n = sum_as_hex(checksum_type, F_SUM(file), 1);
- else if (iflags & ITEM_TRANSFER && canonical_checksum(xfersum_type))
+ else if (iflags & ITEM_TRANSFER)
n = sum_as_hex(xfersum_type, sender_file_sum, 0);
}
if (!n) {
{
static char buf[MAX_DIGEST_LEN*2+1];
int i, x1, x2;
+ int canonical = canonical_checksum(csum_type);
int sum_len = csum_len_for_type(csum_type, flist_csum);
- char *c = buf + sum_len*2;
+ char *c;
- assert(c - buf < (int)sizeof buf);
+ if (!canonical)
+ return NULL;
- *c = '\0';
+ assert(sum_len*2 < (int)sizeof buf);
- for (i = sum_len; --i >= 0; ) {
- x1 = CVAL(sum, i);
- x2 = x1 >> 4;
- x1 &= 0xF;
- *--c = x1 <= 9 ? x1 + '0' : x1 + 'a' - 10;
- *--c = x2 <= 9 ? x2 + '0' : x2 + 'a' - 10;
+ for (i = sum_len, c = buf; --i >= 0; ) {
+ int ndx = canonical < 0 ? sum_len - i - 1 : i;
+ x2 = CVAL(sum, ndx);
+ x1 = x2 >> 4;
+ x2 &= 0xF;
+ *c++ = x1 <= 9 ? x1 + '0' : x1 + 'a' - 10;
+ *c++ = x2 <= 9 ? x2 + '0' : x2 + 'a' - 10;
}
+ *c = '\0';
+
return buf;
}