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
634 stars 116 forks source link

[Bug]: BIT7Z_AUTO_FORMAT is fail #134

Closed psvajaz closed 1 year ago

psvajaz commented 1 year ago

bit7z version

4.0.x RC

Compilation options

BIT7Z_AUTO_FORMAT, BIT7Z_AUTO_PREFIX_LONG_PATHS

7-zip version

v22.01

7-zip shared library used

7z.dll / 7z.so

Compilers

MSVC

Compiler versions

MSVC2017

Architecture

x86

Operating system

Windows

Operating system versions

Windows 11

Bug description

Usage scenario: Modify the 7z compressed package suffix to. rar and open the file. Use BitArchiveReader arc {lib, filename, BitFormat:: Auto, mSPassword}; When obtaining the file, posixCode: 15 will appear Error Message: Failed to detect the format of the file: No known signature found.

After reading the source code, it was found that the file suffix name should be determined first. If the determination is successful, detectFormatFromSig will not be run for file configuration determination, which may cause compressed files to not open properly

Steps to reproduce

No response

Expected behavior

No response

Relevant compilation output

No response

Code of Conduct

rikyoz commented 1 year ago

Hi! Thanks for reporting the bug!

After reading the source code, it was found that the file suffix name should be determined first. If the determination is successful, detectFormatFromSig will not be run for file configuration determination, which may cause compressed files to not open properly

I replicated your usage scenario, and indeed bit7z fails to detect the format. However, the problem is not that detectFormatFromSig is not called.

The BitInputArchive::openArchiveStream method takes into account precisely the case where a format was detected from the extension, but we could not open the archive:

HRESULT res = in_archive->Open( in_stream, nullptr, open_callback );

if ( res != S_OK && mArchiveHandler.format() == BitFormat::Auto && !detected_by_signature ) {
    /* ... */
    mDetectedFormat = &( detectFormatFromSig( in_stream ) );
    ...
}

The actual problem is that, in some cases, the call to Open might change the state of the underlying file stream so that when detectFormatFromSig tries to read the file signature, it fails, hence the format detection error. I've pushed a commit to the develop branch that fixes this issue.

Thank you again! :pray:

rikyoz commented 1 year ago

Fixed in v4.0.0.