git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 3/5] tag.c: Refactor parse_tag_buffer to be saner to program

From
Shawn O. Pearce <spearce@spearce.org>
Date
Apr 12, 2010, 23:25 UTC
Message-ID
<1271114729-18166-3-git-send-email-spearce@spearce.org>
In-Reply-To
<20100411024008.GC23075@spearce.org>

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>
---
 tag.c |   43 +++++++++++++++++++++----------------------
 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;
 }
 
-- 
1.7.1.rc1.246.g978a8
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 10 of 17 in “git describe bug?”
  1. Dustin SallingsApr 2, 2010
  2. Shawn O. PearceApr 2, 2010
  3. Andreas EricssonApr 6, 2010
  4. Shawn O. PearceApr 11, 2010
  5. describe: Break annotated tag ties by tagger dateShawn O. Pearce, Apr 11, 2010
  6. Junio C HamanoApr 11, 2010
  7. Shawn O. PearceApr 11, 2010
  8. 1/5 tag.c: Correct indentationShawn O. Pearce, Apr 12, 2010
  9. 2/5 tag.h: Remove unused signature fieldShawn O. Pearce, Apr 12, 2010
  10. 3/5 tag.c: Refactor parse_tag_buffer to be saner to programShawn O. Pearce, Apr 12, 2010
  11. 4/5 tag.c: Parse tagger date (if present)Shawn O. Pearce, Apr 12, 2010
  12. 5/5 describe: Break annotated tag ties by tagger dateShawn O. Pearce, Apr 12, 2010
  13. Andreas EricssonApr 13, 2010
  14. Thomas RastApr 13, 2010
  15. Shawn O. PearceApr 13, 2010
  16. Junio C HamanoApr 13, 2010
  17. Shawn O. PearceApr 13, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.