Skip to content

Commit

Permalink
tag.c: Refactor parse_tag_buffer to be saner to program
Browse files Browse the repository at this point in the history
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: Shawn O. Pearce <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
spearce authored and gitster committed Apr 13, 2010
1 parent 628511a commit 28de5b6
Showing 1 changed file with 21 additions and 22 deletions.
43 changes: 21 additions & 22 deletions tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,41 +38,31 @@ 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;
item->object.parsed = 1;

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;
Expand All @@ -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;
}

Expand Down

0 comments on commit 28de5b6

Please sign in to comment.