All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 2/9] fsck_tree(): fix shadowed variable
Date: Mon, 03 May 2021 13:15:03 +0200	[thread overview]
Message-ID: <87y2cwvz9e.fsf@evledraar.gmail.com> (raw)
In-Reply-To: <YI12stO48egyiHjv@coredump.intra.peff.net>


On Sat, May 01 2021, Jeff King wrote:

> Commit b2f2039c2b (fsck: accept an oid instead of a "struct tree" for
> fsck_tree(), 2019-10-18) introduced a new "oid" parameter to
> fsck_tree(), and we pass it to the report() function when we find
> problems. However, that is shadowed within the tree-walking loop by the
> existing "oid" variable which we use to store the oid of each tree
> entry. As a result, we may report the wrong oid for some problems we
> detect within the loop (the entry oid, instead of the tree oid).
>
> Our tests didn't catch this because they checked only that we found the
> expected fsck problem, not that it was attached to the correct object.
>
> Let's rename both variables in the function to avoid confusion. This
> makes the diff a little noisy (e.g., all of the report() calls outside
> the loop were already correct but need to be touched), but makes sure we
> catch all cases and will avoid similar confusion in the future.
>
> And we can update the test to be a bit more specific and catch this
> problem.

Have you considered just passing down the "obj" instead of the "oid"?
It's a bit of a bigger change, but seems to be worth it in this case as
the below diff (on top of master) shows. We spend quite a bit of effort
peeling an "obj" just to pass oid/type further down the stack.

If you're interested in picking that up consider it to have by SOB, but
I don't think me submitting it while you have this in-flight is worth
the conflict.

diff --git a/builtin/fsck.c b/builtin/fsck.c
index 87a99b0108e..5ce8d4792d6 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -51,18 +51,18 @@ static int name_objects;
 #define ERROR_COMMIT_GRAPH 020
 #define ERROR_MULTI_PACK_INDEX 040
 
-static const char *describe_object(const struct object_id *oid)
+static const char *describe_object(const struct object *obj)
 {
-	return fsck_describe_object(&fsck_walk_options, oid);
+	return fsck_describe_object(&fsck_walk_options, obj);
 }
 
-static const char *printable_type(const struct object_id *oid,
-				  enum object_type type)
+static const char *printable_type(const struct object *obj)
 {
 	const char *ret;
+	enum object_type type = obj->type;
 
 	if (type == OBJ_NONE)
-		type = oid_object_info(the_repository, oid, NULL);
+		type = oid_object_info(the_repository, &obj->oid, NULL);
 
 	ret = type_name(type);
 	if (!ret)
@@ -76,14 +76,13 @@ static int objerror(struct object *obj, const char *err)
 	errors_found |= ERROR_OBJECT;
 	/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
 	fprintf_ln(stderr, _("error in %s %s: %s"),
-		   printable_type(&obj->oid, obj->type),
-		   describe_object(&obj->oid), err);
+		   printable_type(obj),
+		   describe_object(obj), err);
 	return -1;
 }
 
 static int fsck_error_func(struct fsck_options *o,
-			   const struct object_id *oid,
-			   enum object_type object_type,
+			   const struct object *obj,
 			   enum fsck_msg_type msg_type,
 			   enum fsck_msg_id msg_id,
 			   const char *message)
@@ -92,14 +91,14 @@ static int fsck_error_func(struct fsck_options *o,
 	case FSCK_WARN:
 		/* TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> */
 		fprintf_ln(stderr, _("warning in %s %s: %s"),
-			   printable_type(oid, object_type),
-			   describe_object(oid), message);
+			   printable_type(obj),
+			   describe_object(obj), message);
 		return 0;
 	case FSCK_ERROR:
 		/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
 		fprintf_ln(stderr, _("error in %s %s: %s"),
-			   printable_type(oid, object_type),
-			   describe_object(oid), message);
+			   printable_type(obj),
+			   describe_object(obj), message);
 		return 1;
 	default:
 		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
@@ -121,8 +120,8 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
 	if (!obj) {
 		/* ... these references to parent->fld are safe here */
 		printf_ln(_("broken link from %7s %s"),
-			  printable_type(&parent->oid, parent->type),
-			  describe_object(&parent->oid));
+			  printable_type(parent),
+			  describe_object(parent));
 		printf_ln(_("broken link from %7s %s"),
 			  (type == OBJ_ANY ? _("unknown") : type_name(type)),
 			  _("unknown"));
@@ -150,10 +149,10 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
 		if (parent && !has_object(the_repository, &obj->oid, 1)) {
 			printf_ln(_("broken link from %7s %s\n"
 				    "              to %7s %s"),
-				  printable_type(&parent->oid, parent->type),
-				  describe_object(&parent->oid),
-				  printable_type(&obj->oid, obj->type),
-				  describe_object(&obj->oid));
+				  printable_type(parent),
+				  describe_object(parent),
+				  printable_type(obj),
+				  describe_object(obj));
 			errors_found |= ERROR_REACHABLE;
 		}
 		return 1;
@@ -261,8 +260,8 @@ static void check_reachable_object(struct object *obj)
 		if (has_object_pack(&obj->oid))
 			return; /* it is in pack - forget about it */
 		printf_ln(_("missing %s %s"),
-			  printable_type(&obj->oid, obj->type),
-			  describe_object(&obj->oid));
+			  printable_type(obj),
+			  describe_object(obj));
 		errors_found |= ERROR_REACHABLE;
 		return;
 	}
@@ -288,8 +287,8 @@ static void check_unreachable_object(struct object *obj)
 	 */
 	if (show_unreachable) {
 		printf_ln(_("unreachable %s %s"),
-			  printable_type(&obj->oid, obj->type),
-			  describe_object(&obj->oid));
+			  printable_type(obj),
+			  describe_object(obj));
 		return;
 	}
 
@@ -308,12 +307,12 @@ static void check_unreachable_object(struct object *obj)
 	if (!(obj->flags & USED)) {
 		if (show_dangling)
 			printf_ln(_("dangling %s %s"),
-				  printable_type(&obj->oid, obj->type),
-				  describe_object(&obj->oid));
+				  printable_type(obj),
+				  describe_object(obj));
 		if (write_lost_and_found) {
 			char *filename = git_pathdup("lost-found/%s/%s",
 				obj->type == OBJ_COMMIT ? "commit" : "other",
-				describe_object(&obj->oid));
+				describe_object(obj));
 			FILE *f;
 
 			if (safe_create_leading_directories_const(filename)) {
@@ -326,7 +325,7 @@ static void check_unreachable_object(struct object *obj)
 				if (stream_blob_to_fd(fileno(f), &obj->oid, NULL, 1))
 					die_errno(_("could not write '%s'"), filename);
 			} else
-				fprintf(f, "%s\n", describe_object(&obj->oid));
+				fprintf(f, "%s\n", describe_object(obj));
 			if (fclose(f))
 				die_errno(_("could not finish '%s'"),
 					  filename);
@@ -345,7 +344,7 @@ static void check_unreachable_object(struct object *obj)
 static void check_object(struct object *obj)
 {
 	if (verbose)
-		fprintf_ln(stderr, _("Checking %s"), describe_object(&obj->oid));
+		fprintf_ln(stderr, _("Checking %s"), describe_object(obj));
 
 	if (obj->flags & REACHABLE)
 		check_reachable_object(obj);
@@ -403,8 +402,8 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
 
 	if (verbose)
 		fprintf_ln(stderr, _("Checking %s %s"),
-			   printable_type(&obj->oid, obj->type),
-			   describe_object(&obj->oid));
+			   printable_type(obj),
+			   describe_object(obj));
 
 	if (fsck_walk(obj, NULL, &fsck_obj_options))
 		objerror(obj, _("broken links"));
@@ -417,7 +416,7 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
 
 		if (!commit->parents && show_root)
 			printf_ln(_("root %s"),
-				  describe_object(&commit->object.oid));
+				  describe_object(&commit->object));
 	}
 
 	if (obj->type == OBJ_TAG) {
@@ -425,10 +424,10 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
 
 		if (show_tags && tag->tagged) {
 			printf_ln(_("tagged %s %s (%s) in %s"),
-				  printable_type(&tag->tagged->oid, tag->tagged->type),
-				  describe_object(&tag->tagged->oid),
+				  printable_type(tag->tagged),
+				  describe_object(tag->tagged),
 				  tag->tag,
-				  describe_object(&tag->object.oid));
+				  describe_object(&tag->object));
 		}
 	}
 
diff --git a/builtin/mktag.c b/builtin/mktag.c
index dddcccdd368..4ea768d6cc1 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -15,8 +15,7 @@ static int option_strict = 1;
 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 
 static int mktag_fsck_error_func(struct fsck_options *o,
-				 const struct object_id *oid,
-				 enum object_type object_type,
+				 const struct object *obj,
 				 enum fsck_msg_type msg_type,
 				 enum fsck_msg_id msg_id,
 				 const char *message)
diff --git a/fsck.c b/fsck.c
index f5ed6a26358..4ded78b5af9 100644
--- a/fsck.c
+++ b/fsck.c
@@ -199,14 +199,14 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values)
 }
 
 static int object_on_skiplist(struct fsck_options *opts,
-			      const struct object_id *oid)
+			      const struct object *obj)
 {
-	return opts && oid && oidset_contains(&opts->skiplist, oid);
+	return opts && obj && oidset_contains(&opts->skiplist, &obj->oid);
 }
 
-__attribute__((format (printf, 5, 6)))
+__attribute__((format (printf, 4, 5)))
 static int report(struct fsck_options *options,
-		  const struct object_id *oid, enum object_type object_type,
+		  const struct object *obj,
 		  enum fsck_msg_id msg_id, const char *fmt, ...)
 {
 	va_list ap;
@@ -217,7 +217,7 @@ static int report(struct fsck_options *options,
 	if (msg_type == FSCK_IGNORE)
 		return 0;
 
-	if (object_on_skiplist(options, oid))
+	if (object_on_skiplist(options, obj))
 		return 0;
 
 	if (msg_type == FSCK_FATAL)
@@ -230,7 +230,7 @@ static int report(struct fsck_options *options,
 
 	va_start(ap, fmt);
 	strbuf_vaddf(&sb, fmt, ap);
-	result = options->error_func(options, oid, object_type,
+	result = options->error_func(options, obj,
 				     msg_type, msg_id, sb.buf);
 	strbuf_release(&sb);
 	va_end(ap);
@@ -278,8 +278,9 @@ void fsck_put_object_name(struct fsck_options *options,
 }
 
 const char *fsck_describe_object(struct fsck_options *options,
-				 const struct object_id *oid)
+				 const struct object *obj)
 {
+	const struct object_id *oid = &obj->oid;
 	static struct strbuf bufs[] = {
 		STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
 	};
@@ -333,7 +334,7 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
 		}
 		else {
 			result = error("in tree %s: entry %s has bad mode %.6o",
-				       fsck_describe_object(options, &tree->object.oid),
+				       fsck_describe_object(options, &tree->object),
 				       entry.path, entry.mode);
 		}
 		if (result < 0)
@@ -443,7 +444,7 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options)
 		return fsck_walk_tag((struct tag *)obj, data, options);
 	default:
 		error("Unknown object type for %s",
-		      fsck_describe_object(options, &obj->oid));
+		      fsck_describe_object(options, obj));
 		return -1;
 	}
 }
@@ -558,7 +559,7 @@ static int verify_ordered(unsigned mode1, const char *name1,
 	return c1 < c2 ? 0 : TREE_UNORDERED;
 }
 
-static int fsck_tree(const struct object_id *oid,
+static int fsck_tree(const struct object *obj,
 		     const char *buffer, unsigned long size,
 		     struct fsck_options *options)
 {
@@ -579,7 +580,7 @@ static int fsck_tree(const struct object_id *oid,
 	struct name_stack df_dup_candidates = { NULL };
 
 	if (init_tree_desc_gently(&desc, buffer, size)) {
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
+		retval += report(options, obj, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
 		return retval;
 	}
 
@@ -606,7 +607,7 @@ static int fsck_tree(const struct object_id *oid,
 				oidset_insert(&options->gitmodules_found, oid);
 			else
 				retval += report(options,
-						 oid, OBJ_TREE,
+						 obj,
 						 FSCK_MSG_GITMODULES_SYMLINK,
 						 ".gitmodules is a symbolic link");
 		}
@@ -619,7 +620,7 @@ static int fsck_tree(const struct object_id *oid,
 					if (!S_ISLNK(mode))
 						oidset_insert(&options->gitmodules_found, oid);
 					else
-						retval += report(options, oid, OBJ_TREE,
+						retval += report(options, obj,
 								 FSCK_MSG_GITMODULES_SYMLINK,
 								 ".gitmodules is a symbolic link");
 				}
@@ -628,7 +629,7 @@ static int fsck_tree(const struct object_id *oid,
 		}
 
 		if (update_tree_entry_gently(&desc)) {
-			retval += report(options, oid, OBJ_TREE, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
+			retval += report(options, obj, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
 			break;
 		}
 
@@ -676,30 +677,30 @@ static int fsck_tree(const struct object_id *oid,
 	name_stack_clear(&df_dup_candidates);
 
 	if (has_null_sha1)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_NULL_SHA1, "contains entries pointing to null sha1");
+		retval += report(options, obj, FSCK_MSG_NULL_SHA1, "contains entries pointing to null sha1");
 	if (has_full_path)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_FULL_PATHNAME, "contains full pathnames");
+		retval += report(options, obj, FSCK_MSG_FULL_PATHNAME, "contains full pathnames");
 	if (has_empty_name)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_EMPTY_NAME, "contains empty pathname");
+		retval += report(options, obj, FSCK_MSG_EMPTY_NAME, "contains empty pathname");
 	if (has_dot)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_HAS_DOT, "contains '.'");
+		retval += report(options, obj, FSCK_MSG_HAS_DOT, "contains '.'");
 	if (has_dotdot)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_HAS_DOTDOT, "contains '..'");
+		retval += report(options, obj, FSCK_MSG_HAS_DOTDOT, "contains '..'");
 	if (has_dotgit)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_HAS_DOTGIT, "contains '.git'");
+		retval += report(options, obj, FSCK_MSG_HAS_DOTGIT, "contains '.git'");
 	if (has_zero_pad)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_ZERO_PADDED_FILEMODE, "contains zero-padded file modes");
+		retval += report(options, obj, FSCK_MSG_ZERO_PADDED_FILEMODE, "contains zero-padded file modes");
 	if (has_bad_modes)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_BAD_FILEMODE, "contains bad file modes");
+		retval += report(options, obj, FSCK_MSG_BAD_FILEMODE, "contains bad file modes");
 	if (has_dup_entries)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_DUPLICATE_ENTRIES, "contains duplicate file entries");
+		retval += report(options, obj, FSCK_MSG_DUPLICATE_ENTRIES, "contains duplicate file entries");
 	if (not_properly_sorted)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_TREE_NOT_SORTED, "not properly sorted");
+		retval += report(options, obj, FSCK_MSG_TREE_NOT_SORTED, "not properly sorted");
 	return retval;
 }
 
 static int verify_headers(const void *data, unsigned long size,
-			  const struct object_id *oid, enum object_type type,
+			  const struct object *obj,
 			  struct fsck_options *options)
 {
 	const char *buffer = (const char *)data;
@@ -708,7 +709,7 @@ static int verify_headers(const void *data, unsigned long size,
 	for (i = 0; i < size; i++) {
 		switch (buffer[i]) {
 		case '\0':
-			return report(options, oid, type,
+			return report(options, obj,
 				FSCK_MSG_NUL_IN_HEADER,
 				"unterminated header: NUL at offset %ld", i);
 		case '\n':
@@ -726,12 +727,12 @@ static int verify_headers(const void *data, unsigned long size,
 	if (size && buffer[size - 1] == '\n')
 		return 0;
 
-	return report(options, oid, type,
-		FSCK_MSG_UNTERMINATED_HEADER, "unterminated header");
+	return report(options, obj,
+		      FSCK_MSG_UNTERMINATED_HEADER, "unterminated header");
 }
 
 static int fsck_ident(const char **ident,
-		      const struct object_id *oid, enum object_type type,
+		      const struct object *obj,
 		      struct fsck_options *options)
 {
 	const char *p = *ident;
@@ -742,28 +743,28 @@ static int fsck_ident(const char **ident,
 		(*ident)++;
 
 	if (*p == '<')
-		return report(options, oid, type, FSCK_MSG_MISSING_NAME_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
+		return report(options, obj, FSCK_MSG_MISSING_NAME_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
 	p += strcspn(p, "<>\n");
 	if (*p == '>')
-		return report(options, oid, type, FSCK_MSG_BAD_NAME, "invalid author/committer line - bad name");
+		return report(options, obj, FSCK_MSG_BAD_NAME, "invalid author/committer line - bad name");
 	if (*p != '<')
-		return report(options, oid, type, FSCK_MSG_MISSING_EMAIL, "invalid author/committer line - missing email");
+		return report(options, obj, FSCK_MSG_MISSING_EMAIL, "invalid author/committer line - missing email");
 	if (p[-1] != ' ')
-		return report(options, oid, type, FSCK_MSG_MISSING_SPACE_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
+		return report(options, obj, FSCK_MSG_MISSING_SPACE_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
 	p++;
 	p += strcspn(p, "<>\n");
 	if (*p != '>')
-		return report(options, oid, type, FSCK_MSG_BAD_EMAIL, "invalid author/committer line - bad email");
+		return report(options, obj, FSCK_MSG_BAD_EMAIL, "invalid author/committer line - bad email");
 	p++;
 	if (*p != ' ')
-		return report(options, oid, type, FSCK_MSG_MISSING_SPACE_BEFORE_DATE, "invalid author/committer line - missing space before date");
+		return report(options, obj, FSCK_MSG_MISSING_SPACE_BEFORE_DATE, "invalid author/committer line - missing space before date");
 	p++;
 	if (*p == '0' && p[1] != ' ')
-		return report(options, oid, type, FSCK_MSG_ZERO_PADDED_DATE, "invalid author/committer line - zero-padded date");
+		return report(options, obj, FSCK_MSG_ZERO_PADDED_DATE, "invalid author/committer line - zero-padded date");
 	if (date_overflows(parse_timestamp(p, &end, 10)))
-		return report(options, oid, type, FSCK_MSG_BAD_DATE_OVERFLOW, "invalid author/committer line - date causes integer overflow");
+		return report(options, obj, FSCK_MSG_BAD_DATE_OVERFLOW, "invalid author/committer line - date causes integer overflow");
 	if ((end == p || *end != ' '))
-		return report(options, oid, type, FSCK_MSG_BAD_DATE, "invalid author/committer line - bad date");
+		return report(options, obj, FSCK_MSG_BAD_DATE, "invalid author/committer line - bad date");
 	p = end + 1;
 	if ((*p != '+' && *p != '-') ||
 	    !isdigit(p[1]) ||
@@ -771,12 +772,12 @@ static int fsck_ident(const char **ident,
 	    !isdigit(p[3]) ||
 	    !isdigit(p[4]) ||
 	    (p[5] != '\n'))
-		return report(options, oid, type, FSCK_MSG_BAD_TIMEZONE, "invalid author/committer line - bad time zone");
+		return report(options, obj, FSCK_MSG_BAD_TIMEZONE, "invalid author/committer line - bad time zone");
 	p += 6;
 	return 0;
 }
 
-static int fsck_commit(const struct object_id *oid,
+static int fsck_commit(const struct object *obj,
 		       const char *buffer, unsigned long size,
 		       struct fsck_options *options)
 {
@@ -786,20 +787,20 @@ static int fsck_commit(const struct object_id *oid,
 	const char *buffer_begin = buffer;
 	const char *p;
 
-	if (verify_headers(buffer, size, oid, OBJ_COMMIT, options))
+	if (verify_headers(buffer, size, obj, options))
 		return -1;
 
 	if (!skip_prefix(buffer, "tree ", &buffer))
-		return report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line");
+		return report(options, obj, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line");
 	if (parse_oid_hex(buffer, &tree_oid, &p) || *p != '\n') {
-		err = report(options, oid, OBJ_COMMIT, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1");
+		err = report(options, obj, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1");
 		if (err)
 			return err;
 	}
 	buffer = p + 1;
 	while (skip_prefix(buffer, "parent ", &buffer)) {
 		if (parse_oid_hex(buffer, &parent_oid, &p) || *p != '\n') {
-			err = report(options, oid, OBJ_COMMIT, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1");
+			err = report(options, obj, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1");
 			if (err)
 				return err;
 		}
@@ -808,23 +809,23 @@ static int fsck_commit(const struct object_id *oid,
 	author_count = 0;
 	while (skip_prefix(buffer, "author ", &buffer)) {
 		author_count++;
-		err = fsck_ident(&buffer, oid, OBJ_COMMIT, options);
+		err = fsck_ident(&buffer, obj, options);
 		if (err)
 			return err;
 	}
 	if (author_count < 1)
-		err = report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_AUTHOR, "invalid format - expected 'author' line");
+		err = report(options, obj, FSCK_MSG_MISSING_AUTHOR, "invalid format - expected 'author' line");
 	else if (author_count > 1)
-		err = report(options, oid, OBJ_COMMIT, FSCK_MSG_MULTIPLE_AUTHORS, "invalid format - multiple 'author' lines");
+		err = report(options, obj, FSCK_MSG_MULTIPLE_AUTHORS, "invalid format - multiple 'author' lines");
 	if (err)
 		return err;
 	if (!skip_prefix(buffer, "committer ", &buffer))
-		return report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_COMMITTER, "invalid format - expected 'committer' line");
-	err = fsck_ident(&buffer, oid, OBJ_COMMIT, options);
+		return report(options, obj, FSCK_MSG_MISSING_COMMITTER, "invalid format - expected 'committer' line");
+	err = fsck_ident(&buffer, obj, options);
 	if (err)
 		return err;
 	if (memchr(buffer_begin, '\0', size)) {
-		err = report(options, oid, OBJ_COMMIT, FSCK_MSG_NUL_IN_COMMIT,
+		err = report(options, obj, FSCK_MSG_NUL_IN_COMMIT,
 			     "NUL byte in the commit object body");
 		if (err)
 			return err;
@@ -832,16 +833,16 @@ static int fsck_commit(const struct object_id *oid,
 	return 0;
 }
 
-static int fsck_tag(const struct object_id *oid, const char *buffer,
+static int fsck_tag(const struct object *obj, const char *buffer,
 		    unsigned long size, struct fsck_options *options)
 {
 	struct object_id tagged_oid;
 	int tagged_type;
-	return fsck_tag_standalone(oid, buffer, size, options, &tagged_oid,
+	return fsck_tag_standalone(obj, buffer, size, options, &tagged_oid,
 				   &tagged_type);
 }
 
-int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+int fsck_tag_standalone(const struct object *obj, const char *buffer,
 			unsigned long size, struct fsck_options *options,
 			struct object_id *tagged_oid,
 			int *tagged_type)
@@ -851,49 +852,49 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
 	struct strbuf sb = STRBUF_INIT;
 	const char *p;
 
-	ret = verify_headers(buffer, size, oid, OBJ_TAG, options);
+	ret = verify_headers(buffer, size, obj, options);
 	if (ret)
 		goto done;
 
 	if (!skip_prefix(buffer, "object ", &buffer)) {
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
+		ret = report(options, obj, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
 		goto done;
 	}
 	if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
+		ret = report(options, obj, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
 		if (ret)
 			goto done;
 	}
 	buffer = p + 1;
 
 	if (!skip_prefix(buffer, "type ", &buffer)) {
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE_ENTRY, "invalid format - expected 'type' line");
+		ret = report(options, obj, FSCK_MSG_MISSING_TYPE_ENTRY, "invalid format - expected 'type' line");
 		goto done;
 	}
 	eol = strchr(buffer, '\n');
 	if (!eol) {
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
+		ret = report(options, obj, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
 		goto done;
 	}
 	*tagged_type = type_from_string_gently(buffer, eol - buffer, 1);
 	if (*tagged_type < 0)
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
+		ret = report(options, obj, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
 	if (ret)
 		goto done;
 	buffer = eol + 1;
 
 	if (!skip_prefix(buffer, "tag ", &buffer)) {
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TAG_ENTRY, "invalid format - expected 'tag' line");
+		ret = report(options, obj, FSCK_MSG_MISSING_TAG_ENTRY, "invalid format - expected 'tag' line");
 		goto done;
 	}
 	eol = strchr(buffer, '\n');
 	if (!eol) {
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TAG, "invalid format - unexpected end after 'type' line");
+		ret = report(options, obj, FSCK_MSG_MISSING_TAG, "invalid format - unexpected end after 'type' line");
 		goto done;
 	}
 	strbuf_addf(&sb, "refs/tags/%.*s", (int)(eol - buffer), buffer);
 	if (check_refname_format(sb.buf, 0)) {
-		ret = report(options, oid, OBJ_TAG,
+		ret = report(options, obj,
 			     FSCK_MSG_BAD_TAG_NAME,
 			     "invalid 'tag' name: %.*s",
 			     (int)(eol - buffer), buffer);
@@ -904,12 +905,12 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
 
 	if (!skip_prefix(buffer, "tagger ", &buffer)) {
 		/* early tags do not contain 'tagger' lines; warn only */
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TAGGER_ENTRY, "invalid format - expected 'tagger' line");
+		ret = report(options, obj, FSCK_MSG_MISSING_TAGGER_ENTRY, "invalid format - expected 'tagger' line");
 		if (ret)
 			goto done;
 	}
 	else
-		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
+		ret = fsck_ident(&buffer, obj, options);
 	if (!*buffer)
 		goto done;
 
@@ -921,7 +922,7 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
 		 * garbage" could be a custom header. E.g. "mktag"
 		 * doesn't want any unknown headers.
 		 */
-		ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
+		ret = report(options, obj, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
 		if (ret)
 			goto done;
 	}
@@ -1075,7 +1076,7 @@ static int check_submodule_url(const char *url)
 }
 
 struct fsck_gitmodules_data {
-	const struct object_id *oid;
+	const struct object *obj;
 	struct fsck_options *options;
 	int ret;
 };
@@ -1094,27 +1095,27 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
 	name = xmemdupz(subsection, subsection_len);
 	if (check_submodule_name(name) < 0)
 		data->ret |= report(data->options,
-				    data->oid, OBJ_BLOB,
+				    data->obj,
 				    FSCK_MSG_GITMODULES_NAME,
 				    "disallowed submodule name: %s",
 				    name);
 	if (!strcmp(key, "url") && value &&
 	    check_submodule_url(value) < 0)
 		data->ret |= report(data->options,
-				    data->oid, OBJ_BLOB,
+				    data->obj,
 				    FSCK_MSG_GITMODULES_URL,
 				    "disallowed submodule url: %s",
 				    value);
 	if (!strcmp(key, "path") && value &&
 	    looks_like_command_line_option(value))
 		data->ret |= report(data->options,
-				    data->oid, OBJ_BLOB,
+				    data->obj,
 				    FSCK_MSG_GITMODULES_PATH,
 				    "disallowed submodule path: %s",
 				    value);
 	if (!strcmp(key, "update") && value &&
 	    parse_submodule_update_type(value) == SM_UPDATE_COMMAND)
-		data->ret |= report(data->options, data->oid, OBJ_BLOB,
+		data->ret |= report(data->options, data->obj,
 				    FSCK_MSG_GITMODULES_UPDATE,
 				    "disallowed submodule update setting: %s",
 				    value);
@@ -1123,9 +1124,10 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
 	return 0;
 }
 
-static int fsck_blob(const struct object_id *oid, const char *buf,
+static int fsck_blob(const struct object *obj, const char *buf,
 		     unsigned long size, struct fsck_options *options)
 {
+	const struct object_id *oid = &obj->oid;
 	struct fsck_gitmodules_data data;
 	struct config_options config_opts = { 0 };
 
@@ -1133,7 +1135,7 @@ static int fsck_blob(const struct object_id *oid, const char *buf,
 		return 0;
 	oidset_insert(&options->gitmodules_done, oid);
 
-	if (object_on_skiplist(options, oid))
+	if (object_on_skiplist(options, obj))
 		return 0;
 
 	if (!buf) {
@@ -1142,18 +1144,18 @@ static int fsck_blob(const struct object_id *oid, const char *buf,
 		 * blob too gigantic to load into memory. Let's just consider
 		 * that an error.
 		 */
-		return report(options, oid, OBJ_BLOB,
+		return report(options, obj,
 			      FSCK_MSG_GITMODULES_LARGE,
 			      ".gitmodules too large to parse");
 	}
 
-	data.oid = oid;
+	data.obj = obj;
 	data.options = options;
 	data.ret = 0;
 	config_opts.error_action = CONFIG_ERROR_SILENT;
 	if (git_config_from_mem(fsck_gitmodules_fn, CONFIG_ORIGIN_BLOB,
 				".gitmodules", buf, size, &data, &config_opts))
-		data.ret |= report(options, oid, OBJ_BLOB,
+		data.ret |= report(options, obj,
 				   FSCK_MSG_GITMODULES_PARSE,
 				   "could not parse gitmodules blob");
 
@@ -1164,35 +1166,34 @@ int fsck_object(struct object *obj, void *data, unsigned long size,
 	struct fsck_options *options)
 {
 	if (!obj)
-		return report(options, NULL, OBJ_NONE, FSCK_MSG_BAD_OBJECT_SHA1, "no valid object to fsck");
+		return report(options, obj, FSCK_MSG_BAD_OBJECT_SHA1, "no valid object to fsck");
 
 	if (obj->type == OBJ_BLOB)
-		return fsck_blob(&obj->oid, data, size, options);
+		return fsck_blob(obj, data, size, options);
 	if (obj->type == OBJ_TREE)
-		return fsck_tree(&obj->oid, data, size, options);
+		return fsck_tree(obj, data, size, options);
 	if (obj->type == OBJ_COMMIT)
-		return fsck_commit(&obj->oid, data, size, options);
+		return fsck_commit(obj, data, size, options);
 	if (obj->type == OBJ_TAG)
-		return fsck_tag(&obj->oid, data, size, options);
+		return fsck_tag(obj, data, size, options);
 
-	return report(options, &obj->oid, obj->type,
+	return report(options, obj,
 		      FSCK_MSG_UNKNOWN_TYPE,
 		      "unknown type '%d' (internal fsck error)",
 		      obj->type);
 }
 
 int fsck_error_function(struct fsck_options *o,
-			const struct object_id *oid,
-			enum object_type object_type,
+			const struct object *obj,
 			enum fsck_msg_type msg_type,
 			enum fsck_msg_id msg_id,
 			const char *message)
 {
 	if (msg_type == FSCK_WARN) {
-		warning("object %s: %s", fsck_describe_object(o, oid), message);
+		warning("object %s: %s", fsck_describe_object(o, obj), message);
 		return 0;
 	}
-	error("object %s: %s", fsck_describe_object(o, oid), message);
+	error("object %s: %s", fsck_describe_object(o, obj), message);
 	return 1;
 }
 
@@ -1204,6 +1205,7 @@ int fsck_finish(struct fsck_options *options)
 
 	oidset_iter_init(&options->gitmodules_found, &iter);
 	while ((oid = oidset_iter_next(&iter))) {
+		struct object *obj;
 		enum object_type type;
 		unsigned long size;
 		char *buf;
@@ -1215,20 +1217,24 @@ int fsck_finish(struct fsck_options *options)
 		if (!buf) {
 			if (is_promisor_object(oid))
 				continue;
+			obj = (struct object *)lookup_blob(the_repository, oid);
 			ret |= report(options,
-				      oid, OBJ_BLOB,
+				      obj,
 				      FSCK_MSG_GITMODULES_MISSING,
 				      "unable to read .gitmodules blob");
 			continue;
 		}
 
-		if (type == OBJ_BLOB)
-			ret |= fsck_blob(oid, buf, size, options);
-		else
+		if (type == OBJ_BLOB) {
+			obj = (struct object *)lookup_blob(the_repository, oid);
+			ret |= fsck_blob(obj, buf, size, options);
+		} else {
+			obj = lookup_object(the_repository, oid);
 			ret |= report(options,
-				      oid, type,
+				      obj,
 				      FSCK_MSG_GITMODULES_BLOB,
 				      "non-blob found at .gitmodules");
+		}
 		free(buf);
 	}
 
@@ -1267,15 +1273,14 @@ int git_fsck_config(const char *var, const char *value, void *cb)
  */
 
 int fsck_error_cb_print_missing_gitmodules(struct fsck_options *o,
-					   const struct object_id *oid,
-					   enum object_type object_type,
+					   const struct object *obj,
 					   enum fsck_msg_type msg_type,
 					   enum fsck_msg_id msg_id,
 					   const char *message)
 {
 	if (msg_id == FSCK_MSG_GITMODULES_MISSING) {
-		puts(oid_to_hex(oid));
+		puts(oid_to_hex(&obj->oid));
 		return 0;
 	}
-	return fsck_error_function(o, oid, object_type, msg_type, msg_id, message);
+	return fsck_error_function(o, obj, msg_type, msg_id, message);
 }
diff --git a/fsck.h b/fsck.h
index 7202c3c87e8..864032709c4 100644
--- a/fsck.h
+++ b/fsck.h
@@ -103,17 +103,16 @@ typedef int (*fsck_walk_func)(struct object *obj, enum object_type object_type,
 
 /* callback for fsck_object, type is FSCK_ERROR or FSCK_WARN */
 typedef int (*fsck_error)(struct fsck_options *o,
-			  const struct object_id *oid, enum object_type object_type,
+			  const struct object *obj,
 			  enum fsck_msg_type msg_type, enum fsck_msg_id msg_id,
 			  const char *message);
 
 int fsck_error_function(struct fsck_options *o,
-			const struct object_id *oid, enum object_type object_type,
+			const struct object *obj,
 			enum fsck_msg_type msg_type, enum fsck_msg_id msg_id,
 			const char *message);
 int fsck_error_cb_print_missing_gitmodules(struct fsck_options *o,
-					   const struct object_id *oid,
-					   enum object_type object_type,
+					   const struct object *obj,
 					   enum fsck_msg_type msg_type,
 					   enum fsck_msg_id msg_id,
 					   const char *message);
@@ -168,7 +167,7 @@ int fsck_object(struct object *obj, void *data, unsigned long size,
  * fsck a tag, and pass info about it back to the caller. This is
  * exposed fsck_object() internals for git-mktag(1).
  */
-int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+int fsck_tag_standalone(const struct object *obj, const char *buffer,
 			unsigned long size, struct fsck_options *options,
 			struct object_id *tagged_oid,
 			int *tag_type);
@@ -203,7 +202,7 @@ void fsck_put_object_name(struct fsck_options *options,
 			  const struct object_id *oid,
 			  const char *fmt, ...);
 const char *fsck_describe_object(struct fsck_options *options,
-				 const struct object_id *oid);
+				 const struct object *obj);
 
 /*
  * git_config() callback for use by fsck-y tools that want to support

  reply	other threads:[~2021-05-03 11:21 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-01 15:40 [PATCH 0/9] leftover bits from symlinked gitattributes, etc topics Jeff King
2021-05-01 15:41 ` [PATCH 1/9] t7415: remove out-dated comment about translation Jeff King
2021-05-03  9:46   ` Ævar Arnfjörð Bjarmason
2021-05-03 20:29     ` Jeff King
2021-05-01 15:41 ` [PATCH 2/9] fsck_tree(): fix shadowed variable Jeff King
2021-05-03 11:15   ` Ævar Arnfjörð Bjarmason [this message]
2021-05-03 20:13     ` Jeff King
2021-05-04 10:10       ` Ævar Arnfjörð Bjarmason
2021-05-01 15:41 ` [PATCH 3/9] fsck_tree(): wrap some long lines Jeff King
2021-05-03 11:22   ` Ævar Arnfjörð Bjarmason
2021-05-03 20:23     ` Jeff King
2021-05-01 15:42 ` [PATCH 4/9] t7415: rename to expand scope Jeff King
2021-05-01 15:42 ` [PATCH 5/9] t7450: test verify_path() handling of gitmodules Jeff King
2021-05-01 18:55   ` Eric Sunshine
2021-05-01 19:03     ` Eric Sunshine
2021-05-03 19:39       ` Jeff King
2021-05-03 10:12   ` Ævar Arnfjörð Bjarmason
2021-05-03 20:32     ` Jeff King
2021-05-01 15:42 ` [PATCH 6/9] t7450: test .gitmodules symlink matching against obscured names Jeff King
2021-05-01 15:42 ` [PATCH 7/9] t0060: test ntfs/hfs-obscured dotfiles Jeff King
2021-05-01 15:43 ` [PATCH 8/9] fsck: warn about symlinked dotfiles we'll open with O_NOFOLLOW Jeff King
2021-05-01 15:43 ` [PATCH 9/9] docs: document symlink restrictions for dot-files Jeff King
2021-05-01 19:16   ` Eric Sunshine
2021-05-03 20:33     ` Jeff King
2021-05-03  5:36 ` [PATCH 0/9] leftover bits from symlinked gitattributes, etc topics Junio C Hamano
2021-05-03 20:42 ` [PATCH v2 " Jeff King
2021-05-03 20:43   ` [PATCH v2 1/9] t7415: remove out-dated comment about translation Jeff King
2021-05-03 20:43   ` [PATCH v2 2/9] fsck_tree(): fix shadowed variable Jeff King
2021-05-03 20:43   ` [PATCH v2 3/9] fsck_tree(): wrap some long lines Jeff King
2021-05-03 20:43   ` [PATCH v2 4/9] t7415: rename to expand scope Jeff King
2021-05-03 20:43   ` [PATCH v2 5/9] t7450: test verify_path() handling of gitmodules Jeff King
2021-05-03 20:43   ` [PATCH v2 6/9] t7450: test .gitmodules symlink matching against obscured names Jeff King
2021-05-03 20:43   ` [PATCH v2 7/9] t0060: test ntfs/hfs-obscured dotfiles Jeff King
2021-05-03 20:43   ` [PATCH v2 8/9] fsck: warn about symlinked dotfiles we'll open with O_NOFOLLOW Jeff King
2021-05-03 20:43   ` [PATCH v2 9/9] docs: document symlink restrictions for dot-files Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y2cwvz9e.fsf@evledraar.gmail.com \
    --to=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.