Skip to content

Commit ea6f0a2

Browse files
committed
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 <[email protected]>
1 parent a1cdc25 commit ea6f0a2

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

builtin/fsck.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -392,28 +392,34 @@ static void add_sha1_list(unsigned char *sha1, unsigned long ino)
392392
sha1_list.nr = ++nr;
393393
}
394394

395+
static inline int is_loose_object_file(struct dirent *de,
396+
char *name, unsigned char *sha1)
397+
{
398+
if (strlen(de->d_name) != 38)
399+
return 0;
400+
memcpy(name + 2, de->d_name, 39);
401+
return !get_sha1_hex(name, sha1);
402+
}
403+
395404
static void fsck_dir(int i, char *path)
396405
{
397406
DIR *dir = opendir(path);
398407
struct dirent *de;
408+
char name[100];
399409

400410
if (!dir)
401411
return;
402412

403413
if (verbose)
404414
fprintf(stderr, "Checking directory %s\n", path);
405415

416+
sprintf(name, "%02x", i);
406417
while ((de = readdir(dir)) != NULL) {
407-
char name[100];
408418
unsigned char sha1[20];
409419

410420
if (is_dot_or_dotdot(de->d_name))
411421
continue;
412-
if (strlen(de->d_name) == 38) {
413-
sprintf(name, "%02x", i);
414-
memcpy(name+2, de->d_name, 39);
415-
if (get_sha1_hex(name, sha1) < 0)
416-
break;
422+
if (is_loose_object_file(de, name, sha1)) {
417423
add_sha1_list(sha1, DIRENT_SORT_HINT(de));
418424
continue;
419425
}

0 commit comments

Comments
 (0)