Sync from SUSE:ALP:Source:Standard:1.0 libheif revision 633fc099c060b274b3145a14f62d1e0c

This commit is contained in:
Adrian Schröter 2024-12-04 14:16:49 +01:00
parent 12afb649c8
commit 8e01a989d6
4 changed files with 252 additions and 3 deletions

3
_multibuild Normal file
View File

@ -0,0 +1,3 @@
<multibuild>
<package>test</package>
</multibuild>

View File

@ -0,0 +1,200 @@
Index: libheif-1.17.6/libheif/context.cc
===================================================================
--- libheif-1.17.6.orig/libheif/context.cc
+++ libheif-1.17.6/libheif/context.cc
@@ -324,9 +324,9 @@ Error ImageOverlay::parse(size_t num_ima
std::stringstream sstr;
sstr << "Overlay image data version " << ((int) m_version) << " is not implemented yet";
- return Error(heif_error_Unsupported_feature,
- heif_suberror_Unsupported_data_version,
- sstr.str());
+ return {heif_error_Unsupported_feature,
+ heif_suberror_Unsupported_data_version,
+ sstr.str()};
}
int field_len = ((m_flags & 1) ? 4 : 2);
@@ -344,6 +344,12 @@ Error ImageOverlay::parse(size_t num_ima
m_width = readvec(data, ptr, field_len);
m_height = readvec(data, ptr, field_len);
+ if (m_width==0 || m_height==0) {
+ return {heif_error_Invalid_input,
+ heif_suberror_Invalid_overlay_data,
+ "Overlay image with zero width or height."};
+ }
+
m_offsets.resize(num_images);
for (size_t i = 0; i < num_images; i++) {
Index: libheif-1.17.6/libheif/pixelimage.cc
===================================================================
--- libheif-1.17.6.orig/libheif/pixelimage.cc
+++ libheif-1.17.6/libheif/pixelimage.cc
@@ -748,7 +748,20 @@ Error HeifPixelImage::fill_RGB_16bit(uin
}
-Error HeifPixelImage::overlay(std::shared_ptr<HeifPixelImage>& overlay, int dx, int dy)
+uint32_t negate_negative_int32(int32_t x)
+{
+ assert(x <= 0);
+
+ if (x == INT32_MIN) {
+ return static_cast<uint32_t>(INT32_MAX) + 1;
+ }
+ else {
+ return static_cast<uint32_t>(-x);
+ }
+}
+
+
+Error HeifPixelImage::overlay(std::shared_ptr<HeifPixelImage>& overlay, int32_t dx, int32_t dy)
{
std::set<enum heif_channel> channels = overlay->get_channel_set();
@@ -773,70 +786,89 @@ Error HeifPixelImage::overlay(std::share
in_p = overlay->get_plane(channel, &in_stride);
out_p = get_plane(channel, &out_stride);
- int in_w = overlay->get_width(channel);
- int in_h = overlay->get_height(channel);
- assert(in_w >= 0);
- assert(in_h >= 0);
+ uint32_t in_w = overlay->get_width(channel);
+ uint32_t in_h = overlay->get_height(channel);
- int out_w = get_width(channel);
- int out_h = get_height(channel);
- assert(out_w >= 0);
- assert(out_h >= 0);
+ uint32_t out_w = get_width(channel);
+ uint32_t out_h = get_height(channel);
- // overlay image extends past the right border -> cut width for copy
- if (dx + in_w > out_w) {
- in_w = out_w - dx;
+ // top-left points where to start copying in source and destination
+ uint32_t in_x0;
+ uint32_t in_y0;
+ uint32_t out_x0;
+ uint32_t out_y0;
+
+ if (dx > 0 && static_cast<uint32_t>(dx) >= out_w) {
+ // the overlay image is completely outside the right border -> skip overlaying
+ return Error::Ok;
+ }
+ else if (dx < 0 && in_w <= negate_negative_int32(dx)) {
+ // the overlay image is completely outside the left border -> skip overlaying
+ return Error::Ok;
}
- // overlay image extends past the bottom border -> cut height for copy
- if (dy + in_h > out_h) {
- in_h = out_h - dy;
- }
+ if (dx < 0) {
+ // overlay image started partially outside of left border
- // overlay image completely outside right or bottom border -> do not copy
- if (in_w < 0 || in_h < 0) {
- return Error(heif_error_Invalid_input,
- heif_suberror_Overlay_image_outside_of_canvas,
- "Overlay image outside of right or bottom canvas border");
+ in_x0 = negate_negative_int32(dx);
+ out_x0 = 0;
+ in_w = in_w - in_x0; // in_x0 < in_w because in_w > -dx = in_x0
+ }
+ else {
+ in_x0 = 0;
+ out_x0 = static_cast<uint32_t>(dx);
}
+ // we know that dx >= 0 && dx < out_w
- // calculate top-left point where to start copying in source and destination
- int in_x0 = 0;
- int in_y0 = 0;
- int out_x0 = dx;
- int out_y0 = dy;
+ if (static_cast<uint32_t>(dx) > UINT32_MAX - in_w ||
+ dx + in_w > out_w) {
+ // overlay image extends partially outside of right border
- // overlay image started outside of left border
- // -> move start into the image and start at left output column
- if (dx < 0) {
- in_x0 = -dx;
- out_x0 = 0;
+ in_w = out_w - static_cast<uint32_t>(dx); // we know that dx < out_w from first condition
}
- // overlay image started outside of top border
- // -> move start into the image and start at top output row
+
+ if (dy > 0 && static_cast<uint32_t>(dy) >= out_h) {
+ // the overlay image is completely outside the bottom border -> skip overlaying
+ return Error::Ok;
+ }
+ else if (dy < 0 && in_h <= negate_negative_int32(dy)) {
+ // the overlay image is completely outside the top border -> skip overlaying
+ return Error::Ok;
+ }
+
+
+
if (dy < 0) {
- in_y0 = -dy;
+ // overlay image started partially outside of top border
+
+ in_y0 = negate_negative_int32(dy);
out_y0 = 0;
+ in_h = in_h - in_y0; // in_y0 < in_h because in_h > -dy = in_y0
+ }
+ else {
+ in_y0 = 0;
+ out_y0 = static_cast<uint32_t>(dy);
}
- // if overlay image is completely outside at left border, do not copy anything.
- if (in_w <= in_x0 ||
- in_h <= in_y0) {
- return Error(heif_error_Invalid_input,
- heif_suberror_Overlay_image_outside_of_canvas,
- "Overlay image outside of left or top canvas border");
+ // we know that dy >= 0 && dy < out_h
+
+ if (static_cast<uint32_t>(dy) > UINT32_MAX - in_h ||
+ dy + in_h > out_h) {
+ // overlay image extends partially outside of bottom border
+
+ in_h = out_h - static_cast<uint32_t>(dy); // we know that dy < out_h from first condition
}
- for (int y = in_y0; y < in_h; y++) {
+ for (uint32_t y = in_y0; y < in_h; y++) {
if (!has_alpha) {
memcpy(out_p + out_x0 + (out_y0 + y - in_y0) * out_stride,
in_p + in_x0 + y * in_stride,
in_w - in_x0);
}
else {
- for (int x = in_x0; x < in_w; x++) {
+ for (uint32_t x = in_x0; x < in_w; x++) {
uint8_t* outptr = &out_p[out_x0 + (out_y0 + y - in_y0) * out_stride + x];
uint8_t in_val = in_p[in_x0 + y * in_stride + x];
uint8_t alpha_val = alpha_p[in_x0 + y * in_stride + x];
Index: libheif-1.17.6/libheif/pixelimage.h
===================================================================
--- libheif-1.17.6.orig/libheif/pixelimage.h
+++ libheif-1.17.6/libheif/pixelimage.h
@@ -109,7 +109,7 @@ public:
Error fill_RGB_16bit(uint16_t r, uint16_t g, uint16_t b, uint16_t a);
- Error overlay(std::shared_ptr<HeifPixelImage>& overlay, int dx, int dy);
+ Error overlay(std::shared_ptr<HeifPixelImage>& overlay, int32_t dx, int32_t dy);
Error scale_nearest_neighbor(std::shared_ptr<HeifPixelImage>& output, int width, int height) const;

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Tue Oct 22 08:46:30 UTC 2024 - pgajdos@suse.com
- security update
- added patches
fix CVE-2024-41311 [bsc#1231714], out-of-bounds read and write in ImageOverlay:parse() due to decoding a heif file containing an overlay image with forged offsets
+ libheif-CVE-2024-41311.patch
- turn on the testsuite
- added sources
+ _multibuild
-------------------------------------------------------------------
Wed Jan 3 09:26:08 UTC 2024 - Dirk Müller <dmueller@suse.com>

View File

@ -16,6 +16,15 @@
#
%global flavor @BUILD_FLAVOR@%{nil}
%if "%{flavor}" == "test"
%define psuffix -test
%bcond_without test
%else
%define psuffix %{nil}
%bcond_with test
%endif
%define gdk_pixbuf_binary_version 2.10.0
%bcond_with x265
%bcond_with kvazaar
@ -26,15 +35,17 @@
%endif
%endif
Name: libheif
Name: libheif%{psuffix}
Version: 1.17.6
Release: 0
Summary: HEIF/AVIF file format decoder and encoder
License: GPL-2.0-or-later
Group: Productivity/Graphics/Other
URL: https://github.com/strukturag/libheif
Source0: %{url}/releases/download/v%{version}/%{name}-%{version}.tar.gz
Source0: %{url}/releases/download/v%{version}/libheif-%{version}.tar.gz
Source99: baselibs.conf
# CVE-2024-41311 [bsc#1231714], out-of-bounds read and write in ImageOverlay:parse() due to decoding a heif file containing an overlay image with forged offsets
Patch0: libheif-CVE-2024-41311.patch
BuildRequires: chrpath
BuildRequires: cmake
BuildRequires: fdupes
@ -59,6 +70,9 @@ BuildRequires: pkgconfig(SvtAv1Enc)
BuildRequires: pkgconfig(libde265)
BuildRequires: pkgconfig(x265)
%endif
%if %{with test}
BuildArch: noarch
%endif
%description
libheif is an ISO/IEC 23008-12:2017 HEIF and AVIF (AV1 Image File Format) file
@ -219,10 +233,17 @@ Allows to show thumbnail previews of HEIF and AVIF images using %{name}.
%endif
%prep
%autosetup -p1
%autosetup -p1 -n libheif-%{version}
%build
# https://github.com/strukturag/libheif/issues/1281
sed -i '/add_libheif_test(encode)/d' tests/CMakeLists.txt
%cmake \
%if %{with test}
--preset=testing \
-DWITH_FFMPEG_DECODER=OFF \
-DWITH_FFMPEG_DECODER_PLUGIN=OFF \
%else
-DWITH_AOM_DECODER=ON \
-DWITH_AOM_DECODER_PLUGIN=ON \
-DWITH_AOM_ENCODER=ON \
@ -275,9 +296,21 @@ Allows to show thumbnail previews of HEIF and AVIF images using %{name}.
-DCMAKE_CXX_FLAGS="-pthread" \
%endif
-DPLUGIN_DIRECTORY=%{_libexecdir}/libheif \
%endif
%nil
%cmake_build
%if %{with test}
%check
cd build
export LD_LIBRARY_PATH=$(pwd)/libheif
make test
%endif
%if !%{with test}
%install
%cmake_install
%if %{with x265}
@ -376,4 +409,6 @@ rm -f %{buildroot}%{_datadir}/thumbnailers/heif.thumbnailer
%{_mandir}/man1/heif-thumbnailer.1%{?ext_man}
%endif
%endif
%changelog