What happens
Windows drops a trailing dot or space, and NameRules::rewrite applies that adjustment itself so the name on disk matches what the report promised. When the adjustment consumes the entire component there is nothing left, and the entry is refused as Unnameable.
plan_names runs rewrite_entry over every name in the listing, so one such entry aborts the whole plan and extract_with returns before a single byte is written. The rest of the archive is unreachable.
Reproduction
rewrite_entry("...") = Err(... "..." becomes "", which is not a name this system can hold)
rewrite_entry(" ") = Err(... " " becomes "", which is not a name this system can hold)
rewrite_entry("docs/.../f.txt") = Err(... "..." becomes "", which is not a name this system can hold)
The third is the one that stings: f.txt is a perfectly ordinary file, and it cannot be extracted because of the directory above it.
Why it is different from the refusals we do want
The other refusals are questions. A character the host cannot write is something the user can answer with a substitution, and the dialog exists to collect that answer. This one has no character to substitute: TrailingCharacters is documented as an adjustment applied without asking, precisely because there is nothing to ask. So the user is shown a refusal they cannot act on, for an archive that is not malformed and that Unix extracts without comment.
Options worth weighing
- Give a name that empties out a fallback rather than refusing it, in the same spirit as
DEVICE_SUFFIX for a reserved device. It has the same property: an adjustment nobody can be asked about, stated in the report rather than negotiated.
- Or keep the refusal but scope it to the entry rather than the archive, so the other entries still extract and the listing says which one was skipped. That is a bigger change, since "nothing was written" is currently a guarantee.
The first is small and consistent with what the module already does for devices.
Found while auditing the Windows CI failure that led to #88.
What happens
Windows drops a trailing dot or space, and
NameRules::rewriteapplies that adjustment itself so the name on disk matches what the report promised. When the adjustment consumes the entire component there is nothing left, and the entry is refused asUnnameable.plan_namesrunsrewrite_entryover every name in the listing, so one such entry aborts the whole plan andextract_withreturns before a single byte is written. The rest of the archive is unreachable.Reproduction
The third is the one that stings:
f.txtis a perfectly ordinary file, and it cannot be extracted because of the directory above it.Why it is different from the refusals we do want
The other refusals are questions. A character the host cannot write is something the user can answer with a substitution, and the dialog exists to collect that answer. This one has no character to substitute:
TrailingCharactersis documented as an adjustment applied without asking, precisely because there is nothing to ask. So the user is shown a refusal they cannot act on, for an archive that is not malformed and that Unix extracts without comment.Options worth weighing
DEVICE_SUFFIXfor a reserved device. It has the same property: an adjustment nobody can be asked about, stated in the report rather than negotiated.The first is small and consistent with what the module already does for devices.
Found while auditing the Windows CI failure that led to #88.