aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libutil/compression.cc25
-rw-r--r--tests/unit/libutil/compression.cc10
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
* --------------------------------------------------------------------------*/