If the path or name index is zero, this means the entry data is to be found inline rather than being located in the dictionary table. This is there to allow easy completion of thin packs without having to add new table entries which would have required a full rewrite of the pack data. Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxxx> --- packv4-create.c | 6 +++--- packv4-parse.c | 28 ++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/packv4-create.c b/packv4-create.c index fd16222..9d6ffc0 100644 --- a/packv4-create.c +++ b/packv4-create.c @@ -343,7 +343,7 @@ void *pv4_encode_commit(void *buffer, unsigned long *sizep) index = dict_add_entry(commit_name_table, tz_val, in, end - in); if (index < 0) goto bad_dict; - out += encode_varint(index, out); + out += encode_varint(index + 1, out); time = strtoul(end, &end, 10); if (!end || end[0] != ' ' || end[6] != '\n') goto bad_data; @@ -361,7 +361,7 @@ void *pv4_encode_commit(void *buffer, unsigned long *sizep) index = dict_add_entry(commit_name_table, tz_val, in, end - in); if (index < 0) goto bad_dict; - out += encode_varint(index, out); + out += encode_varint(index + 1, out); time = strtoul(end, &end, 10); if (!end || end[0] != ' ' || end[6] != '\n') goto bad_data; @@ -561,7 +561,7 @@ void *pv4_encode_tree(void *_buffer, unsigned long *sizep, free(buffer); return NULL; } - out += encode_varint(index << 1, out); + out += encode_varint((index + 1) << 1, out); out += encode_sha1ref(name_entry.sha1, out); } diff --git a/packv4-parse.c b/packv4-parse.c index 4c218d2..6db4ed3 100644 --- a/packv4-parse.c +++ b/packv4-parse.c @@ -125,11 +125,19 @@ const unsigned char *get_nameref(struct packed_git *p, const unsigned char **src load_name_dict(p); index = decode_varint(srcp); - if (index >= p->name_dict->nb_entries) { + + if (!index) { + /* the entry data is inline */ + const unsigned char *data = *srcp; + *srcp += 2 + strlen((const char *)*srcp + 2) + 1; + return data; + } + + if (index - 1 >= p->name_dict->nb_entries) { error("%s: index overflow", __func__); return NULL; } - return p->name_dict->data + p->name_dict->offsets[index]; + return p->name_dict->data + p->name_dict->offsets[index - 1]; } static void load_path_dict(struct packed_git *p) @@ -151,16 +159,24 @@ static void load_path_dict(struct packed_git *p) p->path_dict = paths; } -const unsigned char *get_pathref(struct packed_git *p, unsigned int index) +const unsigned char *get_pathref(struct packed_git *p, unsigned int index, + const unsigned char **srcp) { if (!p->path_dict) load_path_dict(p); - if (index >= p->path_dict->nb_entries) { + if (!index) { + /* the entry data is inline */ + const unsigned char *data = *srcp; + *srcp += 2 + strlen((const char *)*srcp + 2) + 1; + return data; + } + + if (index - 1 >= p->path_dict->nb_entries) { error("%s: index overflow", __func__); return NULL; } - return p->path_dict->data + p->path_dict->offsets[index]; + return p->path_dict->data + p->path_dict->offsets[index - 1]; } void *pv4_get_commit(struct packed_git *p, struct pack_window **w_curs, @@ -296,7 +312,7 @@ static int decode_entries(struct packed_git *p, struct pack_window **w_curs, unsigned mode; int len; - path = get_pathref(p, what >> 1); + path = get_pathref(p, what >> 1, &scp); sha1 = get_sha1ref(p, &scp); if (!path || !sha1) return -1; -- 1.8.4.38.g317e65b -- 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