From ea6f0a23ac63b3a19202db5441704e3d79236ad4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Jan 2011 13:01:54 -0800 Subject: [PATCH] fsck: do not give up too early in fsck_dir() When there is a random garbage file whose name happens to be 38-byte long in a .git/objects/??/ directory, the loop terminated prematurely without marking all the other files that it hasn't checked in the readdir() loop. Treat such a file just like any other garbage file, and do not break out of the readdir() loop. While at it, replace repeated sprintf() calls to a single one outside the loop. Signed-off-by: Junio C Hamano --- builtin/fsck.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index 91409a006..795aba087 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -392,10 +392,20 @@ static void add_sha1_list(unsigned char *sha1, unsigned long ino) sha1_list.nr = ++nr; } +static inline int is_loose_object_file(struct dirent *de, + char *name, unsigned char *sha1) +{ + if (strlen(de->d_name) != 38) + return 0; + memcpy(name + 2, de->d_name, 39); + return !get_sha1_hex(name, sha1); +} + static void fsck_dir(int i, char *path) { DIR *dir = opendir(path); struct dirent *de; + char name[100]; if (!dir) return; @@ -403,17 +413,13 @@ static void fsck_dir(int i, char *path) if (verbose) fprintf(stderr, "Checking directory %s\n", path); + sprintf(name, "%02x", i); while ((de = readdir(dir)) != NULL) { - char name[100]; unsigned char sha1[20]; if (is_dot_or_dotdot(de->d_name)) continue; - if (strlen(de->d_name) == 38) { - sprintf(name, "%02x", i); - memcpy(name+2, de->d_name, 39); - if (get_sha1_hex(name, sha1) < 0) - break; + if (is_loose_object_file(de, name, sha1)) { add_sha1_list(sha1, DIRENT_SORT_HINT(de)); continue; } -- 2.30.2