[gimp/gimp-2-10] plug-ins: fix #8411 crash when attempting to open PSD
- From: Jacob Boerema <jboerema src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] plug-ins: fix #8411 crash when attempting to open PSD
- Date: Wed, 3 Aug 2022 23:13:13 +0000 (UTC)
commit 8352d80de6c3587a40ef5e4cfc195a2afa53039c
Author: Jacob Boerema <jgboerema gmail com>
Date: Wed Aug 3 17:32:34 2022 -0400
plug-ins: fix #8411 crash when attempting to open PSD
Apparently some layers in PSD files can have extra channels which we
did not account for when computing destination offsets, causing crashes.
So let's make sure we don't include the "extra" channels when computing
the offsets by introducing base_channels. We also move the alpha channel
in the spot of the first extra channel (even though it seems, based on
the one example we have, that the extra channel might be the same as
the alpha channel).
(cherry picked from commit 5fbd06629de33191ba58450942aee4385829ef89)
# Conflicts:
# plug-ins/file-psd/psd-load.c
plug-ins/file-psd/psd-load.c | 48 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 8 deletions(-)
---
diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c
index 8d53d384c2..d5a0b2ad44 100644
--- a/plug-ins/file-psd/psd-load.c
+++ b/plug-ins/file-psd/psd-load.c
@@ -1268,7 +1268,7 @@ add_layers (gint32 image_id,
gint32 parent_group_id = -1;
guint16 alpha_chn;
guint16 user_mask_chn;
- guint16 layer_channels;
+ guint16 layer_channels, base_channels;
guint16 channel_idx[MAX_CHANNELS];
guint16 *rle_pack_len;
guint16 bps;
@@ -1498,6 +1498,13 @@ add_layers (gint32 image_id,
else
parent_group_id = -1; /* root */
+ if (img_a->color_mode == PSD_CMYK)
+ base_channels = 4;
+ else if (img_a->color_mode == PSD_RGB || img_a->color_mode == PSD_LAB)
+ base_channels = 3;
+ else
+ base_channels = 1;
+
IFDBG(3) g_debug ("Re-hash channel indices");
for (cidx = 0; cidx < lyr_a[lidx]->num_channels; ++cidx)
{
@@ -1513,15 +1520,40 @@ add_layers (gint32 image_id,
}
else if (lyr_chn[cidx]->data)
{
- channel_idx[layer_channels] = cidx; /* Assumes in sane order */
- layer_channels++; /* RGB, Lab, CMYK etc. */
+ if (layer_channels < base_channels)
+ {
+ channel_idx[layer_channels] = cidx; /* Assumes in sane order */
+ layer_channels++; /* RGB, Lab, CMYK etc. */
+ }
+ else
+ {
+ /* channel_idx[base_channels] is reserved for alpha channel,
+ * but this layer apparently has extra channels.
+ * From the one example I have (see #8411) it looks like
+ * that channel is the same as the alpha channel. */
+ IFDBG(2) g_debug ("This layer has an extra channel (id: %d)", lyr_chn[cidx]->id);
+ channel_idx[layer_channels+1] = cidx; /* Assumes in sane order */
+ layer_channels += 2; /* RGB, Lab, CMYK etc. */
+ }
+ }
+ else
+ {
+ IFDBG(4) g_debug ("Channel %d (id: %d) has no data", cidx, lyr_chn[cidx]->id);
}
}
if (alpha)
{
- channel_idx[layer_channels] = alpha_chn;
- layer_channels++;
+ if (layer_channels <= base_channels)
+ {
+ channel_idx[layer_channels] = alpha_chn;
+ layer_channels++;
+ }
+ else
+ {
+ channel_idx[base_channels] = alpha_chn;
+ }
+ base_channels++;
}
/* Create the layer */
@@ -1687,15 +1719,15 @@ add_layers (gint32 image_id,
const GeglRectangle *roi = &iter->items[0].roi;
guint8 *dst0 = iter->items[0].data;
gint src_step = bps;
- gint dst_step = bps * layer_channels;
+ gint dst_step = bps * base_channels;
if (img_a->color_mode == PSD_CMYK)
{
- dst0 = gegl_scratch_alloc (layer_channels *
+ dst0 = gegl_scratch_alloc (base_channels *
iter->length);
}
- for (cidx = 0; cidx < layer_channels; ++cidx)
+ for (cidx = 0; cidx < base_channels; ++cidx)
{
gint b;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]