Commit 7b02f2d1 for libheif

commit 7b02f2d1c88298dc6b78d4bbff9c55a85986d88b
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Thu Jan 1 01:31:49 2026 +0100

    rewrite zlib decompression loop (#1656)

diff --git a/libheif/compression_zlib.cc b/libheif/compression_zlib.cc
index e76fbf33..c712cae3 100644
--- a/libheif/compression_zlib.cc
+++ b/libheif/compression_zlib.cc
@@ -91,8 +91,8 @@ Result<std::vector<uint8_t>> do_inflate(const std::vector<uint8_t>& compressed_i

   // decompress data with zlib

-  const int outBufferSize = 8192;
-  uint8_t dst[outBufferSize];
+  std::vector<uint8_t> dst;
+  dst.resize(8192);

   z_stream strm;
   memset(&strm, 0, sizeof(z_stream));
@@ -100,8 +100,8 @@ Result<std::vector<uint8_t>> do_inflate(const std::vector<uint8_t>& compressed_i
   strm.avail_in = (int)compressed_input.size();
   strm.next_in = (Bytef*) compressed_input.data();

-  strm.avail_out = outBufferSize;
-  strm.next_out = (Bytef*) dst;
+  strm.avail_out = (uInt)dst.size();
+  strm.next_out = (Bytef*) dst.data();

   strm.zalloc = Z_NULL;
   strm.zfree = Z_NULL;
@@ -117,15 +117,25 @@ Result<std::vector<uint8_t>> do_inflate(const std::vector<uint8_t>& compressed_i
   }

   do {
-    strm.next_out = dst;
-    strm.avail_out = outBufferSize;
-
-    err = inflate(&strm, Z_FINISH);
-    if (err == Z_BUF_ERROR || err == Z_OK) {
-      // this is the usual case when we run out of buffer space
-      // -> do nothing
+    strm.avail_out = (uInt)dst.size();
+    strm.next_out = (Bytef*) dst.data();
+
+    err = inflate(&strm, Z_NO_FLUSH);
+
+    if (err == Z_BUF_ERROR) {
+      if (dst.size() >= 65536) { // TODO: make this a security limit
+        std::stringstream sstr;
+        sstr << "Error performing zlib inflate: maximum output buffer size exceeded\n";
+        return Error(heif_error_Memory_allocation_error, heif_suberror_Compression_initialisation_error, sstr.str());
+      }
+
+      dst.resize(dst.size() * 2);
+      strm.next_out = dst.data();
+      strm.avail_out = (uInt)dst.size();
+      continue;
     }
-    else if (err == Z_NEED_DICT || err == Z_DATA_ERROR || err == Z_STREAM_ERROR) {
+
+    if (err == Z_NEED_DICT || err == Z_DATA_ERROR || err == Z_STREAM_ERROR) {
       inflateEnd(&strm);
       std::stringstream sstr;
       sstr << "Error performing zlib inflate: " << (strm.msg ? strm.msg : "NULL") << " (" << err << ")\n";
@@ -133,7 +143,7 @@ Result<std::vector<uint8_t>> do_inflate(const std::vector<uint8_t>& compressed_i
     }

     // append decoded data to output
-    output.insert(output.end(), dst, dst + outBufferSize - strm.avail_out);
+    output.insert(output.end(), dst.begin(), dst.end() - strm.avail_out);
   } while (err != Z_STREAM_END);