Commit 4a5febca for libheif

commit 4a5febca612124e8798d766d558da4d046204673
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Fri May 15 16:15:40 2026 +0200

    pass security_limits through decoder plugin options (#1782)

diff --git a/libheif/api/libheif/heif_plugin.h b/libheif/api/libheif/heif_plugin.h
index 86074dea..90777b4c 100644
--- a/libheif/api/libheif/heif_plugin.h
+++ b/libheif/api/libheif/heif_plugin.h
@@ -45,8 +45,9 @@ extern "C" {
 //  1.15         3         3          2
 //  1.20         4         3          2
 //  1.21         5         4          2
+//  1.22         6         4          2

-#define heif_decoder_plugin_latest_version 5
+#define heif_decoder_plugin_latest_version 6
 #define heif_encoder_plugin_latest_version 4

 // The minimum plugin versions that can be used with this libheif version.
@@ -72,10 +73,16 @@ typedef struct heif_decoder_plugin_options
   int strict_decoding; // bool
   int num_threads; // 0 - undefined, use decoder default

+  // --- added in plugin_api_version 6 ---
+  // Security limits the plugin must enforce for image allocations during decoding.
+  // The pointee must outlive the decoder instance (typically the context's limits).
+  // Only read by plugins reporting plugin_api_version >= 6.
+  const heif_security_limits* limits;
+
 } heif_decoder_plugin_options;


-typedef struct heif_decoder_plugin
+typedef struct bheif_decoder_plugin
 {
   // API version supported by this plugin (see table above for supported versions)
   int plugin_api_version;
diff --git a/libheif/codecs/decoder.cc b/libheif/codecs/decoder.cc
index 5176e732..39950588 100644
--- a/libheif/codecs/decoder.cc
+++ b/libheif/codecs/decoder.cc
@@ -357,6 +357,7 @@ Error Decoder::decode_sequence_frame_from_compressed_data(bool upload_configurat
       plugin_options.format = get_compression_format();
       plugin_options.num_threads = options.num_codec_threads;
       plugin_options.strict_decoding = options.strict_decoding;
+      plugin_options.limits = limits;

       err = m_decoder_plugin->new_decoder2(&m_decoder, &plugin_options);
       if (err.code != heif_error_Ok) {
diff --git a/libheif/plugins/decoder_aom.cc b/libheif/plugins/decoder_aom.cc
index 2e693cb2..76b5004f 100644
--- a/libheif/plugins/decoder_aom.cc
+++ b/libheif/plugins/decoder_aom.cc
@@ -58,6 +58,7 @@ struct aom_decoder
   std::deque<Packet> output_queue;
   bool strict_decoding = false;
   std::string error_message;
+  const heif_security_limits* limits = nullptr;
 };

 static const char kSuccess[] = "Success";
@@ -134,6 +135,7 @@ heif_error aom_new_decoder2(void** dec, const heif_decoder_plugin_options* optio
   }

   decoder->codec_initialized = true;
+  decoder->limits = options->limits;
   *dec = decoder;

   heif_error err = {heif_error_Ok, heif_suberror_Unspecified, kSuccess};
@@ -143,7 +145,7 @@ heif_error aom_new_decoder2(void** dec, const heif_decoder_plugin_options* optio

 heif_error aom_new_decoder(void** dec)
 {
-  heif_decoder_plugin_options options;
+  heif_decoder_plugin_options options{};
   options.format = heif_compression_AV1;
   options.strict_decoding = false;
   options.num_threads = 0;
@@ -335,7 +337,7 @@ heif_error aom_push_data2(void* decoder_raw, const void* frame_data, size_t fram
   for (;;) {
     heif_image* img;
     uintptr_t out_user_data;
-    heif_error err = get_next_image_from_decoder(decoder, &iter, &img, &out_user_data, nullptr); // TODO: send limits);
+    heif_error err = get_next_image_from_decoder(decoder, &iter, &img, &out_user_data, decoder->limits);
     if (err.code) {
       return err;
     }
@@ -408,7 +410,7 @@ static heif_error aom_flush_data(void* decoder_raw)

 static const heif_decoder_plugin decoder_aom
     {
-        5,
+        6,
         aom_plugin_name,
         aom_init_plugin,
         aom_deinit_plugin,
@@ -420,7 +422,7 @@ static const heif_decoder_plugin decoder_aom
         aom_set_strict_decoding,
         "aom",
         aom_decode_next_image,
-        /* minimum_required_libheif_version */ LIBHEIF_MAKE_VERSION(1,21,0),
+        /* minimum_required_libheif_version */ LIBHEIF_MAKE_VERSION(1,22,0),
         aom_does_support_format2,
         aom_new_decoder2,
         aom_push_data2,
diff --git a/libheif/plugins/decoder_dav1d.cc b/libheif/plugins/decoder_dav1d.cc
index 653c8f53..31d5ed08 100644
--- a/libheif/plugins/decoder_dav1d.cc
+++ b/libheif/plugins/decoder_dav1d.cc
@@ -99,11 +99,12 @@ heif_error dav1d_new_decoder2(void** dec, const heif_decoder_plugin_options* opt

   dav1d_default_settings(&decoder->settings);

-  if (heif_get_global_security_limits()->max_image_size_pixels > std::numeric_limits<unsigned int>::max()) {
+  const heif_security_limits* limits = options->limits ? options->limits : heif_get_global_security_limits();
+  if (limits->max_image_size_pixels > std::numeric_limits<unsigned int>::max()) {
     decoder->settings.frame_size_limit = 0;
   }
   else {
-    decoder->settings.frame_size_limit = static_cast<unsigned int>(heif_get_global_security_limits()->max_image_size_pixels);
+    decoder->settings.frame_size_limit = static_cast<unsigned int>(limits->max_image_size_pixels);
   }

   decoder->settings.all_layers = 0;
@@ -124,7 +125,7 @@ heif_error dav1d_new_decoder2(void** dec, const heif_decoder_plugin_options* opt

 heif_error dav1d_new_decoder(void** dec)
 {
-  struct heif_decoder_plugin_options options;
+  struct heif_decoder_plugin_options options{};
   options.format = heif_compression_AV1;
   options.strict_decoding = false;
   options.num_threads = 0;
@@ -420,7 +421,7 @@ heif_error dav1d_flush_data(void* decoder_raw)

 static const heif_decoder_plugin decoder_dav1d
     {
-        5,
+        6,
         dav1d_plugin_name,
         dav1d_init_plugin,
         dav1d_deinit_plugin,
@@ -432,7 +433,7 @@ static const heif_decoder_plugin decoder_dav1d
         dav1d_set_strict_decoding,
         "dav1d",
         dav1d_decode_next_image,
-        /* minimum_required_libheif_version */ LIBHEIF_MAKE_VERSION(1,21,0),
+        /* minimum_required_libheif_version */ LIBHEIF_MAKE_VERSION(1,22,0),
         dav1d_does_support_format2,
         dav1d_new_decoder2,
         dav1d_push_data2,
diff --git a/libheif/plugins/decoder_ffmpeg.cc b/libheif/plugins/decoder_ffmpeg.cc
index dba6c19e..28cdf8a0 100644
--- a/libheif/plugins/decoder_ffmpeg.cc
+++ b/libheif/plugins/decoder_ffmpeg.cc
@@ -195,7 +195,7 @@ static heif_error ffmpeg_new_decoder2(void** dec, const heif_decoder_plugin_opti

 static heif_error ffmpeg_new_decoder(void** dec)
 {
-  heif_decoder_plugin_options options;
+  heif_decoder_plugin_options options{};
   options.format = heif_compression_HEVC;
   options.num_threads = 0;
   options.strict_decoding = false;
diff --git a/libheif/plugins/decoder_jpeg.cc b/libheif/plugins/decoder_jpeg.cc
index 2872c8aa..bd06c8c1 100644
--- a/libheif/plugins/decoder_jpeg.cc
+++ b/libheif/plugins/decoder_jpeg.cc
@@ -103,7 +103,7 @@ heif_error jpeg_new_decoder2(void** dec, const heif_decoder_plugin_options* opti

 heif_error jpeg_new_decoder(void** dec)
 {
-  heif_decoder_plugin_options options;
+  heif_decoder_plugin_options options{};
   options.format = heif_compression_JPEG;
   options.num_threads = 0;
   options.strict_decoding = false;
diff --git a/libheif/plugins/decoder_libde265.cc b/libheif/plugins/decoder_libde265.cc
index cd53aece..ccf49221 100644
--- a/libheif/plugins/decoder_libde265.cc
+++ b/libheif/plugins/decoder_libde265.cc
@@ -198,7 +198,7 @@ heif_error libde265_new_decoder2(void** dec, const heif_decoder_plugin_options*

 static heif_error libde265_new_decoder(void** dec)
 {
-  heif_decoder_plugin_options options;
+  heif_decoder_plugin_options options{};
   options.format = heif_compression_HEVC;
   options.num_threads = 0;
   options.strict_decoding = false;
diff --git a/libheif/plugins/decoder_openh264.cc b/libheif/plugins/decoder_openh264.cc
index f76f1c38..d3063055 100644
--- a/libheif/plugins/decoder_openh264.cc
+++ b/libheif/plugins/decoder_openh264.cc
@@ -148,7 +148,7 @@ heif_error openh264_new_decoder2(void** dec, const heif_decoder_plugin_options*

 heif_error openh264_new_decoder(void** dec)
 {
-  heif_decoder_plugin_options options;
+  heif_decoder_plugin_options options{};
   options.format = heif_compression_AVC;
   options.num_threads = 0;
   options.strict_decoding = false;
diff --git a/libheif/plugins/decoder_openjpeg.cc b/libheif/plugins/decoder_openjpeg.cc
index 3d294c90..3f94ed14 100644
--- a/libheif/plugins/decoder_openjpeg.cc
+++ b/libheif/plugins/decoder_openjpeg.cc
@@ -94,7 +94,7 @@ heif_error openjpeg_new_decoder2(void** dec, const heif_decoder_plugin_options*

 heif_error openjpeg_new_decoder(void** dec)
 {
-  heif_decoder_plugin_options options;
+  heif_decoder_plugin_options options{};
   options.format = heif_compression_JPEG2000;
   options.num_threads = 0;
   options.strict_decoding = false;
diff --git a/libheif/plugins/decoder_vvdec.cc b/libheif/plugins/decoder_vvdec.cc
index 743728ed..73724325 100644
--- a/libheif/plugins/decoder_vvdec.cc
+++ b/libheif/plugins/decoder_vvdec.cc
@@ -132,7 +132,7 @@ heif_error vvdec_new_decoder2(void** dec, const heif_decoder_plugin_options* opt

 heif_error vvdec_new_decoder(void** dec)
 {
-  heif_decoder_plugin_options options;
+  heif_decoder_plugin_options options{};
   options.format = heif_compression_VVC;
   options.num_threads = 0;
   options.strict_decoding = false;