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

[PATCH 4/6] fsck: check tag objects' headers

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Aug 28, 2014, 14:46 UTC
Message-ID
<alpine.DEB.1.00.1408281646530.990@s15462909.onlinehome-server.info>
In-Reply-To
<alpine.DEB.1.00.1408171840040.990@s15462909.onlinehome-server.info>

We inspect commit objects pretty much in detail in git-fsck, but we just glanced over the tag objects. Let's be stricter.

This work was sponsored by GitHub Inc.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 fsck.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 87 insertions(+), 1 deletion(-)
diff --git a/fsck.c b/fsck.c
index db6aaa4..d30946b 100644
--- a/fsck.c
+++ b/fsck.c
@@ -6,6 +6,7 @@
 #include "commit.h"
 #include "tag.h"
 #include "fsck.h"
+#include "refs.h"
 
 static int fsck_walk_tree(struct tree *tree, fsck_walk_func walk, void *data)
 {
@@ -355,6 +356,90 @@ static int fsck_commit(struct commit *commit, const char *data,
 	return ret;
 }
 
+static int fsck_tag_buffer(struct tag *tag, const char *data,
+	unsigned long size, fsck_error error_func)
+{
+	unsigned char commit_sha1[20];
+	int ret = 0;
+	const char *buffer;
+	char *tmp = NULL, *eol;
+
+	if (data)
+		buffer = data;
+	else {
+		enum object_type type;
+
+		buffer = tmp = read_sha1_file(tag->object.sha1, &type, &size);
+		if (!buffer)
+			return error_func(&tag->object, FSCK_ERROR,
+				"cannot read tag object");
+
+		if (type != OBJ_TAG) {
+			ret = error_func(&tag->object, FSCK_ERROR,
+				"expected tag got %s",
+			    typename(type));
+			goto done;
+		}
+	}
+
+	if (must_have_empty_line(buffer, size, &tag->object, error_func))
+		goto done;
+
+	if (!skip_prefix(buffer, "object ", &buffer)) {
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'object' line");
+		goto done;
+	}
+	if (get_sha1_hex(buffer, commit_sha1) || buffer[40] != '\n') {
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid 'object' line format - bad sha1");
+		goto done;
+	}
+	buffer += 41;
+
+	if (!skip_prefix(buffer, "type ", &buffer)) {
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'type' line");
+		goto done;
+	}
+	eol = strchr(buffer, '\n');
+	if (!eol) {
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid format - unexpected end after 'type' line");
+		goto done;
+	}
+	*eol = '\0';
+	if (type_from_string_gently(buffer) < 0)
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid 'type' value");
+	*eol = '\n';
+	if (ret)
+		goto done;
+	buffer = eol + 1;
+
+	if (!skip_prefix(buffer, "tag ", &buffer)) {
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'tag' line");
+		goto done;
+	}
+	eol = strchr(buffer, '\n');
+	if (!eol) {
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid format - unexpected end after 'type' line");
+		goto done;
+	}
+	*eol = '\0';
+	if (check_refname_format(buffer, REFNAME_ALLOW_ONELEVEL))
+		ret = error_func(&tag->object, FSCK_ERROR, "invalid 'tag' name: %s", buffer);
+	*eol = '\n';
+	if (ret)
+		goto done;
+	buffer = eol + 1;
+
+	if (!skip_prefix(buffer, "tagger ", &buffer)) {
+		/* early tags do not contain 'tagger' lines; warn only */
+		error_func(&tag->object, FSCK_WARN, "invalid format - expected 'tagger' line");
+	}
+	ret = fsck_ident(&buffer, &tag->object, error_func);
+
+done:
+	free(tmp);
+	return ret;
+}
+
 static int fsck_tag(struct tag *tag, const char *data,
 	unsigned long size, fsck_error error_func)
 {
@@ -362,7 +447,8 @@ static int fsck_tag(struct tag *tag, const char *data,
 
 	if (!tagged)
 		return error_func(&tag->object, FSCK_ERROR, "could not load tagged object");
-	return 0;
+
+	return fsck_tag_buffer(tag, data, size, error_func);
 }
 
 int fsck_object(struct object *obj, void *data, unsigned long size,
-- 
2.0.0.rc3.9669.g840d1f9
Previous: Jeff KingNext: Junio C Hamano
Message 11 of 68 in “Improve tag checking in fsck and with transfer.fsckobjects”
  1. 0/6 Improve tag checking in fsck and with transfer.fsckobjectsJohannes Schindelin, Aug 28, 2014
  2. 1/6 Refactor type_from_string() to avoid die()ing in case of errorsJohannes Schindelin, Aug 28, 2014
  3. Junio C HamanoAug 28, 2014
  4. 2/6 Accept object data in the fsck_object() functionJohannes Schindelin, Aug 28, 2014
  5. Junio C HamanoAug 28, 2014
  6. Jeff KingAug 29, 2014
  7. Jeff KingAug 29, 2014
  8. 3/6 Make sure fsck_commit_buffer() does not run out of the bufferJohannes Schindelin, Aug 28, 2014
  9. Junio C HamanoAug 28, 2014
  10. Jeff KingAug 29, 2014
  11. 4/6 fsck: check tag objects' headersJohannes Schindelin, Aug 28, 2014
  12. Junio C HamanoAug 28, 2014
  13. Junio C HamanoAug 28, 2014
  14. Jeff KingAug 29, 2014
  15. Junio C HamanoAug 31, 2014
  16. Jeff KingSep 3, 2014
  17. Junio C HamanoSep 3, 2014
  18. Jeff KingSep 4, 2014
  19. Jeff KingAug 29, 2014
  20. Junio C HamanoSep 2, 2014
  21. Jeff KingSep 3, 2014
  22. 5/6 Add regression tests for stricter tag fsck'ingJohannes Schindelin, Aug 28, 2014
  23. 6/6 Make sure that index-pack --strict fails upon invalid tag objectsJohannes Schindelin, Aug 28, 2014
  24. 0/6 Improve tag checking in fsck and with transfer.fsckobjectsJohannes Schindelin, Sep 10, 2014
  25. Johannes SchindelinSep 10, 2014
  26. Junio C HamanoSep 10, 2014
  27. Junio C HamanoSep 10, 2014
  28. Johannes SchindelinSep 11, 2014
  29. 0/6 Improve tag checking in fsck and with transfer.fsckobjectsJohannes Schindelin, Sep 11, 2014
  30. 1/6 Refactor type_from_string() to avoid die()ing in case of errorsJohannes Schindelin, Sep 11, 2014
  31. 2/6 Accept object data in the fsck_object() functionJohannes Schindelin, Sep 11, 2014
  32. 3/6 Make sure fsck_commit_buffer() does not run out of the bufferJohannes Schindelin, Sep 11, 2014
  33. 4/6 fsck: check tag objects' headersJohannes Schindelin, Sep 11, 2014
  34. 5/6 Add regression tests for stricter tag fsck'ingJohannes Schindelin, Sep 11, 2014
  35. 6/6 Make sure that index-pack --strict checks tag objectsJohannes Schindelin, Sep 11, 2014
  36. Junio C HamanoSep 11, 2014
  37. Junio C HamanoSep 11, 2014
  38. 0/3 hash-object --literallyJunio C Hamano, Sep 11, 2014
  39. 1/3 hash-object: reduce file-scope staticsJunio C Hamano, Sep 11, 2014
  40. 2/3 hash-object: pass 'write_object' as a flagJunio C Hamano, Sep 11, 2014
  41. 3/3 hash-object: add --literally optionJunio C Hamano, Sep 11, 2014
  42. Johannes SchindelinSep 12, 2014
  43. 0/6 Improve tag checking in fsck and with transfer.fsckobjectsJohannes Schindelin, Sep 12, 2014
  44. 1/6 Refactor type_from_string() to avoid die()ing in case of errorsJohannes Schindelin, Sep 12, 2014
  45. 2/6 Accept object data in the fsck_object() functionJohannes Schindelin, Sep 12, 2014
  46. 3/6 Make sure fsck_commit_buffer() does not run out of the bufferJohannes Schindelin, Sep 12, 2014
  47. 4/6 fsck: check tag objects' headersJohannes Schindelin, Sep 12, 2014
  48. 5/6 Add regression tests for stricter tag fsck'ingJohannes Schindelin, Sep 12, 2014
  49. 6/6 Make sure that index-pack --strict checks tag objectsJohannes Schindelin, Sep 12, 2014
  50. Junio C HamanoSep 12, 2014
  51. Johannes SchindelinSep 13, 2014
  52. 1/6 Refactor type_from_string() to avoid die()ing in case of errorsJohannes Schindelin, Sep 10, 2014
  53. 2/6 Accept object data in the fsck_object() functionJohannes Schindelin, Sep 10, 2014
  54. 3/6 Make sure fsck_commit_buffer() does not run out of the bufferJohannes Schindelin, Sep 10, 2014
  55. Junio C HamanoSep 10, 2014
  56. Johannes SchindelinSep 11, 2014
  57. Junio C HamanoSep 11, 2014
  58. Eric SunshineSep 10, 2014
  59. 4/6 fsck: check tag objects' headersJohannes Schindelin, Sep 10, 2014
  60. Junio C HamanoSep 10, 2014
  61. 5/6 Add regression tests for stricter tag fsck'ingJohannes Schindelin, Sep 10, 2014
  62. Junio C HamanoSep 10, 2014
  63. Johannes SchindelinSep 11, 2014
  64. 6/6 Make sure that index-pack --strict fails upon invalid tag objectsJohannes Schindelin, Sep 10, 2014
  65. Junio C HamanoSep 10, 2014
  66. Johannes SchindelinSep 11, 2014
  67. Junio C HamanoSep 11, 2014
  68. Johannes SchindelinSep 11, 2014

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.