Skip to content

Commit

Permalink
Make sorting by basename fully deterministic
Browse files Browse the repository at this point in the history
BasenameCompare() completely ignored leading directories.
While this is fine with respect to the zip files trrntzip creates,
the order of printed messages can differ when directory entries
get removed or re-zipping fails because of name clashes.

Compare the full paths of entries in case the basenames compare
equal to always ensure the same sort order and thus deterministic
output.

This should fix the flaky directories-2-d.test, so remove it from
XFAIL_TESTS on WIN32.
  • Loading branch information
miller-alex committed Apr 6, 2024
1 parent d7f05e7 commit d097c5a
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
1 change: 0 additions & 1 deletion regress/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ if(WIN32)
set(XFAIL_TESTS ${XFAIL_TESTS}
cli-q.test
cli-s.test
directories-2-d.test
recurse.test
recursive.test
)
Expand Down
10 changes: 8 additions & 2 deletions src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,19 @@ int StringCompare(const void *str1, const void *str2) {
return CanonicalCmp(p1, p2);
}

// No tie-breaker for leading dirs required, names must be unique
int BasenameCompare(const void *str1, const void *str2) {
const char *p1 = *(const char **)str1;
const char *p2 = *(const char **)str2;
const char *b1 = strrchr(p1, '/');
const char *b2 = strrchr(p2, '/');
return CanonicalCmp(b1 ? b1 + 1 : p1, b2 ? b2 + 1 : p2);
int res = CanonicalCmp(b1 ? b1 + 1 : p1, b2 ? b2 + 1 : p2);

// Tie-breaker ensures deterministic output. (It isn't needed for correct
// operation since names of added members must be unique.)
if (!res && b1 && b2)
res = CanonicalCmp(p1, p2);

return res;
}

int EndsWithCaseInsensitive(const char *str, const char *tail) {
Expand Down

0 comments on commit d097c5a

Please sign in to comment.