BrotliDecompressionSource: don't bail out too early
If we've consumed the entire input, that doesn't actually mean we're done decompressing - there might be more output left. This worked (?) in most cases because the input and output sizes are pretty comparable, but sometimes they're not and then things get very funny. Change-Id: I73435a654a911b8ce25119f713b80706c5783c1b
This commit is contained in:
parent
fb7d315411
commit
7d52d74bbe
2 changed files with 24 additions and 13 deletions
|
@ -163,23 +163,24 @@ struct BrotliDecompressionSource : Source
|
||||||
uint8_t * out = (uint8_t *) data;
|
uint8_t * out = (uint8_t *) data;
|
||||||
const auto * begin = out;
|
const auto * begin = out;
|
||||||
|
|
||||||
try {
|
while (len && !BrotliDecoderIsFinished(state.get())) {
|
||||||
while (len && !BrotliDecoderIsFinished(state.get())) {
|
checkInterrupt();
|
||||||
checkInterrupt();
|
|
||||||
|
|
||||||
while (avail_in == 0) {
|
while (avail_in == 0) {
|
||||||
|
try {
|
||||||
avail_in = inner->read(buf.get(), BUF_SIZE);
|
avail_in = inner->read(buf.get(), BUF_SIZE);
|
||||||
next_in = (const uint8_t *) buf.get();
|
} catch (EndOfFile &) {
|
||||||
}
|
break;
|
||||||
|
|
||||||
if (!BrotliDecoderDecompressStream(
|
|
||||||
state.get(), &avail_in, &next_in, &len, &out, nullptr
|
|
||||||
))
|
|
||||||
{
|
|
||||||
throw CompressionError("error while decompressing brotli file");
|
|
||||||
}
|
}
|
||||||
|
next_in = (const uint8_t *) buf.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BrotliDecoderDecompressStream(
|
||||||
|
state.get(), &avail_in, &next_in, &len, &out, nullptr
|
||||||
|
))
|
||||||
|
{
|
||||||
|
throw CompressionError("error while decompressing brotli file");
|
||||||
}
|
}
|
||||||
} catch (EndOfFile &) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (begin != out) {
|
if (begin != out) {
|
||||||
|
|
|
@ -66,6 +66,16 @@ namespace nix {
|
||||||
ASSERT_THROW(decompress(method, str), CompressionError);
|
ASSERT_THROW(decompress(method, str), CompressionError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(decompress, veryLongBrotli) {
|
||||||
|
auto method = "br";
|
||||||
|
auto str = std::string(65536, 'a');
|
||||||
|
auto o = decompress(method, compress(method, str));
|
||||||
|
|
||||||
|
// This is just to not print 64k of "a" for most failures
|
||||||
|
ASSERT_EQ(o.length(), str.length());
|
||||||
|
ASSERT_EQ(o, str);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* compression sinks
|
* compression sinks
|
||||||
* --------------------------------------------------------------------------*/
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in a new issue