Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed: Incorrect ZStandard API Usage for Partial Decompression of Blocks #13

Merged
merged 4 commits into from
Sep 26, 2023

Conversation

Sewer56
Copy link
Member

@Sewer56 Sewer56 commented Sep 26, 2023

Changes the code to correct the error handling for: ZSTD_decompressStream in rare case of partial block decompression.

While the original code is correct, for the cases of decompressing entire blocks; it's not valid for the case of partial decompression; because the result of ZSTD_decompressStream can return a non-error positive value that's used as a 'hint' for the next call to ZSTD_decompressStream.

Previously we checked the result against 0, which is only true if the entire input has been decompressed; but in the case of partial decompression, this cannot be true.

Some Background Info

This is actually caused by an oversight during optimization, not a bug.

Originally during development it used to not be possible to partial decompress chunks; so the original code was not an issue.

However down the road, I added the canFastDecompress optimization to ExtractBlock for extracting files which start at offset 0 and only have 1 output. Originally this was intended as a hot path for chunked file blocks; however due to the constraints, this optimization was also valid for first item in SOLID blocks.

In that specific edge case, partial decompression of blocks was now possible, and the existing code using the ZStandard API did not handle it correctly. (The existing code was correct, just not for partial extraction)


After merging, create release 0.3.7 (only need to push tag) and update the NuGet package in following PR

Changes the code to correct the error handling for: ZSTD_decompressStream

While the original code is correct, for the cases of decompressing entire blocks; it's not valid for the case of partial decompression; because the result of ZSTD_decompressStream can return a non-error positive value that's used as a 'hint' for the next call to `ZSTD_decompressStream`. 

Previously we checked the result against 0, which is only true if the entire input has been decompressed; but in the case of partial decompression, this cannot be true.
@Sewer56 Sewer56 added the meta-bug Something isn't working label Sep 26, 2023
@Sewer56 Sewer56 requested a review from a team September 26, 2023 02:31
@Sewer56 Sewer56 self-assigned this Sep 26, 2023
Copy link
Contributor

@halgari halgari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, makes sense

@halgari
Copy link
Contributor

halgari commented Sep 26, 2023

Is this ready to merge then?

@Sewer56
Copy link
Member Author

Sewer56 commented Sep 26, 2023

Yeah this can be merged, I can do the unit test that catches this in another PR. (I'm writing said test right now)

@Sewer56
Copy link
Member Author

Sewer56 commented Sep 26, 2023

This probably fixes

Which I couldn't originally reproduce.

@codecov-commenter
Copy link

Codecov Report

Attention: 5 lines in your changes are missing coverage. Please review.

Files Coverage Δ
NexusMods.Archives.Nx/Utilities/Compression.cs 69.44% <44.44%> (+2.77%) ⬆️

... and 1 file with indirect coverage changes

📢 Thoughts on this report? Let us know!.

@halgari halgari merged commit d692b57 into main Sep 26, 2023
13 checks passed
@halgari halgari deleted the fix-zstd-api-usage branch September 26, 2023 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
meta-bug Something isn't working
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants