Commit 4e9ba9ce for libheif

commit 4e9ba9ce26e8bab47404708fc508b0d814af6146
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Thu Dec 18 14:40:28 2025 +0100

    [BSD3] fix potential endless loop when trying to decode incomplete input data (#1640)

diff --git a/libheif/codecs/decoder.cc b/libheif/codecs/decoder.cc
index 967db5c7..48105a9d 100644
--- a/libheif/codecs/decoder.cc
+++ b/libheif/codecs/decoder.cc
@@ -430,7 +430,12 @@ Decoder::decode_single_frame_from_compressed_data(const heif_decoding_options& o

   flush_decoder();

-  for (;;) {
+  // We might have to try several times to get an image out of the decoder.
+  // However, we stop after a maximum number of tries because the decoder might not
+  // give any image when the input data is incomplete.
+  const int max_decoding_tries = 50; // hardcoded value, should be large enough
+
+  for (int i = 0; i < max_decoding_tries; i++) {
     Result<std::shared_ptr<HeifPixelImage>> imgResult;
     imgResult = get_decoded_frame(options, nullptr, limits);
     if (imgResult.error()) {
@@ -441,4 +446,12 @@ Decoder::decode_single_frame_from_compressed_data(const heif_decoding_options& o
       return imgResult;
     }
   }
+
+  // We did not receive and image from the decoder. We give up.
+
+  return Error{
+    heif_error_Decoder_plugin_error,
+    heif_suberror_Unspecified,
+    "Decoding the input data did not give a decompressed image."
+  };
 }
diff --git a/libheif/image-items/image_item.cc b/libheif/image-items/image_item.cc
index ce21e092..797df4ec 100644
--- a/libheif/image-items/image_item.cc
+++ b/libheif/image-items/image_item.cc
@@ -937,6 +937,18 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_compressed_image(const

   decoder->set_data_extent(std::move(extent));

+  // Check that we are pushing at least some data into the decoder.
+  // Some decoders (e.g. aom) do not complain when the input data is empty and we might
+  // get stuck in an endless decoding loop, waiting for the decompressed image.
+
+  if (extent.m_size == 0) {
+    return Error{
+      heif_error_Invalid_input,
+      heif_suberror_Unspecified,
+      "Input with empty data extent."
+    };
+  }
+
   return decoder->decode_single_frame_from_compressed_data(options,
                                                            get_context()->get_security_limits());
 }