Skip to content

Commit f911099

Browse files
committed
fix(targa): Protection against corrupt, mis-sized palette
* Check that the palette isn't senselessly bigger than the bpp calls for. * Protection against integer overflow when addressing the palette. Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent 0e42093 commit f911099

4 files changed

Lines changed: 13 additions & 4 deletions

File tree

src/targa.imageio/targainput.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ TGAInput::open(const std::string& name, ImageSpec& newspec)
203203
errorfmt("Palette image with no palette");
204204
return false;
205205
}
206-
207206
if (is_palette()) {
208207
if (m_tga.type == TYPE_GRAY || m_tga.type == TYPE_GRAY_RLE) {
209208
// it should be an error for TYPE_RGB* as well, but apparently some
@@ -216,6 +215,12 @@ TGAInput::open(const std::string& name, ImageSpec& newspec)
216215
errorfmt("Illegal palette entry size: {} bits", m_tga.cmap_size);
217216
return false;
218217
}
218+
if (m_tga.cmap_first + m_tga.cmap_length > (uint64_t(1) << m_tga.bpp)) {
219+
errorfmt(
220+
"Too big a color palette ({}) for {} bpp, assume corruption",
221+
m_tga.cmap_first + m_tga.cmap_length, m_tga.bpp);
222+
return false;
223+
}
219224
}
220225

221226
m_alpha_type = TGA_ALPHA_NONE;
@@ -572,14 +577,14 @@ TGAInput::decode_pixel(unsigned char* in, unsigned char* out,
572577
unsigned char* palette, int bytespp, int palbytespp,
573578
size_t palette_alloc_size)
574579
{
575-
unsigned int k = 0;
580+
uint64_t k = 0;
576581
// I hate nested switches...
577582
switch (m_tga.type) {
578583
case TYPE_PALETTED:
579584
case TYPE_PALETTED_RLE:
580585
for (int i = 0; i < bytespp; ++i)
581586
k |= in[i] << (8 * i); // Assemble it in little endian order
582-
k = (m_tga.cmap_first + k) * palbytespp;
587+
k = (m_tga.cmap_first + k) * uint64_t(palbytespp);
583588
if (k + palbytespp > palette_alloc_size) {
584589
errorfmt("Corrupt palette index");
585590
return false;

testsuite/targa/ref/out.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,17 @@ Full command line was:
201201
oiiotool ERROR: read : "src/crash1707.tga": Invalid alpha type 138. Corrupted header?
202202
Full command line was:
203203
> oiiotool --oiioattrib try_all_readers 0 src/crash1707.tga -o crash1707.exr
204-
oiiotool ERROR: read : "src/crash1708.tga": Corrupt palette index
204+
oiiotool ERROR: read : "src/crash1708.tga": Too big a color palette (382) for 8 bpp, assume corruption
205205
Full command line was:
206206
> oiiotool --oiioattrib try_all_readers 0 src/crash1708.tga -o crash1708.exr
207207
oiiotool ERROR: read : "src/crash3952.tga": Uncompressed image size 15231.5 MB exceeds the 1024 MB limit.
208208
Image claimed to be 60927x65535, 4-channel uint8. Possible corrupt input?
209209
If this is a valid file, raise the OIIO attribute "limits:imagesize_MB".
210210
Full command line was:
211211
> oiiotool --oiioattrib limits:imagesize_MB 1024 --oiioattrib try_all_readers 0 src/crash3952.tga -o crash3952.exr
212+
oiiotool ERROR: read : "src/crash-20250423.tga": Corrupt palette index
213+
Full command line was:
214+
> oiiotool --oiioattrib try_all_readers 0 src/crash-20250423.tga -o out.null
212215
Reading src/1x1.tga
213216
src/1x1.tga : 1 x 1, 3 channel, uint2 targa
214217
SHA-1: DB9237F28F9622F7B7E73B783A8822B63BDB3708

testsuite/targa/run.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
command += oiiotool("--oiioattrib limits:imagesize_MB 1024 "
2828
"--oiioattrib try_all_readers 0 "
2929
"src/crash3952.tga -o crash3952.exr", failureok = True)
30+
command += oiiotool("--oiioattrib try_all_readers 0 src/crash-20250423.tga -o out.null", failureok=True);
3031

3132
# Test odds and ends, unusual files
3233
command += rw_command("src", "1x1.tga")
26 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)