Opened 10 years ago
Last modified 10 years ago
#8150 new Bugs
gzip_compressor produces corrupt data when used with filtering_ostream
Reported by: | Owned by: | Jonathan Turkanis | |
---|---|---|---|
Milestone: | To Be Determined | Component: | iostreams |
Version: | Boost 1.53.0 | Severity: | Regression |
Keywords: | Cc: |
Description
In some cases, the USE_CORRUPTING_OSTREAM path in the following program will produce corrupt gzip output (fails CRC and the de-gzipped file differs slightly from the original input). This does not occur for all data, so I will attach an input data file that triggers the error.
This bug only affects gzip_stream when used with filtering_ostream. It does not affect filtering_istream usage.
Bug reproduced on Mac 10.8.2, 64-bit, Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn), zlib 1.2.5 (dylib as shipped with Mac OS X), boost 1.53.0.
Bug does not appear to be affected by compiler optimizations (-O0 and -Os tested).
#include <iostream> #include <fstream> #include <vector> #include <boost/iostreams/filter/gzip.hpp> #include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/device/back_inserter.hpp> #include <boost/iostreams/copy.hpp> #include <boost/iostreams/device/array.hpp> #include <boost/iostreams/stream.hpp> #include <boost/iostreams/device/file_descriptor.hpp> int main(int argc, char *argv[]) { std::vector<char> input; std::vector<char> output; boost::iostreams::file_descriptor_source source("inputdata"); boost::iostreams::copy(source, boost::iostreams::back_inserter(input)); #define USE_CORRUPTING_OSTREAM 1 #if USE_CORRUPTING_OSTREAM boost::iostreams::filtering_ostream gzip_stream; gzip_stream.push(boost::iostreams::gzip_compressor()); gzip_stream.push(boost::iostreams::back_inserter(output)); gzip_stream.write(&input[0], input.size()); boost::iostreams::close(gzip_stream); #else boost::iostreams::filtering_istream gzip_stream; boost::iostreams::stream<boost::iostreams::array_source> input_array(&input[0], input.size()); gzip_stream.push(boost::iostreams::gzip_compressor()); gzip_stream.push(input_array); boost::iostreams::copy(gzip_stream, boost::iostreams::back_inserter(output)); #endif boost::iostreams::file_descriptor_sink destination("inputdata.gz"); destination.write(&output[0], output.size()); }
Attachments (1)
Change History (3)
by , 10 years ago
comment:1 by , 10 years ago
To be specific, when this inputdata file is run through the two different code paths, the only difference is that the USE_CORRUPTING_OSTREAM version is one byte shorter -- it is missing the 0xFF at byte 0x4000. Otherwise, the gzipped output is identical.
comment:2 by , 10 years ago
Further investigation has revealed that this is a bug in libcxx, not boost. The fix is here:
https://llvm.org/viewvc/llvm-project/libcxx/trunk/include/streambuf?annotate=165884
basically, the 0xff in the data was incorrectly passed by libcxx through to indirect_streambuf::overflow, causing it to be interpreted as an EOF (and rejected).
Please close this bug.
inputdata to be used with the program in the ticket to trigger the bug