Hello
The program below decompresses a
std::string using Boost.IOStream. The target is an array sink of fixed size.
The users know the decompressed size in advance but for security reasons I need to check the number of bytes written to the sink.
If the array is too small, a "write area exhausted" exception is thrown, which is fine.
If the array is too big, decompression succeeds. I would like to check the number of bytes written to the sink and throw an exception.
How can I determine how many bytes have been written to the sink?
Btw: I cannot use the “counter” filter because of the overhead involved in line counting and because the return value of its
characters() method is “int”. The buffers involved in my application require a 64 bit data type.
Private base class
basic_zlib_decompressor of class
basic_gzip_decompressor has method total_out() which seems to return the value in question but its return type is also only an “int”.
Regards, Peter.
#include <iostream>
#include <stdexcept>
#include <iomanip>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/filter/gzip.hpp>
void decompress(const
std::size_t
p_bufferSize)
{
// decompressed string is "xy"
const
std::string s("\x1f\x8b\x08\x08\x58\xce\xf6\x5b\x02\x03\x78\x79\x00\xab\xa8\x04\x00\x99\x28\xe6\x8f\x02\x00\x00\x00",25);
boost::iostreams::filtering_streambuf<boost::iostreams::output>
filteringStreambuf;
filteringStreambuf.push(boost::iostreams::gzip_decompressor());
const
std::unique_ptr<char[]> buffer=std::make_unique<char[]>(p_bufferSize);
filteringStreambuf.push(boost::iostreams::array_sink(buffer.get(),p_bufferSize));
boost::iostreams::write(filteringStreambuf,s.c_str(),s.size());
boost::iostreams::close(filteringStreambuf);
}
int main()
{
try
{
decompress(3); // works, although only 2 bytes are required, should be made to fail
//decompress(2); // works, exactly fills the buffer
//decompress(1); // throws exception "write area exhausted" as expected
return 0;
}
catch (const
std::exception& e) {
std::cout <<
e.what() <<
std::endl;
}
return 1;
}