-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
[Bug] hex::dec::lzma_decompress
reports an error when decompressing a small buffer
#2033
Comments
Thanks for investigating! Yeah I think I didn't understand the API correctly. |
As discussed in WerWolv#2033, we should limit the memory usage to a reasonably sane value (1GiB here), rather than always increasing it when exceeded. We also print a warning to the console in this case. This also avoided the bug when decompressing a small buffer.
As discussed in WerWolv#2033, we should limit the memory usage to a reasonably sane value (1GiB here), rather than always increasing it when exceeded. We also print a warning to the console in this case. This also avoided the bug when decompressing a small buffer.
I was the person who fixed the fact that it was impossible to decompress any file using the previous code. As reported in the PR the problem was caused by not calling lzma_memusage() to adjust the limit using the value returned. That eliminated the error and now lzma implementation is able to decompress any size input. However there is a minimum size file imposed to 100 bytes which in practice makes sense because below 100 bytes the resulting 'compressed' file is actually bigger. LZMA_STREAM_END is an indicator that your compressed file is bigger then the original. If you decompress a real lzma compressed file you will see the the code returns true and the file will have the correct size, so setting the limit to 1 Gb is not only unnecessary, but will limit the files that can be decompressed just so you can decompress files that should not have been compressed to begin with. How is that an improvement? |
<!-- Please provide as much information as possible about what your PR aims to do. PRs with no description will most likely be closed until more information is provided. If you're planing on changing fundamental behaviour or add big new features, please open a GitHub Issue first before starting to work on it. If it's not something big and you still want to contact us about it, feel free to do so ! --> ### Problem description <!-- Describe the bug that you fixed/feature request that you implemented, or link to an existing issue describing it --> See #2033 (`hex::dec::lzma_decompress` reports an error when decompressing a small buffer). ### Implementation description <!-- Explain what you did to correct the problem --> Set the LZMA decompressor memory limit to 1GiB fixed. Print a warning when exceeded, and abort with returning `false`. ### Screenshots <!-- If your change is visual, take a screenshot showing it. Ideally, make before/after sceenshots --> Normal result when decompressing a small buffer ![image](https://github.com/user-attachments/assets/5b9e6b07-464e-41f6-bdc7-f5b1cd351069) Warning message when `memlimit` is exceeded: (Set to 64B here for a demo) > W: lzma_decompress memory usage 1114168 bytes would exceed the limit (64 bytes), aborting ![image](https://github.com/user-attachments/assets/04abf3ef-1d29-4846-bb41-214695c7d09c) ### Additional things <!-- Anything else you would like to say --> Is the warning wording OK? I'm not a native English speaker so please change it if you want to.
Operating System
Windows
What's the issue you encountered?
When decompressing a short lzma-compressed buffer,
hex::dec::lzma_decompress
reports an error, but the data is written to the section with an incorrect size of 100 bytes.How can the issue be reproduced?
xz
compressed file with the following Python code:The hexdump of the result
123.xz
file is:ok=false
is printed to the console. There is a "decompressed" section of 100 bytes, of which the first 3 bytes are31 32 33
("123") and others00
.The expected result should be:
ok=true
, and the "decompressed" section contains only the first 3 bytes.ImHex Version
1.36.0
ImHex Build Type
Installation type
MSI
Additional context?
The corresponding code is here:
ImHex/plugins/decompress/source/content/pl_functions.cpp
Lines 151 to 204 in 6005af1
After some debugging, it seems like first
lzma_code()
returnsLZMA_MEMLIMIT_ERROR
(6), but after adjusting the limit, it returnsLZMA_STREAM_END
(1), and is incorrectly treated as an error.To fix this once and for all, noticing earlier at
lzma_auto_decoder()
ImHex/plugins/decompress/source/content/pl_functions.cpp
Line 158 in 6005af1
the decoding
memlimit
is set to0x10000
(64KiB) which is too small for any.xz
files. According toman xz
, common decompression memory requirements are between 1MiB and 65MiB.We are always increasing the memory limit anyways, so it shouldn't be set in the first place. According to the
liblzma
doc,UINT64_MAX
should be used to disable the limiter. In this way we don't have to process theLZMA_MEMLIMIT_ERROR
error.Or if we want to be safe, set it to something like 1GiB and treat
LZMA_MEMLIMIT_ERROR
as a real error.Which one do you prefer? I can write a PR for this.
The text was updated successfully, but these errors were encountered: