[gimp] 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] plug-ins: fix #8411 crash when attempting to open PSD
- Date: Wed, 3 Aug 2022 23:09:18 +0000 (UTC)
commit 5fbd06629de33191ba58450942aee4385829ef89
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).
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 3ead2ff199..cd41f23eb2 100644
--- a/plug-ins/file-psd/psd-load.c
+++ b/plug-ins/file-psd/psd-load.c
@@ -1573,7 +1573,7 @@ add_layers (GimpImage *image,
GimpLayer *clipping_group = NULL;
guint16 alpha_chn;
guint16 user_mask_chn;
- guint16 layer_channels;
+ guint16 layer_channels, base_channels;
guint16 channel_idx[MAX_CHANNELS];
guint16 bps;
gint32 l_x; /* Layer x */
@@ -1856,6 +1856,13 @@ add_layers (GimpImage *image,
else
parent_group = NULL; /* 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)
{
@@ -1872,15 +1879,40 @@ add_layers (GimpImage *image,
}
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++;
}
IFDBG(4) g_debug ("Create the layer (group type: %d, clipping group type: %d)",
@@ -2066,15 +2098,15 @@ add_layers (GimpImage *image,
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 || img_a->color_mode == PSD_LAB)
{
- dst0 = gegl_scratch_alloc (layer_channels * bps *
+ dst0 = gegl_scratch_alloc (base_channels * bps *
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]