Am 19.05.20 um 14:11 schrieb Derrick Stolee: > On 5/15/2020 1:22 PM, Derrick Stolee wrote: >> René Scharfe 9068cfb2 fsck: report non-consecutive duplicate names in trees >> fsck.c >> 9068cfb2 623) break; >> 9068cfb2 626) if (is_less_than_slash(*p)) { >> 9068cfb2 627) name_stack_push(candidates, f_name); >> 9068cfb2 628) break; >> 9068cfb2 630) } > > These are different conditions in verify_ordered() to check the > special case of blobs and trees having the "same" name (but > sorted differently due to appending '/' to trees before sorting). > > There is another name_stack_push() that _is_ covered. I wonder > what case would trigger this push? Our test has one entry between the conflicting two: x x.1 x/ The branch is necessary if the check of a candidate tree consumes a candidate file from the stack that we need to check against later candidate trees, e.g.: x x.1.2 x.1/ x/ Let's check each in sequence: 1. "x" is a candidate file because the next entry starts with "x" + less-than-slash, so "x/" can still follow. We push it onto the stack. 2. "x.1.2" is not a candidate. A hypothetical "x.1.2/" would come before "x.1/", so we can be sure we don't have it. 3. "x.1/" is a candidate tree because it follows an entry that starts with "x.1" + less-than-slash, so we could have seen a file named "x.1" earlier. We pop "x" from the stack and see that it doesn't match, but is a prefix. "x.1/" is "x" + less-than-slash, so "x/" can still follow. We push it back onto the stack. And that's the branch in question. 4. "x/" is a candidate tree because it follows an entry that starts with "x" + less-than-slash, so we could have seen a file named "x" earlier. We pop "x" from the stack, and have a match. But here's one that slips by fsck and the test coverage check: x x.1 x.1.2 x/ This duplicate is not caught by the current code. Both "x" and "x.1" are candidate files. "x.1.2" is not a candidate. "x/" is checked against "x.1" from the top of the stack, found not to be a prefix and the search ends at that point, unsuccessfully. I think we need this to fix it: diff --git a/fsck.c b/fsck.c index 8bb3ecf282..594e800015 100644 --- a/fsck.c +++ b/fsck.c @@ -620,7 +620,7 @@ static int verify_ordered(unsigned mode1, const char *name1, if (!f_name) break; if (!skip_prefix(name2, f_name, &p)) - break; + continue; if (!*p) return TREE_HAS_DUPS; if (is_less_than_slash(*p)) {