git-fsck-cache: be stricter about "tree" objects

In particular, warn about things like zero-padding of the mode bits,
which is a big no-no, since it makes otherwise identical trees have
different representations (and thus different SHA1 numbers).

Also make the warnings more regular.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Linus Torvalds 2005-07-27 16:08:43 -07:00 committed by Junio C Hamano
parent 4e81304afc
commit 64071805ed
3 changed files with 37 additions and 12 deletions

View File

@ -109,13 +109,19 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
static int fsck_tree(struct tree *item) static int fsck_tree(struct tree *item)
{ {
int retval;
int has_full_path = 0; int has_full_path = 0;
int has_zero_pad = 0;
int has_bad_modes = 0;
int has_dup_entries = 0;
int not_properly_sorted = 0;
struct tree_entry_list *entry, *last; struct tree_entry_list *entry, *last;
last = NULL; last = NULL;
for (entry = item->entries; entry; entry = entry->next) { for (entry = item->entries; entry; entry = entry->next) {
if (strchr(entry->name, '/')) if (strchr(entry->name, '/'))
has_full_path = 1; has_full_path = 1;
has_zero_pad |= entry->zeropad;
switch (entry->mode) { switch (entry->mode) {
/* /*
@ -135,22 +141,17 @@ static int fsck_tree(struct tree *item)
if (!check_strict) if (!check_strict)
break; break;
default: default:
printf("tree %s has entry %o %s\n", has_bad_modes = 1;
sha1_to_hex(item->object.sha1),
entry->mode, entry->name);
} }
if (last) { if (last) {
switch (verify_ordered(last, entry)) { switch (verify_ordered(last, entry)) {
case TREE_UNORDERED: case TREE_UNORDERED:
fprintf(stderr, "tree %s not ordered\n", not_properly_sorted = 1;
sha1_to_hex(item->object.sha1)); break;
return -1;
case TREE_HAS_DUPS: case TREE_HAS_DUPS:
fprintf(stderr, "tree %s has duplicate entries for '%s'\n", has_dup_entries = 1;
sha1_to_hex(item->object.sha1), break;
entry->name);
return -1;
default: default:
break; break;
} }
@ -159,13 +160,35 @@ static int fsck_tree(struct tree *item)
last = entry; last = entry;
} }
retval = 0;
if (has_full_path) { if (has_full_path) {
fprintf(stderr, "warning: git-fsck-cache: tree %s " fprintf(stderr, "warning: git-fsck-cache: tree %s "
"has full pathnames in it\n", "has full pathnames in it\n",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));
} }
if (has_zero_pad) {
return 0; fprintf(stderr, "warning: git-fsck-cache: tree %s "
"has zero-padded file modes in it\n",
sha1_to_hex(item->object.sha1));
}
if (has_bad_modes) {
fprintf(stderr, "warning: git-fsck-cache: tree %s "
"has bad file modes in it\n",
sha1_to_hex(item->object.sha1));
}
if (has_dup_entries) {
fprintf(stderr, "error: git-fsck-cache: tree %s "
"has duplicate file entries\n",
sha1_to_hex(item->object.sha1));
retval = -1;
}
if (not_properly_sorted) {
fprintf(stderr, "error: git-fsck-cache: tree %s "
"is not properly sorted\n",
sha1_to_hex(item->object.sha1));
retval = -1;
}
return retval;
} }
static int fsck_commit(struct commit *commit) static int fsck_commit(struct commit *commit)

1
tree.c
View File

@ -167,6 +167,7 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
entry->directory = S_ISDIR(mode) != 0; entry->directory = S_ISDIR(mode) != 0;
entry->executable = (mode & S_IXUSR) != 0; entry->executable = (mode & S_IXUSR) != 0;
entry->symlink = S_ISLNK(mode) != 0; entry->symlink = S_ISLNK(mode) != 0;
entry->zeropad = *(char *)bufptr == '0';
entry->mode = mode; entry->mode = mode;
entry->next = NULL; entry->next = NULL;

1
tree.h
View File

@ -10,6 +10,7 @@ struct tree_entry_list {
unsigned directory : 1; unsigned directory : 1;
unsigned executable : 1; unsigned executable : 1;
unsigned symlink : 1; unsigned symlink : 1;
unsigned zeropad : 1;
unsigned int mode; unsigned int mode;
char *name; char *name;
union { union {