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,