Commit 28de5b6b authored by Shawn O. Pearce's avatar Shawn O. Pearce Committed by Junio C Hamano

tag.c: Refactor parse_tag_buffer to be saner to program

This code was horribly ugly to follow.  The structure of the headers
in an annotated tag object must follow a prescribed order, and most
of these are required.  Simplify the entire parsing logic by going
through the headers in the order they are supposed to appear in,
acting on each header as its identified in the buffer.

This change has the same behavior as the older version, its just
easier to read and maintain.
Signed-off-by: default avatarShawn O. Pearce <[email protected]>
Signed-off-by: default avatarJunio C Hamano <[email protected]>
parent 628511a5
......@@ -38,11 +38,11 @@ struct tag *lookup_tag(const unsigned char *sha1)
int parse_tag_buffer(struct tag *item, void *data, unsigned long size)
{
int typelen, taglen;
unsigned char sha1[20];
const char *type_line, *tag_line, *sig_line;
char type[20];
const char *start = data;
const char *bufptr = data;
const char *tail = bufptr + size;
const char *nl;
if (item->object.parsed)
return 0;
......@@ -50,29 +50,19 @@ int parse_tag_buffer(struct tag *item, void *data, unsigned long size)
if (size < 64)
return -1;
if (memcmp("object ", data, 7) || get_sha1_hex((char *) data + 7, sha1))
if (memcmp("object ", bufptr, 7) || get_sha1_hex(bufptr + 7, sha1) || bufptr[47] != '\n')
return -1;
bufptr += 48; /* "object " + sha1 + "\n" */
type_line = (char *) data + 48;
if (memcmp("\ntype ", type_line-1, 6))
if (prefixcmp(bufptr, "type "))
return -1;
tag_line = memchr(type_line, '\n', size - (type_line - start));
if (!tag_line || memcmp("tag ", ++tag_line, 4))
return -1;
sig_line = memchr(tag_line, '\n', size - (tag_line - start));
if (!sig_line)
return -1;
sig_line++;
typelen = tag_line - type_line - strlen("type \n");
if (typelen >= 20)
bufptr += 5;
nl = memchr(bufptr, '\n', tail - bufptr);
if (!nl || sizeof(type) <= (nl - bufptr))
return -1;
memcpy(type, type_line + 5, typelen);
type[typelen] = '\0';
taglen = sig_line - tag_line - strlen("tag \n");
item->tag = xmemdupz(tag_line + 4, taglen);
strncpy(type, bufptr, nl - bufptr);
type[nl - bufptr] = '\0';
bufptr = nl + 1;
if (!strcmp(type, blob_type)) {
item->tagged = &lookup_blob(sha1)->object;
......@@ -87,6 +77,15 @@ int parse_tag_buffer(struct tag *item, void *data, unsigned long size)
item->tagged = NULL;
}
if (prefixcmp(bufptr, "tag "))
return -1;
bufptr += 4;
nl = memchr(bufptr, '\n', tail - bufptr);
if (!nl)
return -1;
item->tag = xmemdupz(bufptr, nl - bufptr);
bufptr = nl + 1;
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment