125 lines
4.2 KiB
Diff
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;
|