sharanggupta opened a new pull request, #826:
URL: https://github.com/apache/commons-compress/pull/826

   [COMPRESS-639](https://issues.apache.org/jira/browse/COMPRESS-639)
   
   **What**
   
   `ZipArchiveOutputStream` keeps the local header offset of each entry in a 
`HashMap` keyed by the `ZipArchiveEntry`, and looks it up when it writes the 
central directory. `ZipArchiveEntry.hashCode()` only uses the name, but 
`equals(Object)` compares the times, sizes, CRC, extra fields and more, and 
some of these change while an entry is written. So entries with the same name, 
time, size and CRC, such as the entries that `ParallelScatterZipCreator` adds 
in the issue, can share one map entry:
   
   - If two entries are equal when they are written, the second `put` replaces 
the offset of the first, and both central directory records point to the second 
local file header. The archive silently loses the first entry.
   - If the extra fields of one entry change when the central directory is 
written, as they do with `Zip64Mode.Always`, the lookup of the other entry 
finds nothing, and `close()` throws the `NullPointerException` from the issue.
   
   **How**
   
   The map is now an `IdentityHashMap`. Each entry is put and looked up with 
the same `ZipArchiveEntry` instance, so every entry keeps its own offset, 
whatever `equals(Object)` says.
   
   **Tests**
   
   - `ParallelScatterZipCreatorTest.sameZipArchiveEntryNullPointerException`, 
which was disabled for COMPRESS-639, is enabled. It now also reads the archive 
back and checks that the 100 entries have 100 different local header offsets. 
It fails on `master` with the `NullPointerException`.
   - `ZipArchiveOutputStreamTest.testEqualEntriesKeepTheirOwnLocalHeaders` 
writes two equal `STORED` entries and checks with `ZipFile` that the first 
entry's local header is at offset 0 and the second one's right after the first 
entry's data. On `master`, both point to the second local header.
   
   `changes.xml` has an entry. `mvn` and `mvn changes:changes-validate 
-DfailOnError=true` pass locally on JDK 17.
   
   Before you push a pull request, review this list:
   
   - [x] Read the [contribution guidelines](CONTRIBUTING.md) for this project.
   - [x] Read the [ASF Generative Tooling 
Guidance](https://www.apache.org/legal/generative-tooling.html) if you use 
Artificial Intelligence (AI).
   - [x] I used AI to create any part of, or all of, this pull request. Which 
AI tool was used to create this pull request, and to what extent did it 
contribute? Claude (Anthropic) helped analyse the issue and draft the change 
and tests; I reviewed them against the code and ran the build.
   - [x] Run a successful build using the default 
[Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command 
line by itself.
   - [x] Write unit tests that match behavioral changes, where the tests fail 
if the changes to the runtime are not applied. This may not always be possible, 
but it is a best practice.
   - [x] Write a pull request description that is detailed enough to understand 
what the pull request does, how, and why.
   - [x] Each commit in the pull request should have a meaningful subject line 
and body. Note that a maintainer may squash commits during the merge process.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to