rikyoz / bit7z

A C++ static library offering a clean and simple interface to the 7-zip shared libraries.
https://rikyoz.github.io/bit7z
Mozilla Public License 2.0
627 stars 114 forks source link

BitMemCompressor not working ? #17

Closed Itsukan0 closed 5 years ago

Itsukan0 commented 5 years ago

Hello and thanks for this library !

Describe the bug

I try to use MemCompressor to write a buffer into an archive, a buffer that I got while extracting a paint-made BMP that I packed into a 7z archive.

When I try to compress the buffer into an archive, I have a Bit Error, invalid arg exception at Update Items with an empty error message

To Reproduce

Steps to reproduce the behavior:

1) Tools initialisation : bit7z::Bit7zLibrary lib(L"7za.dll"); bit7z::BitMemCompressor memcompressor(lib, bit7z::BitFormat::SevenZip); bit7z::BitExtractor extractor(lib, bit7z::BitFormat::SevenZip);

2) Buffer extraction :

std::vector buffer; extractor.extract(L"D:/Travail_Hassim/bit7z/x64/Debug/LZMA2.7z", buffer);

3) Buffer compression ( Error happens here) :

memcompressor.compress(buffer, L"D:/Travail_Hassim/bit7z/x64/Debug/outputdir/testarchive.7z",L"TestArchive2");

Expected behavior

testarchive.7z to appear with the buffer data in it

Environment details (put an x in all the boxes that apply):

rikyoz commented 5 years ago

Hi! First of all, thanks for using bit7z and above all for the bug report! I've managed to replicate the bug and I think I found what the problem is, as well as how to fix it.

The problem Technically speaking, the bug is due to the fact that the UpdateItems function (from the dll) calls the method GetProperty of bit7z's MemUpdateCallback class in order to retrieve the kpidAttrib property of the input buffer. Since it is a buffer and not a file, GetProperty assigns the default constant FILE_ATTRIBUTE_NORMAL to the BitPropVariant object for that property: the value of this constant (0x00000080) is a signed 32-bit integer — i.e. an int, the default type for integer literals — and hence the type of the variant is set accordingly. However, UpdateItems requires an unsigned 32-bit integer variant for that property, otherwise it returns an invalid argument error, hence the bug.

The bug was mistakenly introduced in the latest stable version v3.0: the previous stable version v2.1 should not be affected by this bug, since it didn't use a custom variant class (e.g. BitPropVariant).

Solution Casting the constant to uint32_t should fix the bug, i.e. changing the code at line 116 of MemUpdateCallback.cpp (https://github.com/rikyoz/bit7z/blob/master/src/memupdatecallback.cpp#L116) as follows:

prop = static_cast< uint32_t >( FILE_ATTRIBUTE_NORMAL );

Asap I'll probably publish a hotfix release in order to solve this, maybe a v3.0.1 version. Thank you again for having reported the bug!

Itsukan0 commented 5 years ago

It seems to fix the problem indeed, thanks for the insight !

rikyoz commented 5 years ago

You're welcome!