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]: Unsigned number overflow #112

Closed liugantang closed 1 year ago

liugantang commented 1 year ago

bit7z version

4.0.x beta

7-zip version

v21.07

7-zip DLL used

7z.dll

MSVC version

2019

Architecture

x86

Which version of Windows are you using?

Windows 10

Bug description

I recently discovered that some times a large amount of data is still written to the file stream after compression is complete. After studying the source code, I found that CStdOutStream::SetSize( UInt64 newSize ) is the cause of this problem.

const auto diff_pos = newSize - static_cast< uint64_t >( mOutputStream.tellp() );
    if ( diff_pos > 0 ) {
        std::fill_n( std::ostream_iterator< char >( mOutputStream ), diff_pos, '\0' );
    }

if newSize < static_cast< uint64_t >( mOutputStream.tellp() ), diff_pos will be a huge number. The huge amount of data is then continuously written to the file stream by std::fill_n. It's not clear to me why mOutputStream.tellp() would be a larger number than newSize.

Steps to reproduce

No response

Expected behavior

No response

Relevant compilation output

No response

Code of Conduct

rikyoz commented 1 year ago

Hi! Thank you for reporting this bug!

It's not clear to me why mOutputStream.tellp() would be a larger number than newSize.

It's not clear to me, either. It's really strange, and I never encountered such a problem until now. I suppose that, for some reason, 7-zip wanted to shrink the file size.

Please, could you provide me some more information, e.g., the archive format you used for the compression operation and the total size of the file(s) you were compressing? Thank you!

if newSize < static_cast< uint64_t >( mOutputStream.tellp() ), diff_pos will be a huge number. The huge amount of data is then continuously written to the file stream by std::fill_n.

Yeah, I'll probably have to implement a way to handle such cases.

Thank you again!

liugantang commented 1 year ago

请您提供更多信息,例如,您用于压缩操作的存档格式以及您正在压缩的文件的总大小?谢谢!

The file size is 94.3 MB, and this is my code:

bool progress(uint64_t val)
{
    std::cout << val << std::endl;
    return true;
}

int main()
{

    std::wstring srcPath = L"C:\\Users\\Administrator\\Downloads\\Oxford_English_Dictionary_2nd.tar.zip";
    std::wstring dstPath = L"C:\\Users\\Administrator\\Downloads\\test.zip";
    try {
        Bit7zLibrary lib;
        BitFileCompressor compressor(lib, BitFormat::Zip);
        compressor.setProgressCallback(progress);
        compressor.compressFile(srcPath, dstPath);

    }
    catch(BitException& ex){
        std::wcout << ex.what() << std::endl;
    }
    return 0;
}
rikyoz commented 1 year ago

Thank you for the details! I was able to replicate the issue you observed. I'm working on a fix, which I hope to push as soon as possible.

rikyoz commented 1 year ago

Hi! Just a quick update: I pushed a commit (e8eca9b) that should fix the issue. Let me know if you encounter any other issues!