summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2010-04-12 23:25:27 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-04-13 04:45:13 (GMT)
commit28de5b6b400fcdbd2d0665bc0cec7d7e4b813b43 (patch)
treeeaa842b6a6719b73269e8ba2f2652a4377d492d5
parent628511a5883fa809e86b34ebc147ac62eb214458 (diff)
downloadgit-28de5b6b400fcdbd2d0665bc0cec7d7e4b813b43.zip
git-28de5b6b400fcdbd2d0665bc0cec7d7e4b813b43.tar.gz
git-28de5b6b400fcdbd2d0665bc0cec7d7e4b813b43.tar.bz2
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: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--tag.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/tag.c b/tag.c
index 52d71bb..ceb8655 100644
--- a/tag.c
+++ b/tag.c
@@ -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;
}