Signed-off-by: Hervé Cauwelier <herve@xxxxxxxxxx> --- src/cc-compat.h | 3 +++ src/odb.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cc-compat.h b/src/cc-compat.h index 8997caa..8dd6774 100644 --- a/src/cc-compat.h +++ b/src/cc-compat.h @@ -30,6 +30,9 @@ # define GIT_TYPEOF(x) #endif +#define bitsizeof(x) (CHAR_BIT * sizeof(x)) +#define MSB(x, bits) ((x) & GIT_TYPEOF(x)(~0ULL << (bitsizeof(x) - (bits)))) + /* * Does our compiler/platform support the C99 <inttypes.h> and * <stdint.h> header files. (C99 requires that <inttypes.h> diff --git a/src/odb.c b/src/odb.c index 2319998..2b4b016 100644 --- a/src/odb.c +++ b/src/odb.c @@ -97,8 +97,10 @@ struct git_odb { }; typedef struct { /* object header data */ - git_otype type; /* object type */ - size_t size; /* object size */ + git_otype type; /* object type */ + size_t size; /* object size */ + off_t base_offset; /* delta base offset (GIT_OBJ_OFS_DELTA) */ + git_oid base_name; /* delta base name (GIT_OBJ_REF_DELTA) */ } obj_hdr; static struct { @@ -238,6 +240,7 @@ static size_t get_binary_object_header(obj_hdr *hdr, gitfo_buf *obj) unsigned char c; unsigned char *data = obj->data; size_t shift, size, used = 0; + off_t base_offset; if (obj->len == 0) return 0; @@ -258,6 +261,27 @@ static size_t get_binary_object_header(obj_hdr *hdr, gitfo_buf *obj) } hdr->size = size; + hdr->base_offset = 0; + hdr->base_name.id[0] = '\0'; + + if (hdr->type == GIT_OBJ_OFS_DELTA) { + c = data[used++]; + base_offset = c & 127; + while (c & 128) { + base_offset++; + if (!base_offset || MSB(base_offset, 7)) + return 0; /* overflow */ + c = data[used++]; + base_offset = (base_offset << 7) + (c & 127); + } + assert(base_offset > 0); + hdr->base_offset = base_offset; + } + else if (hdr->type == GIT_OBJ_REF_DELTA) { + git_oid_mkraw(&hdr->base_name, data + used); + used += 20; + } + return used; } -- 1.6.5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html