Commit 8850b995 for libheif
commit 8850b9950a17b3ee64410e82bbc97c081f7f7f6b
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Mon Oct 26 10:52:22 2026 +0100
gdk-pixbuf: check the result of heif_image_scale_image() [GHSA-gff5-3vgr-p8h2]
heif_image_scale_image() writes *output only on success, but stop_load()
ignored its return value. When the scaling failed, the loader released the
decoded image and continued with the uninitialised 'resized' pointer: it read
the plane through it and handed it to gdk-pixbuf, whose destroy callback
later ran heif_image_release() on it.
A small valid file triggers this when the application keeps the aspect ratio
and fixes one output dimension, e.g. a 1x65536 AVIF loaded with
gdk_pixbuf_new_from_file_at_scale(path, 3840, -1, TRUE, ...) requests a
3840x251658240 output plane whose allocation fails.
Also return an error instead of continuing when the plane or the pixbuf
cannot be obtained.
Fixes GHSA-gff5-3vgr-p8h2 (reported as ANT-2026-1XUR5PVQ).
diff --git a/gdk-pixbuf/pixbufloader-heif.c b/gdk-pixbuf/pixbufloader-heif.c
index 88e6e00e..df71730c 100644
--- a/gdk-pixbuf/pixbufloader-heif.c
+++ b/gdk-pixbuf/pixbufloader-heif.c
@@ -130,8 +130,16 @@ static gboolean stop_load(gpointer context, GError** error)
}
if (requested_width > 0 && requested_height > 0 && (width != requested_width || height != requested_height)) {
- struct heif_image* resized;
- heif_image_scale_image(img, &resized, requested_width, requested_height, NULL);
+ struct heif_image* resized = NULL;
+ err = heif_image_scale_image(img, &resized, requested_width, requested_height, NULL);
+ if (err.code != heif_error_Ok) {
+ g_set_error(error, GDK_PIXBUF_ERROR,
+ err.code == heif_error_Memory_allocation_error ? GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY
+ : GDK_PIXBUF_ERROR_FAILED,
+ "HEIF scaling failed: %s", err.message);
+ goto cleanup;
+ }
+
heif_image_release(img);
width = requested_width;
height = requested_height;
@@ -139,9 +147,19 @@ static gboolean stop_load(gpointer context, GError** error)
}
data = heif_image_get_plane_readonly(img, heif_channel_interleaved, &stride);
+ if (!data) {
+ g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED,
+ "HEIF decoding failed: cannot access image data");
+ goto cleanup;
+ }
pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, has_alpha, 8, width, height, stride, release_heif_image,
img);
+ if (!pixbuf) {
+ g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ "cannot allocate pixbuf");
+ goto cleanup;
+ }
size_t profile_size = heif_image_handle_get_raw_color_profile_size(hdl);
if(profile_size) {