使用 Boost Zlib 的解压缩在 Windows 崩溃

Decompression with Boost Zlib crashes on Windows

我在 Linux 上成功使用了以下代码,但它在 Windows 上的 boost::iostreams::copy() 处崩溃了。可能是什么原因?

#include <sstream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>

// 
bool is_compressed(const std::string &data) {
    return data.at(0) == 0x78 && (unsigned char) data.at(1) == 0xDA;
}

std::string compress(const std::string &plain_text) {
    boost::iostreams::filtering_streambuf<boost::iostreams::output> output_stream;
    const auto compression_level = boost::iostreams::zlib::best_compression;
    output_stream.push(boost::iostreams::zlib_compressor(compression_level));
    std::stringstream string_stream;
    output_stream.push(string_stream);
    boost::iostreams::copy(boost::iostreams::basic_array_source<char>(plain_text.c_str(),
                                                                      plain_text.size()), output_stream);
    return string_stream.str();
}

std::string decompress(const std::string &cipher_text) {
    std::stringstream string_stream;
    string_stream << cipher_text;
    boost::iostreams::filtering_streambuf<boost::iostreams::input> input_stream;
    input_stream.push(boost::iostreams::zlib_decompressor());

    input_stream.push(string_stream);
    std::stringstream unpacked_text;
    boost::iostreams::copy(input_stream, unpacked_text); // <-- Crashes here on Windows
    return unpacked_text.str();
}

异常:

Exception thrown at 0x00007FFF08A8A859 in my_project.exe: Microsoft C++ exception: boost::wrapexcept<boost::iostreams::zlib_error> at memory location 0x00000015E14FD440.
Exception thrown at 0x00007FFF08A8A859 in my_project.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.

我的 Boost 版本是 1.72.0

我尝试在主函数的顶部调用一个简单的 compress/decompress 示例,它成功了。但是,当使用更大的压缩缓冲区时,它仍然会以同样的方式崩溃。

This answer 不适用于我,因为我正在写入 std::stringstream 而不是输出文件。

几天后,我发现 Windows 行分隔符 0D 0A 被写入了 zlib 压缩文件,而不仅仅是 Linux 上的 0A ].这令人惊讶地导致解压崩溃。一个简单的修复是用 0A 替换所有 0D 0A 序列。请参阅 this 问题。不过,我不知道为什么这个 "hack" 是必要的。也许还有更优雅的方式?或者也许我的解决方案甚至不是万无一失的。随时 post 另一个答案。