From c1b0318b393c90679e6fa5bc1d329fd5d5012ec1 Mon Sep 17 00:00:00 2001
From: Cosmin Truta <ctruta@gmail.com>
Date: Fri, 20 Mar 2026 21:25:12 +0200
Subject: [PATCH] fix: Sync `info_ptr->palette` after in-place transforms

Copy `png_ptr->palette` into `info_ptr->palette` upon entering
the function that runs immediately after the in-place transforms.

The palette decoupling in the previous commit gave `png_struct`
and `png_info` independently-allocated palette buffers, fixing a
use-after-free vulnerability. However, `png_init_read_transformations`
modifies `png_ptr->palette` in place (e.g. for gamma correction or
background compositing), and the old aliasing made those modifications
visible through `png_get_PLTE`. With independent buffers,
`info_ptr->palette` retained the original values, causing our tests to
fail on indexed-colour background compositing.
---
 pngrtran.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Index: libpng-1.6.44/pngrtran.c
===================================================================
--- libpng-1.6.44.orig/pngrtran.c
+++ libpng-1.6.44/pngrtran.c
@@ -1976,6 +1976,21 @@ png_read_transform_info(png_structrp png
 {
    png_debug(1, "in png_read_transform_info");
 
+   if (png_ptr->transformations != 0)
+   {
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+          info_ptr->palette != NULL && png_ptr->palette != NULL)
+      {
+         /* Sync info_ptr->palette with png_ptr->palette.
+          * The function png_init_read_transformations may have modified
+          * png_ptr->palette in place (e.g. for gamma correction or for
+          * background compositing).
+          */
+         memcpy(info_ptr->palette, png_ptr->palette,
+             PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)));
+      }
+   }
+
 #ifdef PNG_READ_EXPAND_SUPPORTED
    if ((png_ptr->transformations & PNG_EXPAND) != 0)
    {
