Commit 6aca89d7 for libheif

commit 6aca89d76a5118bd47adcb5b83e7b01a32134985
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Mon May 18 21:09:06 2026 +0200

    initialize allocated memory to avoid information leak (GHSA-2vh6-whr3-cmq3)

diff --git a/libheif/image-items/grid.cc b/libheif/image-items/grid.cc
index 865526bd..18e7bab4 100644
--- a/libheif/image-items/grid.cc
+++ b/libheif/image-items/grid.cc
@@ -357,8 +357,10 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
         return err;
       }

-      if (src_width < grid.get_width() / grid.get_columns() ||
-          src_height < grid.get_height() / grid.get_rows()) {
+      // Integer division would let e.g. 9 tiles of 11px each "cover" a 107px canvas
+      // (107/9 == 11), leaving an 8-pixel gap inside the visible image area.
+      if (static_cast<uint64_t>(src_width) * grid.get_columns() < grid.get_width() ||
+          static_cast<uint64_t>(src_height) * grid.get_rows() < grid.get_height()) {
         return Error{heif_error_Invalid_input,
                      heif_suberror_Invalid_grid_data,
                      "Grid tiles do not cover whole image"};
diff --git a/libheif/image/pixelimage.cc b/libheif/image/pixelimage.cc
index 4ea2487b..ba06fc0a 100644
--- a/libheif/image/pixelimage.cc
+++ b/libheif/image/pixelimage.cc
@@ -24,6 +24,7 @@
 #include "security_limits.h"

 #include <cassert>
+#include <cstdlib>
 #include <cstring>
 #include <utility>
 #include <limits>
@@ -156,7 +157,7 @@ static std::vector<uint16_t> map_channel_to_component_type(heif_channel channel,
 HeifPixelImage::~HeifPixelImage()
 {
   for (auto& component : m_storage) {
-    delete[] component.allocated_mem;
+    std::free(component.allocated_mem);
   }
 }

@@ -459,7 +460,9 @@ Error HeifPixelImage::ComponentStorage::alloc(uint32_t width, uint32_t height, h

     // --- allocate memory

-  allocated_mem = new (std::nothrow) uint8_t[allocation_size];
+  // Must zero-initialize: padding regions (stride, rounded_size(), alignment slack) are not
+  // written by decoders, so uninitialized contents would leak across decoded images.
+  allocated_mem = static_cast<uint8_t*>(std::calloc(1, allocation_size));
   if (allocated_mem == nullptr) {
     std::stringstream sstr;
     sstr << "Allocating " << allocation_size << " bytes failed";
@@ -540,7 +543,7 @@ Error HeifPixelImage::extend_padding_to_size(uint32_t width, uint32_t height, bo
       // --- release the old plane before replacing it with the reallocated plane

       m_memory_handle.free(component.allocation_size);
-      delete[] component.allocated_mem;
+      std::free(component.allocated_mem);

       component = newPlane;
     }
@@ -631,7 +634,7 @@ Error HeifPixelImage::extend_to_size_with_zero(uint32_t width, uint32_t height,
       // --- release the old plane before replacing it with the reallocated plane

       m_memory_handle.free(component.allocation_size);
-      delete[] component.allocated_mem;
+      std::free(component.allocated_mem);

       component = newPlane;
     }