Commit 12360126 for libheif

commit 1236012605e9b24e123f5f41220f2b1f71359b8b
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Mon Oct 26 10:53:37 2026 +0100

    Harden image scaling against oversized requests and unchecked errors

    heif_image_scale_image() now checks its pointer arguments and sets *output
    to NULL on entry, so that a caller that misses the error check gets NULL
    instead of an uninitialised pointer.

    The gdk-pixbuf loader bounds the requested output size by
    max_image_size_pixels of the global security limits before it calls the
    scaler, which does not apply any limit itself. Previously such a request
    only failed if the allocation failed, which it does not with
    vm.overcommit_memory=1.

diff --git a/gdk-pixbuf/pixbufloader-heif.c b/gdk-pixbuf/pixbufloader-heif.c
index df71730c..a78015dc 100644
--- a/gdk-pixbuf/pixbufloader-heif.c
+++ b/gdk-pixbuf/pixbufloader-heif.c
@@ -130,6 +130,17 @@ static gboolean stop_load(gpointer context, GError** error)
   }

   if (requested_width > 0 && requested_height > 0 && (width != requested_width || height != requested_height)) {
+    // The scaler does not apply the security limits, and the requested size may be derived
+    // from the file's aspect ratio (e.g. when only the width is fixed). Bound it here.
+    const struct heif_security_limits* limits = heif_get_global_security_limits();
+    if (limits->max_image_size_pixels != 0 &&
+        (guint64) requested_width * (guint64) requested_height > limits->max_image_size_pixels) {
+      g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+                  "HEIF scaling failed: requested size %dx%d exceeds the security limit",
+                  requested_width, requested_height);
+      goto cleanup;
+    }
+
     struct heif_image* resized = NULL;
     err = heif_image_scale_image(img, &resized, requested_width, requested_height, NULL);
     if (err.code != heif_error_Ok) {
diff --git a/libheif/api/libheif/heif_image.cc b/libheif/api/libheif/heif_image.cc
index d61b7904..f87ed1f3 100644
--- a/libheif/api/libheif/heif_image.cc
+++ b/libheif/api/libheif/heif_image.cc
@@ -242,6 +242,13 @@ heif_error heif_image_scale_image(const heif_image* input,
                                   int width, int height,
                                   const heif_scaling_options* options)
 {
+  if (output == nullptr || input == nullptr) {
+    return heif_error_null_pointer_argument;
+  }
+
+  // Callers that miss the error check get NULL instead of an uninitialised pointer.
+  *output = nullptr;
+
   std::shared_ptr<HeifPixelImage> out_img;

   Error err = input->image->scale_nearest_neighbor(out_img, width, height, nullptr);
diff --git a/libheif/api/libheif/heif_image.h b/libheif/api/libheif/heif_image.h
index ce2393f7..3b043d9a 100644
--- a/libheif/api/libheif/heif_image.h
+++ b/libheif/api/libheif/heif_image.h
@@ -290,6 +290,7 @@ uint8_t* heif_image_get_plane2(heif_image*,
 typedef struct heif_scaling_options heif_scaling_options;

 // Currently, heif_scaling_options is not defined yet. Pass a NULL pointer.
+// On error, '*output' is set to NULL. Always check the returned error.
 LIBHEIF_API
 heif_error heif_image_scale_image(const heif_image* input,
                                   heif_image** output,