diff options
-rw-r--r-- | count-delta.c | 23 | ||||
-rw-r--r-- | delta.h | 22 | ||||
-rw-r--r-- | diff-delta.c | 3 | ||||
-rw-r--r-- | pack-objects.c | 2 | ||||
-rw-r--r-- | patch-delta.c | 22 | ||||
-rw-r--r-- | sha1_file.c | 21 |
6 files changed, 35 insertions, 58 deletions
diff --git a/count-delta.c b/count-delta.c index 8901034188..7559ff68b1 100644 --- a/count-delta.c +++ b/count-delta.c @@ -6,23 +6,9 @@ #include <stdlib.h> #include <string.h> #include <limits.h> +#include "delta.h" #include "count-delta.h" -static unsigned long get_hdr_size(const unsigned char **datap) -{ - const unsigned char *data = *datap; - unsigned char cmd = *data++; - unsigned long size = cmd & ~0x80; - int i = 7; - while (cmd & 0x80) { - cmd = *data++; - size |= (cmd & ~0x80) << i; - i += 7; - } - *datap = data; - return size; -} - /* * NOTE. We do not _interpret_ delta fully. As an approximation, we * just count the number of bytes that are copied from the source, and @@ -44,15 +30,14 @@ int count_delta(void *delta_buf, unsigned long delta_size, unsigned char cmd; unsigned long src_size, dst_size, out; - /* the smallest delta size possible is 4 bytes */ - if (delta_size < 4) + if (delta_size < DELTA_SIZE_MIN) return -1; data = delta_buf; top = delta_buf + delta_size; - src_size = get_hdr_size(&data); - dst_size = get_hdr_size(&data); + src_size = get_delta_hdr_size(&data); + dst_size = get_delta_hdr_size(&data); added_literal = copied_from_source = out = 0; while (data < top) { @@ -9,4 +9,26 @@ extern void *patch_delta(void *src_buf, unsigned long src_size, void *delta_buf, unsigned long delta_size, unsigned long *dst_size); +/* the smallest possible delta size is 4 bytes */ +#define DELTA_SIZE_MIN 4 + +/* + * This must be called twice on the delta data buffer, first to get the + * expected reference buffer size, and again to get the result buffer size. + */ +static inline unsigned long get_delta_hdr_size(const unsigned char **datap) +{ + const unsigned char *data = *datap; + unsigned char cmd = *data++; + unsigned long size = cmd & ~0x80; + int i = 7; + while (cmd & 0x80) { + cmd = *data++; + size |= (cmd & ~0x80) << i; + i += 7; + } + *datap = data; + return size; +} + #endif diff --git a/diff-delta.c b/diff-delta.c index 67f60814b7..b2ae7b5e6c 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -306,12 +306,13 @@ void *diff_delta(void *from_buf, unsigned long from_size, *orig = i; } - /* next time around the largest possible output is 1 + 4 + 3 */ if (max_size && outpos > max_size) { free(out); delta_cleanup(&bdf); return NULL; } + + /* next time around the largest possible output is 1 + 4 + 3 */ if (outpos > outsize - 8) { void *tmp = out; outsize = outsize * 3 / 2; diff --git a/pack-objects.c b/pack-objects.c index fc969e342a..d95f45ebfe 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -34,7 +34,7 @@ static void *delta_against(void *buf, unsigned long size, struct object_entry *e if (!otherbuf) die("unable to read %s", sha1_to_hex(entry->delta->sha1)); delta_buf = diff_delta(otherbuf, othersize, - buf, size, &delta_size, ~0UL); + buf, size, &delta_size, 0); if (!delta_buf || delta_size != entry->delta_size) die("delta size changed"); free(buf); diff --git a/patch-delta.c b/patch-delta.c index b68dd13c63..26281ea123 100644 --- a/patch-delta.c +++ b/patch-delta.c @@ -20,36 +20,20 @@ void *patch_delta(void *src_buf, unsigned long src_size, const unsigned char *data, *top; unsigned char *dst_buf, *out, cmd; unsigned long size; - int i; - /* the smallest delta size possible is 4 bytes */ - if (delta_size < 4) + if (delta_size < DELTA_SIZE_MIN) return NULL; data = delta_buf; top = delta_buf + delta_size; /* make sure the orig file size matches what we expect */ - cmd = *data++; - size = cmd & ~0x80; - i = 7; - while (cmd & 0x80) { - cmd = *data++; - size |= (cmd & ~0x80) << i; - i += 7; - } + size = get_delta_hdr_size(&data); if (size != src_size) return NULL; /* now the result size */ - cmd = *data++; - size = cmd & ~0x80; - i = 7; - while (cmd & 0x80) { - cmd = *data++; - size |= (cmd & ~0x80) << i; - i += 7; - } + size = get_delta_hdr_size(&data); dst_buf = malloc(size); if (!dst_buf) return NULL; diff --git a/sha1_file.c b/sha1_file.c index f6cf180bd4..737ecb4800 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -592,22 +592,6 @@ void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned l return unpack_sha1_rest(&stream, hdr, *size); } -static unsigned long parse_delta_size(unsigned char **p) -{ - unsigned char c; - unsigned long size = 0; - unsigned shift = 0; - unsigned char *data = *p; - - do { - c = *data++; - size += (c & 0x7f) << shift; - shift += 7; - } while (c & 0x80); - *p = data; - return size; -} - static int packed_delta_info(unsigned char *base_sha1, unsigned long delta_size, unsigned long left, @@ -645,11 +629,12 @@ static int packed_delta_info(unsigned char *base_sha1, * the result size. Verify the base size while we are at it. */ data = delta_head; - verify_base_size = parse_delta_size(&data); - result_size = parse_delta_size(&data); + verify_base_size = get_delta_hdr_size(&data); if (verify_base_size != base_size) die("delta base size mismatch"); + /* Read the result size */ + result_size = get_delta_hdr_size(&data); *sizep = result_size; return 0; } |