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

[PATCH 2/6] rerere: check dirname format while iterating rr_cache directory

From
Jeff King <peff@peff.net>
Date
Jan 28, 2021, 06:14 UTC
Message-ID
<YBJWM0v/D6afqBLI@coredump.intra.peff.net>
In-Reply-To
<YBJVuckmbGriVa//@coredump.intra.peff.net>

In rerere_gc(), we walk over the .git/rr_cache directory and create a struct for each entry we find. We feed any name we get from readdir() to find_rerere_dir(), which then calls get_sha1_hex() on it (since we use the binary hash as a lookup key). If that fails (i.e., the directory name is not what we expected), it returns NULL. But the comment in find_rerere_dir() says "BUG".

It _would_ be a bug for the call from new_rerere_id_hex(), the only other code path, to fail here; it's generating the hex internally. But the call in rerere_gc() is using it say "is this a plausible directory name".

Let's instead have rerere_gc() do its own "is this plausible" check. That has two benefits:

  - we can now reliably BUG() inside find_rerere_dir(), which would
    catch bugs in the other code path (and we now will never return NULL
    from the function, which makes it easier to see that a rerere_id
    struct will always have a non-NULL "collection" field).
  - it makes the use of the binary hash an implementation detail of
    find_rerere_dir(), not known by callers. That will free us up to
    change it in a future patch.
Signed-off-by: Jeff King <peff@peff.net>
---
Obviously I have an ulterior motive here, but mostly this just seemed
to make the code clearer to me. The separation of concerns might also
help if we did something more exotic with rerere conflict hashes (which
just use the_hash_algo now, but really don't have to).
 rerere.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/rerere.c b/rerere.c
index d6928c1b5c..7b0c262ac6 100644
--- a/rerere.c
+++ b/rerere.c
@@ -146,7 +146,7 @@ static struct rerere_dir *find_rerere_dir(const char *hex)
 	int pos;
 
 	if (get_sha1_hex(hex, hash))
-		return NULL; /* BUG */
+		BUG("cannot parse rerere dir hex?");
 	pos = hash_pos(hash, rerere_dir, rerere_dir_nr, rerere_dir_hash);
 	if (pos < 0) {
 		rr_dir = xmalloc(sizeof(*rr_dir));
@@ -1178,6 +1178,13 @@ static void prune_one(struct rerere_id *id,
 		unlink_rr_item(id);
 }
 
+/* Does the basename in "path" look plausibly like an rr-cache entry? */
+static int is_rr_cache_dirname(const char *path)
+{
+	unsigned char hash[GIT_MAX_RAWSZ];
+	return !get_sha1_hex(path, hash);
+}
+
 void rerere_gc(struct repository *r, struct string_list *rr)
 {
 	struct string_list to_remove = STRING_LIST_INIT_DUP;
@@ -1205,10 +1212,11 @@ void rerere_gc(struct repository *r, struct string_list *rr)
 
 		if (is_dot_or_dotdot(e->d_name))
 			continue;
-		rr_dir = find_rerere_dir(e->d_name);
-		if (!rr_dir)
+		if (!is_rr_cache_dirname(e->d_name))
 			continue; /* or should we remove e->d_name? */
 
+		rr_dir = find_rerere_dir(e->d_name);
+
 		now_empty = 1;
 		for (id.variant = 0, id.collection = rr_dir;
 		     id.variant < id.collection->status_nr;
-- 
2.30.0.758.gfe500d6872
Previous: Derrick StoleeNext: Jeff King
Message 4 of 15 in “convert hash_pos() to oid_pos()”
  1. 0/6 convert hash_pos() to oid_pos()Jeff King, Jan 28, 2021
  2. 1/6 commit_graft_pos(): take an oid instead of a bare hashJeff King, Jan 28, 2021
  3. Derrick StoleeJan 28, 2021
  4. 2/6 rerere: check dirname format while iterating rr_cache directoryJeff King, Jan 28, 2021
  5. 3/6 rerere: tighten rr-cache dirname checkJeff King, Jan 28, 2021
  6. Taylor BlauJan 28, 2021
  7. Jeff KingJan 28, 2021
  8. Jeff KingJan 28, 2021
  9. Junio C HamanoJan 28, 2021
  10. Junio C HamanoJan 28, 2021
  11. Jeff KingJan 28, 2021
  12. 5/6 hash_pos(): convert to oid_pos()Jeff King, Jan 28, 2021
  13. Taylor BlauJan 28, 2021
  14. Jeff KingJan 29, 2021
  15. 6/6 oid_pos(): access table through const pointersJeff King, Jan 28, 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.