diff options
author | Ilya K <me@0upti.me> | 2024-06-20 07:06:52 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@localhost> | 2024-06-20 07:06:52 +0000 |
commit | 697ef65c148a48e5d8255b6425b6ca3a5b7d0be8 (patch) | |
tree | 1ec12c16162277fbcd4519a6cbd56bc0597031ab | |
parent | 6c29a2a6fc1043f2a0c17a6304a1624070ded2ed (diff) | |
parent | 7d52d74bbe39376f331887759020cff097dace55 (diff) |
Merge "BrotliDecompressionSource: don't bail out too early" into main
-rw-r--r-- | src/libutil/compression.cc | 25 | ||||
-rw-r--r-- | tests/unit/libutil/compression.cc | 10 |
2 files changed, 23 insertions, 12 deletions
diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc index d93a1b1d6..a66069e52 100644 --- a/src/libutil/compression.cc +++ b/src/libutil/compression.cc @@ -163,23 +163,24 @@ struct BrotliDecompressionSource : Source uint8_t * out = (uint8_t *) data; const auto * begin = out; - try { - while (len && !BrotliDecoderIsFinished(state.get())) { - checkInterrupt(); + while (len && !BrotliDecoderIsFinished(state.get())) { + checkInterrupt(); - while (avail_in == 0) { + while (avail_in == 0) { + try { avail_in = inner->read(buf.get(), BUF_SIZE); - next_in = (const uint8_t *) buf.get(); + } catch (EndOfFile &) { + break; } + 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"); - } + if (!BrotliDecoderDecompressStream( + state.get(), &avail_in, &next_in, &len, &out, nullptr + )) + { + throw CompressionError("error while decompressing brotli file"); } - } catch (EndOfFile &) { } if (begin != out) { diff --git a/tests/unit/libutil/compression.cc b/tests/unit/libutil/compression.cc index 0542e7d33..3b40db0cd 100644 --- a/tests/unit/libutil/compression.cc +++ b/tests/unit/libutil/compression.cc @@ -66,6 +66,16 @@ namespace nix { 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 * --------------------------------------------------------------------------*/ |