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

[PATCH 2/9] fsck_tree(): fix shadowed variable

From
Jeff King <peff@peff.net>
Date
May 1, 2021, 15:41 UTC
Message-ID
<YI12stO48egyiHjv@coredump.intra.peff.net>
In-Reply-To
<YI12hK4X/gfl3u29@coredump.intra.peff.net>

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.

Signed-off-by: Jeff King <peff@peff.net>
---
 fsck.c                     | 42 ++++++++++++++++++++------------------
 t/t7415-submodule-names.sh |  5 +++--
 2 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/fsck.c b/fsck.c
index f5ed6a2635..dd31ed1413 100644
--- a/fsck.c
+++ b/fsck.c
@@ -558,7 +558,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_id *tree_oid,
 		     const char *buffer, unsigned long size,
 		     struct fsck_options *options)
 {
@@ -579,7 +579,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, tree_oid, OBJ_TREE, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
 		return retval;
 	}
 
@@ -589,11 +589,11 @@ static int fsck_tree(const struct object_id *oid,
 	while (desc.size) {
 		unsigned short mode;
 		const char *name, *backslash;
-		const struct object_id *oid;
+		const struct object_id *entry_oid;
 
-		oid = tree_entry_extract(&desc, &name, &mode);
+		entry_oid = tree_entry_extract(&desc, &name, &mode);
 
-		has_null_sha1 |= is_null_oid(oid);
+		has_null_sha1 |= is_null_oid(entry_oid);
 		has_full_path |= !!strchr(name, '/');
 		has_empty_name |= !*name;
 		has_dot |= !strcmp(name, ".");
@@ -603,10 +603,11 @@ static int fsck_tree(const struct object_id *oid,
 
 		if (is_hfs_dotgitmodules(name) || is_ntfs_dotgitmodules(name)) {
 			if (!S_ISLNK(mode))
-				oidset_insert(&options->gitmodules_found, oid);
+				oidset_insert(&options->gitmodules_found,
+					      entry_oid);
 			else
 				retval += report(options,
-						 oid, OBJ_TREE,
+						 tree_oid, OBJ_TREE,
 						 FSCK_MSG_GITMODULES_SYMLINK,
 						 ".gitmodules is a symbolic link");
 		}
@@ -617,9 +618,10 @@ static int fsck_tree(const struct object_id *oid,
 				has_dotgit |= is_ntfs_dotgit(backslash);
 				if (is_ntfs_dotgitmodules(backslash)) {
 					if (!S_ISLNK(mode))
-						oidset_insert(&options->gitmodules_found, oid);
+						oidset_insert(&options->gitmodules_found,
+							      entry_oid);
 					else
-						retval += report(options, oid, OBJ_TREE,
+						retval += report(options, tree_oid, OBJ_TREE,
 								 FSCK_MSG_GITMODULES_SYMLINK,
 								 ".gitmodules is a symbolic link");
 				}
@@ -628,7 +630,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, tree_oid, OBJ_TREE, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
 			break;
 		}
 
@@ -676,25 +678,25 @@ 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, tree_oid, OBJ_TREE, 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, tree_oid, OBJ_TREE, 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, tree_oid, OBJ_TREE, FSCK_MSG_EMPTY_NAME, "contains empty pathname");
 	if (has_dot)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_HAS_DOT, "contains '.'");
+		retval += report(options, tree_oid, OBJ_TREE, FSCK_MSG_HAS_DOT, "contains '.'");
 	if (has_dotdot)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_HAS_DOTDOT, "contains '..'");
+		retval += report(options, tree_oid, OBJ_TREE, FSCK_MSG_HAS_DOTDOT, "contains '..'");
 	if (has_dotgit)
-		retval += report(options, oid, OBJ_TREE, FSCK_MSG_HAS_DOTGIT, "contains '.git'");
+		retval += report(options, tree_oid, OBJ_TREE, 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, tree_oid, OBJ_TREE, 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, tree_oid, OBJ_TREE, 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, tree_oid, OBJ_TREE, 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, tree_oid, OBJ_TREE, FSCK_MSG_TREE_NOT_SORTED, "not properly sorted");
 	return retval;
 }
 
diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh
index fef6561d80..6a8cf3f47b 100755
--- a/t/t7415-submodule-names.sh
+++ b/t/t7415-submodule-names.sh
@@ -148,12 +148,13 @@ test_expect_success 'fsck detects symlinked .gitmodules file' '
 		{
 			printf "100644 blob $content\t$tricky\n" &&
 			printf "120000 blob $target\t.gitmodules\n"
-		} | git mktree &&
+		} >bad-tree &&
+		tree=$(git mktree <bad-tree) &&
 
 		# Check not only that we fail, but that it is due to the
 		# symlink detector
 		test_must_fail git fsck 2>output &&
-		grep gitmodulesSymlink output
+		grep "tree $tree: gitmodulesSymlink" output
 	)
 '
 
-- 
2.31.1.875.g5dccece0aa
Previous: Jeff KingNext: Ævar Arnfjörð Bjarmason
Message 5 of 35 in “leftover bits from symlinked gitattributes, etc topics”
  1. 0/9 leftover bits from symlinked gitattributes, etc topicsJeff King, May 1, 2021
  2. 1/9 t7415: remove out-dated comment about translationJeff King, May 1, 2021
  3. Ævar Arnfjörð BjarmasonMay 3, 2021
  4. Jeff KingMay 3, 2021
  5. 2/9 fsck_tree(): fix shadowed variableJeff King, May 1, 2021
  6. Ævar Arnfjörð BjarmasonMay 3, 2021
  7. Jeff KingMay 3, 2021
  8. Ævar Arnfjörð BjarmasonMay 4, 2021
  9. 3/9 fsck_tree(): wrap some long linesJeff King, May 1, 2021
  10. Ævar Arnfjörð BjarmasonMay 3, 2021
  11. Jeff KingMay 3, 2021
  12. 4/9 t7415: rename to expand scopeJeff King, May 1, 2021
  13. 5/9 t7450: test verify_path() handling of gitmodulesJeff King, May 1, 2021
  14. Eric SunshineMay 1, 2021
  15. Eric SunshineMay 1, 2021
  16. Jeff KingMay 3, 2021
  17. Ævar Arnfjörð BjarmasonMay 3, 2021
  18. Jeff KingMay 3, 2021
  19. 6/9 t7450: test .gitmodules symlink matching against obscured namesJeff King, May 1, 2021
  20. 7/9 t0060: test ntfs/hfs-obscured dotfilesJeff King, May 1, 2021
  21. 8/9 fsck: warn about symlinked dotfiles we'll open with O_NOFOLLOWJeff King, May 1, 2021
  22. 9/9 docs: document symlink restrictions for dot-filesJeff King, May 1, 2021
  23. Eric SunshineMay 1, 2021
  24. Jeff KingMay 3, 2021
  25. Junio C HamanoMay 3, 2021
  26. 0/9 leftover bits from symlinked gitattributes, etc topicsJeff King, May 3, 2021
  27. 1/9 t7415: remove out-dated comment about translationJeff King, May 3, 2021
  28. 2/9 fsck_tree(): fix shadowed variableJeff King, May 3, 2021
  29. 3/9 fsck_tree(): wrap some long linesJeff King, May 3, 2021
  30. 4/9 t7415: rename to expand scopeJeff King, May 3, 2021
  31. 5/9 t7450: test verify_path() handling of gitmodulesJeff King, May 3, 2021
  32. 6/9 t7450: test .gitmodules symlink matching against obscured namesJeff King, May 3, 2021
  33. 7/9 t0060: test ntfs/hfs-obscured dotfilesJeff King, May 3, 2021
  34. 8/9 fsck: warn about symlinked dotfiles we'll open with O_NOFOLLOWJeff King, May 3, 2021
  35. 9/9 docs: document symlink restrictions for dot-filesJeff King, May 3, 2021

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.