commit 808e2125be6cc2c2a7d0bf069e28a1a222ebff62
parent 77075ac3b00b39a33da68c8cdd06b4e77f5abb9a
Author: Timothy Nikkel <tnikkel@gmail.com>
Date: Fri, 12 Dec 2025 14:52:34 +0000
Bug 2004498. Update libpng to v1.6.53. r=gfx-reviewers,nical
Differential Revision: https://phabricator.services.mozilla.com/D276152
Diffstat:
13 files changed, 112 insertions(+), 148 deletions(-)
diff --git a/media/libpng/ANNOUNCE b/media/libpng/ANNOUNCE
@@ -1,5 +1,5 @@
-libpng 1.6.51 - November 21, 2025
-=================================
+libpng 1.6.53 - December 5, 2025
+================================
This is a public release of libpng, intended for use in production code.
@@ -7,15 +7,12 @@ This is a public release of libpng, intended for use in production code.
Files available for download
----------------------------
-Source files with LF line endings (for Unix/Linux):
+Source files:
- * libpng-1.6.51.tar.xz (LZMA-compressed, recommended)
- * libpng-1.6.51.tar.gz (deflate-compressed)
-
-Source files with CRLF line endings (for Windows):
-
- * lpng1651.7z (LZMA-compressed, recommended)
- * lpng1651.zip (deflate-compressed)
+ * libpng-1.6.53.tar.xz (LZMA-compressed, recommended)
+ * libpng-1.6.53.tar.gz (deflate-compressed)
+ * lpng1653.7z (LZMA-compressed)
+ * lpng1653.zip (deflate-compressed)
Other information:
@@ -25,33 +22,14 @@ Other information:
* TRADEMARK.md
-Changes from version 1.6.50 to version 1.6.51
+Changes from version 1.6.52 to version 1.6.53
---------------------------------------------
- * Fixed CVE-2025-64505 (moderate severity):
- Heap buffer overflow in `png_do_quantize` via malformed palette index.
- (Reported by Samsung; analyzed by Fabio Gritti.)
- * Fixed CVE-2025-64506 (moderate severity):
- Heap buffer over-read in `png_write_image_8bit` with 8-bit input and
- `convert_to_8bit` enabled.
- (Reported by Samsung and <weijinjinnihao@users.noreply.github.com>;
- analyzed by Fabio Gritti.)
- * Fixed CVE-2025-64720 (high severity):
- Buffer overflow in `png_image_read_composite` via incorrect palette
- premultiplication.
- (Reported by Samsung; analyzed by John Bowler.)
- * Fixed CVE-2025-65018 (high severity):
- Heap buffer overflow in `png_combine_row` triggered via
- `png_image_finish_read`.
- (Reported by <yosiimich@users.noreply.github.com>.)
- * Fixed a memory leak in `png_set_quantize`.
- (Reported by Samsung; analyzed by Fabio Gritti.)
- * Removed the experimental and incomplete ERROR_NUMBERS code.
- (Contributed by Tobias Stoeckmann.)
- * Improved the RISC-V vector extension support; required RVV 1.0 or newer.
- (Contributed by Filip Wasil.)
- * Added GitHub Actions workflows for automated testing.
- * Performed various refactorings and cleanups.
+ * Fixed a build failure on RISC-V RVV caused by a misspelled intrinsic.
+ (Contributed by Alexander Smorkalov.)
+ * Fixed a build failure with CMake 4.1 or newer, on Windows, when using
+ Visual C++ without MASM installed.
+ (Reported by Andrew Tribick; fixed by Luis Caro Campos.)
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
diff --git a/media/libpng/AUTHORS b/media/libpng/AUTHORS
@@ -5,6 +5,7 @@ This is the list of PNG Reference Library ("libpng") Contributing
Authors, for copyright and licensing purposes.
* Adam Richter
+ * Alexander Smorkalov
* Andreas Dilger
* Chris Blume
* Cosmin Truta
@@ -56,6 +57,8 @@ Authors, for copyright and licensing purposes.
- ZhangLixia (张利霞)
* Samsung Group
- Filip Wasil
+ * SpacemiT Hangzhou Technology, Co.
+ - Liang Junzhao (梁俊钊)
The build projects, the build scripts, the test scripts, and other
files in the "projects", "scripts" and "tests" directories, have
diff --git a/media/libpng/CHANGES b/media/libpng/CHANGES
@@ -6304,6 +6304,23 @@ Version 1.6.51 [November 21, 2025]
Added GitHub Actions workflows for automated testing.
Performed various refactorings and cleanups.
+Version 1.6.52 [December 3, 2025]
+ Fixed CVE-2025-66293 (high severity):
+ Out-of-bounds read in `png_image_read_composite`.
+ (Reported by flyfish101 <flyfish101@users.noreply.github.com>.)
+ Fixed the Paeth filter handling in the RISC-V RVV implementation.
+ (Reported by Filip Wasil; fixed by Liang Junzhao.)
+ Improved the performance of the RISC-V RVV implementation.
+ (Contributed by Liang Junzhao.)
+ Added allocation failure fuzzing to oss-fuzz.
+ (Contributed by Philippe Antoine.)
+
+Version 1.6.53 [December 5, 2025]
+ Fixed a build failure on RISC-V RVV caused by a misspelled intrinsic.
+ (Contributed by Alexander Smorkalov.)
+ Fixed a build failure with CMake 4.1 or newer, on Windows, when using
+ Visual C++ without MASM installed.
+
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
Subscription is required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/media/libpng/README b/media/libpng/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.51
+README for libpng version 1.6.53
================================
See the note about version numbers near the top of `png.h`.
diff --git a/media/libpng/apng.patch b/media/libpng/apng.patch
@@ -302,7 +302,7 @@ diff --git a/pngget.c b/pngget.c
diff --git a/pnginfo.h b/pnginfo.h
--- a/pnginfo.h
+++ b/pnginfo.h
-@@ -282,5 +282,18 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
+@@ -259,5 +259,18 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
#ifdef PNG_sRGB_SUPPORTED
int rendering_intent;
#endif
diff --git a/media/libpng/libpng-manual.txt b/media/libpng/libpng-manual.txt
@@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
- libpng version 1.6.36, December 2018, through 1.6.51 - November 2025
+ libpng version 1.6.36, December 2018, through 1.6.53 - December 2025
Updated and distributed by Cosmin Truta
Copyright (c) 2018-2025 Cosmin Truta
diff --git a/media/libpng/moz.yaml b/media/libpng/moz.yaml
@@ -11,9 +11,9 @@ origin:
url: "http://www.libpng.org/pub/png/libpng.html"
license: libpng
- release: v1.6.51 (2025-11-21T23:01:00+02:00).
+ release: v1.6.53 (2025-12-05T23:46:38+02:00).
- revision: "v1.6.49"
+ revision: "v1.6.53"
license-file: LICENSE
diff --git a/media/libpng/png.c b/media/libpng/png.c
@@ -13,7 +13,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_51 Your_png_h_is_not_version_1_6_51;
+typedef png_libpng_version_1_6_53 Your_png_h_is_not_version_1_6_53;
/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
* corresponding macro definitions. This causes a compile time failure if
@@ -817,7 +817,7 @@ png_get_copyright(png_const_structrp png_ptr)
return PNG_STRING_COPYRIGHT
#else
return PNG_STRING_NEWLINE \
- "libpng version 1.6.51" PNG_STRING_NEWLINE \
+ "libpng version 1.6.53" PNG_STRING_NEWLINE \
"Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
PNG_STRING_NEWLINE \
diff --git a/media/libpng/png.h b/media/libpng/png.h
@@ -1,6 +1,6 @@
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.51
+ * libpng version 1.6.53
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
@@ -14,7 +14,7 @@
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.35, July 2018:
* Glenn Randers-Pehrson
- * libpng versions 1.6.36, December 2018, through 1.6.51, November 2025:
+ * libpng versions 1.6.36, December 2018, through 1.6.53, December 2025:
* Cosmin Truta
* See also "Contributing Authors", below.
*/
@@ -238,7 +238,7 @@
* ...
* 1.5.30 15 10530 15.so.15.30[.0]
* ...
- * 1.6.51 16 10651 16.so.16.51[.0]
+ * 1.6.53 16 10651 16.so.16.53[.0]
*
* Henceforth the source version will match the shared-library major and
* minor numbers; the shared-library major version number will be used for
@@ -274,7 +274,7 @@
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.51"
+#define PNG_LIBPNG_VER_STRING "1.6.53"
#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
/* The versions of shared library builds should stay in sync, going forward */
@@ -285,7 +285,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 51
+#define PNG_LIBPNG_VER_RELEASE 53
/* This should be zero for a public release, or non-zero for a
* development version.
@@ -316,7 +316,7 @@
* From version 1.0.1 it is:
* XXYYZZ, where XX=major, YY=minor, ZZ=release
*/
-#define PNG_LIBPNG_VER 10651 /* 1.6.51 */
+#define PNG_LIBPNG_VER 10653 /* 1.6.53 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@@ -441,7 +441,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char* png_libpng_version_1_6_51;
+typedef char* png_libpng_version_1_6_53;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
diff --git a/media/libpng/pngconf.h b/media/libpng/pngconf.h
@@ -1,6 +1,6 @@
/* pngconf.h - machine-configurable file for libpng
*
- * libpng version 1.6.51
+ * libpng version 1.6.53
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
diff --git a/media/libpng/pngread.c b/media/libpng/pngread.c
@@ -3287,6 +3287,7 @@ png_image_read_composite(png_voidp argument)
ptrdiff_t step_row = display->row_bytes;
unsigned int channels =
(image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+ int optimize_alpha = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
int pass;
for (pass = 0; pass < passes; ++pass)
@@ -3343,20 +3344,44 @@ png_image_read_composite(png_voidp argument)
if (alpha < 255) /* else just use component */
{
- /* This is PNG_OPTIMIZED_ALPHA, the component value
- * is a linear 8-bit value. Combine this with the
- * current outrow[c] value which is sRGB encoded.
- * Arithmetic here is 16-bits to preserve the output
- * values correctly.
- */
- component *= 257*255; /* =65535 */
- component += (255-alpha)*png_sRGB_table[outrow[c]];
+ if (optimize_alpha != 0)
+ {
+ /* This is PNG_OPTIMIZED_ALPHA, the component value
+ * is a linear 8-bit value. Combine this with the
+ * current outrow[c] value which is sRGB encoded.
+ * Arithmetic here is 16-bits to preserve the output
+ * values correctly.
+ */
+ component *= 257*255; /* =65535 */
+ component += (255-alpha)*png_sRGB_table[outrow[c]];
- /* So 'component' is scaled by 255*65535 and is
- * therefore appropriate for the sRGB to linear
- * conversion table.
- */
- component = PNG_sRGB_FROM_LINEAR(component);
+ /* Clamp to the valid range to defend against
+ * unforeseen cases where the data might be sRGB
+ * instead of linear premultiplied.
+ * (Belt-and-suspenders for CVE-2025-66293.)
+ */
+ if (component > 255*65535)
+ component = 255*65535;
+
+ /* So 'component' is scaled by 255*65535 and is
+ * therefore appropriate for the sRGB-to-linear
+ * conversion table.
+ */
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+ else
+ {
+ /* Compositing was already done on the palette
+ * entries. The data is sRGB premultiplied on black.
+ * Composite with the background in sRGB space.
+ * This is not gamma-correct, but matches what was
+ * done to the palette.
+ */
+ png_uint_32 background = outrow[c];
+ component += ((255-alpha) * background + 127) / 255;
+ if (component > 255)
+ component = 255;
+ }
}
outrow[c] = (png_byte)component;
diff --git a/media/libpng/pngrtran.c b/media/libpng/pngrtran.c
@@ -1843,6 +1843,7 @@ png_init_read_transformations(png_structrp png_ptr)
* transformations elsewhere.
*/
png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
} /* color_type == PNG_COLOR_TYPE_PALETTE */
/* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
diff --git a/media/libpng/riscv/filter_rvv_intrinsics.c b/media/libpng/riscv/filter_rvv_intrinsics.c
@@ -2,8 +2,11 @@
*
* Copyright (c) 2023 Google LLC
* Written by Manfred SCHLAEGL, 2022
- * Dragoș Tiselice <dtiselice@google.com>, May 2023.
- * Filip Wasil <f.wasil@samsung.com>, March 2025.
+ * Revised by:
+ * - Dragoș Tiselice <dtiselice@google.com>, May 2023
+ * - Filip Wasil <f.wasil@samsung.com>, March 2025
+ * - Liang Junzhao <junzhao.liang@spacemit.com>, November 2025
+ * - Alexander Smorkalov <alexander.smorkalov@opencv.ai>, December 2025
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -140,11 +143,8 @@ png_read_filter_row_avg_rvv(size_t len, size_t bpp, unsigned char* row,
/* x = *row */
x = __riscv_vle8_v_u8m1(row, vl);
- /* tmp = a + b */
- vuint16m2_t tmp = __riscv_vwaddu_vv_u16m2(a, b, vl);
-
- /* a = tmp/2 */
- a = __riscv_vnsrl_wx_u8m1(tmp, 1, vl);
+ /* a = (a + b) / 2, round to zero with vxrm = 2 */
+ a = __riscv_vaaddu_vv_u8m1(a, b, 2, vl);
/* a += x */
a = __riscv_vadd_vv_u8m1(a, x, vl);
@@ -177,47 +177,6 @@ png_read_filter_row_avg4_rvv(png_row_infop row_info, png_bytep row,
PNG_UNUSED(prev_row)
}
-#define MIN_CHUNK_LEN 256
-#define MAX_CHUNK_LEN 2048
-
-static inline vuint8m1_t
-prefix_sum(vuint8m1_t chunk, unsigned char* carry, size_t vl,
- size_t max_chunk_len)
-{
- size_t r;
-
- for (r = 1; r < MIN_CHUNK_LEN; r <<= 1)
- {
- vbool8_t shift_mask = __riscv_vmsgeu_vx_u8m1_b8(__riscv_vid_v_u8m1(vl), r, vl);
- chunk = __riscv_vadd_vv_u8m1_mu(shift_mask, chunk, chunk, __riscv_vslideup_vx_u8m1(__riscv_vundefined_u8m1(), chunk, r, vl), vl);
- }
-
- for (r = MIN_CHUNK_LEN; r < MAX_CHUNK_LEN && r < max_chunk_len; r <<= 1)
- {
- vbool8_t shift_mask = __riscv_vmsgeu_vx_u8m1_b8(__riscv_vid_v_u8m1(vl), r, vl);
- chunk = __riscv_vadd_vv_u8m1_mu(shift_mask, chunk, chunk, __riscv_vslideup_vx_u8m1(__riscv_vundefined_u8m1(), chunk, r, vl), vl);
- }
-
- chunk = __riscv_vadd_vx_u8m1(chunk, *carry, vl);
- *carry = __riscv_vmv_x_s_u8m1_u8(__riscv_vslidedown_vx_u8m1(chunk, vl - 1, vl));
-
- return chunk;
-}
-
-static inline vint16m1_t
-abs_diff(vuint16m1_t a, vuint16m1_t b, size_t vl)
-{
- vint16m1_t diff = __riscv_vreinterpret_v_u16m1_i16m1(__riscv_vsub_vv_u16m1(a, b, vl));
- vbool16_t mask = __riscv_vmslt_vx_i16m1_b16(diff, 0, vl);
- return __riscv_vrsub_vx_i16m1_m(mask, diff, 0, vl);
-}
-
-static inline vint16m1_t
-abs_sum(vint16m1_t a, vint16m1_t b, size_t vl)
-{
- return __riscv_vadd_vv_i16m1(a, b, vl);
-}
-
static inline void
png_read_filter_row_paeth_rvv(size_t len, size_t bpp, unsigned char* row,
const unsigned char* prev)
@@ -265,27 +224,22 @@ png_read_filter_row_paeth_rvv(size_t len, size_t bpp, unsigned char* row,
/* x = *row */
vuint8m1_t x = __riscv_vle8_v_u8m1(row, vl);
- /* Calculate p = b - c and pc = a - c using widening subtraction */
- vuint16m2_t p_wide = __riscv_vwsubu_vv_u16m2(b, c, vl);
- vuint16m2_t pc_wide = __riscv_vwsubu_vv_u16m2(a, c, vl);
-
- /* Convert to signed for easier manipulation */
- size_t vl16 = __riscv_vsetvl_e16m2(bpp);
- vint16m2_t p = __riscv_vreinterpret_v_u16m2_i16m2(p_wide);
- vint16m2_t pc = __riscv_vreinterpret_v_u16m2_i16m2(pc_wide);
+ /* p = b - c and pc = a - c */
+ vuint16m2_t p = __riscv_vwsubu_vv_u16m2(b, c, vl);
+ vuint16m2_t pc = __riscv_vwsubu_vv_u16m2(a, c, vl);
/* pa = |p| */
- vbool8_t p_neg_mask = __riscv_vmslt_vx_i16m2_b8(p, 0, vl16);
- vint16m2_t pa = __riscv_vrsub_vx_i16m2_m(p_neg_mask, p, 0, vl16);
+ vuint16m2_t tmp = __riscv_vrsub_vx_u16m2(p, 0, vl);
+ vuint16m2_t pa = __riscv_vminu_vv_u16m2(p, tmp, vl);
/* pb = |pc| */
- vbool8_t pc_neg_mask = __riscv_vmslt_vx_i16m2_b8(pc, 0, vl16);
- vint16m2_t pb = __riscv_vrsub_vx_i16m2_m(pc_neg_mask, pc, 0, vl16);
+ tmp = __riscv_vrsub_vx_u16m2(pc, 0, vl);
+ vuint16m2_t pb = __riscv_vminu_vv_u16m2(pc, tmp, vl);
/* pc = |p + pc| */
- vint16m2_t p_plus_pc = __riscv_vadd_vv_i16m2(p, pc, vl16);
- vbool8_t p_plus_pc_neg_mask = __riscv_vmslt_vx_i16m2_b8(p_plus_pc, 0, vl16);
- pc = __riscv_vrsub_vx_i16m2_m(p_plus_pc_neg_mask, p_plus_pc, 0, vl16);
+ pc = __riscv_vadd_vv_u16m2(p, pc, vl);
+ tmp = __riscv_vrsub_vx_u16m2(pc, 0, vl);
+ pc = __riscv_vminu_vv_u16m2(pc, tmp, vl);
/*
* The key insight is that we want the minimum of pa, pb, pc.
@@ -294,31 +248,17 @@ png_read_filter_row_paeth_rvv(size_t len, size_t bpp, unsigned char* row,
* - Else use c
*/
- /* Find which predictor to use based on minimum absolute difference */
- vbool8_t pa_le_pb = __riscv_vmsle_vv_i16m2_b8(pa, pb, vl16);
- vbool8_t pa_le_pc = __riscv_vmsle_vv_i16m2_b8(pa, pc, vl16);
- vbool8_t pb_le_pc = __riscv_vmsle_vv_i16m2_b8(pb, pc, vl16);
-
- /* use_a = pa <= pb && pa <= pc */
- vbool8_t use_a = __riscv_vmand_mm_b8(pa_le_pb, pa_le_pc, vl16);
-
- /* use_b = !use_a && pb <= pc */
- vbool8_t not_use_a = __riscv_vmnot_m_b8(use_a, vl16);
- vbool8_t use_b = __riscv_vmand_mm_b8(not_use_a, pb_le_pc, vl16);
+ /* if (pb < pa) { pa = pb; a = b; } */
+ vbool8_t m1 = __riscv_vmsltu_vv_u16m2_b8(pb, pa, vl);
+ pa = __riscv_vmerge_vvm_u16m2(pa, pb, m1, vl);
+ a = __riscv_vmerge_vvm_u8m1(a, b, m1, vl);
- /* Switch back to e8m1 for final operations */
- vl = __riscv_vsetvl_e8m1(bpp);
-
- /* Start with a, then conditionally replace with b or c */
- vuint8m1_t result = a;
- result = __riscv_vmerge_vvm_u8m1(result, b, use_b, vl);
-
- /* use_c = !use_a && !use_b */
- vbool8_t use_c = __riscv_vmnand_mm_b8(__riscv_vmor_mm_b8(use_a, use_b, vl), __riscv_vmor_mm_b8(use_a, use_b, vl), vl);
- result = __riscv_vmerge_vvm_u8m1(result, c, use_c, vl);
+ /* if (pc < pa) a = c; */
+ vbool8_t m2 = __riscv_vmsltu_vv_u16m2_b8(pc, pa, vl);
+ a = __riscv_vmerge_vvm_u8m1(a, c, m2, vl);
/* a = result + x */
- a = __riscv_vadd_vv_u8m1(result, x, vl);
+ a = __riscv_vadd_vv_u8m1(a, x, vl);
/* *row = a */
__riscv_vse8_v_u8m1(row, a, vl);