{{ message }}
Repository navigation
compare file names over their full length, including bytes after embedded NUL - #607
Open
ManoharPaturi wants to merge 1 commit into
Open
ManoharPaturi wants to merge 1 commit into
ManoharPaturi wants to merge 1 commit into
Conversation
Member
Contributor
Author
|
Understood — since the lookup API takes NUL-terminated C strings, a caller cannot express a name containing NUL, so the case only arises for archives produced by other writers. Happy to close this if you would rather handle it differently upstream, or leave it parked as a reference for the investigation; the regression test documents the current behavior either way. |
Member
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Problem
File names inside an archive are byte strings with an explicit length, and they may contain embedded NUL bytes. The name hash table treated them as C strings instead:
siphashhashed up to the first NUL, and lookups compared names withstrcmp. Two consequences for archives opened withoutZIP_CHECKCONS, which accepts such names since the NUL check in_zip_dirent_readonly runs when consistency is checked:zip_name_locatefound an entry nameda\0xwhen asked fora. The caller received data belonging to a different file than the name it asked for, which is a name confusion vector for applications that check for or extract specific entries by name from untrusted archives.ato an archive containinga\0xfailed withZIP_ER_EXISTS, since the duplicate check matched the truncated prefix.The same truncation existed in the fallback scan used with
ZIP_FL_NOCASEandZIP_FL_NODIR.Change
Names are now hashed and compared over their full raw length:
siphashtakes an explicit length instead of usingstrlen,memcmp,_zip_hash_add,_zip_hash_deleteand_zip_hash_lookuptake a length argument, and all callers pass the length reported by the string layer (_zip_string_get) or the length of the C string for user supplied names,_zip_name_locatecompares lengths and usesmemcmporstrncasecmp, with theZIP_FL_NODIRadjustment applied to the length as well.Since Windows has no
strncasecmp, it is detected and mapped to_strnicmp/strnicmpthe same waystrcasecmpalready is.Testing
The new regression test
hash_nul_nameopens an in memory archive holding two stored entries with the raw namesa\0xanda\0y. On unfixed code it fails in the first check withfound entry 0 for name "a", but no entry has that nameand exits 1. With this change it passes: no entry is found for the namea(with and withoutZIP_FL_NOCASE), a file namedacan be added without a false duplicate error, and the archive then holds three entries. The full suite, 194 tests, passes, as do the upstream workflows (Linux, macOS, Windows, BSD, Solaris).