Commit 44d2c496 for libheif

commit 44d2c49660bdfc2fad76db9024531d5d29909da9
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Fri Dec 26 15:19:49 2025 +0100

    uncompressed: check for invalid pixel padding

diff --git a/libheif/codecs/uncompressed/decoder_abstract.h b/libheif/codecs/uncompressed/decoder_abstract.h
index f948b4ca..80a25899 100644
--- a/libheif/codecs/uncompressed/decoder_abstract.h
+++ b/libheif/codecs/uncompressed/decoder_abstract.h
@@ -61,13 +61,24 @@ public:
     m_tileStartOffset = get_current_byte_index();
   }

-  inline void handlePixelAlignment(uint32_t pixel_size)
+  inline Error handlePixelAlignment(uint32_t pixel_size)
   {
     if (pixel_size != 0) {
       uint32_t bytes_in_pixel = get_current_byte_index() - m_pixelStartOffset;
-      uint32_t padding = pixel_size - bytes_in_pixel;
-      skip_bytes(padding);
+      if (pixel_size > bytes_in_pixel) {
+        uint32_t padding = pixel_size - bytes_in_pixel;
+        skip_bytes(padding);
+      }
+      else {
+        return {
+          heif_error_Invalid_input,
+          heif_suberror_Unspecified,
+          "Uncompressed image: invalid 'pixel_size'"
+        };
+      }
     }
+
+    return {};
   }

   void handleRowAlignment(uint32_t alignment)
diff --git a/libheif/codecs/uncompressed/decoder_pixel_interleave.cc b/libheif/codecs/uncompressed/decoder_pixel_interleave.cc
index e4d19f54..33364544 100644
--- a/libheif/codecs/uncompressed/decoder_pixel_interleave.cc
+++ b/libheif/codecs/uncompressed/decoder_pixel_interleave.cc
@@ -90,13 +90,16 @@ Error PixelInterleaveDecoder::decode_tile(const DataExtent& dataExtent,

   UncompressedBitReader srcBits(src_data);

-  processTile(srcBits, tile_y, tile_x, out_x0, out_y0);
+  err = processTile(srcBits, tile_y, tile_x, out_x0, out_y0);
+  if (err) {
+    return err;
+  }

   return Error::Ok;
 }


-void PixelInterleaveDecoder::processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column, uint32_t out_x0, uint32_t out_y0)
+Error PixelInterleaveDecoder::processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column, uint32_t out_x0, uint32_t out_y0)
 {
   for (uint32_t tile_y = 0; tile_y < m_tile_height; tile_y++) {
     srcBits.markRowStart();
@@ -116,8 +119,14 @@ void PixelInterleaveDecoder::processTile(UncompressedBitReader& srcBits, uint32_
           srcBits.skip_bytes(entry.bytes_per_component_sample);
         }
       }
-      srcBits.handlePixelAlignment(m_uncC->get_pixel_size());
+      auto err = srcBits.handlePixelAlignment(m_uncC->get_pixel_size());
+      if (err) {
+        return err;
+      }
     }
+
     srcBits.handleRowAlignment(m_uncC->get_row_align_size());
   }
+
+  return {};
 }
diff --git a/libheif/codecs/uncompressed/decoder_pixel_interleave.h b/libheif/codecs/uncompressed/decoder_pixel_interleave.h
index 1fa8b0cc..f6004231 100644
--- a/libheif/codecs/uncompressed/decoder_pixel_interleave.h
+++ b/libheif/codecs/uncompressed/decoder_pixel_interleave.h
@@ -58,8 +58,8 @@ public:
                     uint32_t image_width, uint32_t image_height,
                     uint32_t tile_x, uint32_t tile_y) override;

-  void processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column,
-                   uint32_t out_x0, uint32_t out_y0);
+  [[nodiscard]] Error processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column,
+                                  uint32_t out_x0, uint32_t out_y0);
 };

 #endif // UNCI_DECODER_PIXEL_INTERLEAVE_H