gimp/SOURCES/gimp-CVE-2025-48797.patch
2025-06-17 10:24:43 +00:00

125 lines
4.2 KiB
Diff

diff -urNp a/plug-ins/common/file-tga.c b/plug-ins/common/file-tga.c
--- a/plug-ins/common/file-tga.c 2025-06-14 14:36:28.298535906 +0200
+++ b/plug-ins/common/file-tga.c 2025-06-14 14:50:52.545808264 +0200
@@ -555,7 +555,7 @@ load_image (const gchar *filename,
switch (info.imageType)
{
case TGA_TYPE_MAPPED:
- if (info.bpp != 8)
+ if (info.bpp != 8 || !info.colorMapLength)
{
g_message ("Unhandled sub-format in '%s' (type = %u, bpp = %u)",
gimp_filename_to_utf8 (filename),
@@ -870,32 +870,46 @@ apply_colormap (guchar *dest,
guint width,
const guchar *cmap,
gboolean alpha,
- guint16 index)
+ guint16 colorMapIndex,
+ guint16 colorMapLength)
{
guint x;
+ gint errcnt = 0;
- if (alpha)
- {
- for (x = 0; x < width; x++)
- {
- *(dest++) = cmap[(*src - index) * 4];
- *(dest++) = cmap[(*src - index) * 4 + 1];
- *(dest++) = cmap[(*src - index) * 4 + 2];
- *(dest++) = cmap[(*src - index) * 4 + 3];
-
- src++;
- }
- }
- else
+ for (x = 0; x < width; x++)
{
- for (x = 0; x < width; x++)
- {
- *(dest++) = cmap[(*src - index) * 3];
- *(dest++) = cmap[(*src - index) * 3 + 1];
- *(dest++) = cmap[(*src - index) * 3 + 2];
+ guchar entryIndex = src[x] - colorMapIndex;
- src++;
- }
+ if (src[x] < colorMapIndex || entryIndex >= colorMapLength) {
+ /* On Windows the error console can run out of resources when
+ * producing a huge amount of messages. This can happen when using
+ * fuzzed test images. This causes unresponsiveness at first and
+ * finally crashes GIMP. Eventually this needs to be fixed at the
+ * source, but for now let's limit the error messages to 10
+ * per line (this function is called once per read_line). */
+ if (errcnt < 10)
+ {
+ g_message ("Unsupported colormap entry: %u",
+ src[x]);
+ }
+ else if (errcnt == 10)
+ {
+ g_message ("Too many colormap errors. Image may be corrupt.");
+ }
+ errcnt++;
+ entryIndex = 0;
+ }
+
+ if (alpha) {
+ *(dest++) = cmap[entryIndex * 4];
+ *(dest++) = cmap[entryIndex * 4 + 1];
+ *(dest++) = cmap[entryIndex * 4 + 2];
+ *(dest++) = cmap[entryIndex * 4 + 3];
+ } else {
+ *(dest++) = cmap[entryIndex * 3];
+ *(dest++) = cmap[entryIndex * 3 + 1];
+ *(dest++) = cmap[entryIndex * 3 + 2];
+ }
}
}
@@ -951,7 +965,7 @@ read_line (FILE *fp,
gboolean has_alpha = (info->alphaBits > 0);
apply_colormap (row, buffer, info->width, convert_cmap, has_alpha,
- info->colorMapIndex);
+ info->colorMapIndex, info->colorMapLength);
}
else if (info->imageType == TGA_TYPE_MAPPED)
{
@@ -961,7 +975,7 @@ read_line (FILE *fp,
}
else
{
- memcpy (row, buffer, info->width * drawable->bpp);
+ memcpy (row, buffer, info->width * info->bytes);
}
}
@@ -993,9 +1007,9 @@ ReadImage (FILE *fp,
cmap_bytes = (info->colorMapSize + 7 ) / 8;
tga_cmap = g_new (guchar, info->colorMapLength * cmap_bytes);
- if (info->colorMapSize > 24)
+ if (info->colorMapSize > 24 || info->alphaBits > 0)
{
- /* indexed + full alpha => promoted to RGBA */
+ /* indexed + full alpha, or alpha exists => promoted to RGBA */
itype = GIMP_RGB;
dtype = GIMP_RGBA_IMAGE;
convert_cmap = g_new (guchar, info->colorMapLength * 4);
@@ -1007,13 +1021,6 @@ ReadImage (FILE *fp,
dtype = GIMP_RGB_IMAGE;
convert_cmap = g_new (guchar, info->colorMapLength * 3);
}
- else if (info->alphaBits > 0)
- {
- /* if alpha exists here, promote to RGB */
- itype = GIMP_RGB;
- dtype = GIMP_RGBA_IMAGE;
- convert_cmap = g_new (guchar, info->colorMapLength * 4);
- }
else
{
itype = GIMP_INDEXED;