Amiga: clamp amii_numcolors and guard tile CMAP loop

Reject tile/tomb IFF files whose nPlanes field exceeds DEPTH:
the CMAP loop writes 1<<np entries into amii_initmap[] /
amiv_init_map[], both sized AMII_MAXCOLORS = 1<<DEPTH = 64, so
a malformed file with nPlanes >= 7 would corrupt adjacent BSS.

After OpenScreen succeeds, clamp amii_numcolors to the actually
populated portion of the init-map arrays (AMII_PALETTE_SIZE for
text mode, AMIV_PALETTE_SIZE for tile mode).  On a 64-color
screen this stops LoadRGB4 from loading the zero-initialized
tail entries as black.  Replace the matching magic 32 in the
tilefile selection with AMIV_PALETTE_SIZE.

While there, add the (char) cast on amii_glyph_buffer's
truncating assignment to make the contract explicit.
This commit is contained in:
Ingo Paschke
2026-05-12 15:30:48 +02:00
parent 459113a48e
commit 146fbf20d8
2 changed files with 14 additions and 3 deletions
+7 -1
View File
@@ -130,6 +130,12 @@ ReadImageFile(const char *filename, struct BitMap **bmp)
bmhd = (BitMapHeader *) prop->sp_Data;
np = bmhd->nPlanes;
if (np > DEPTH) {
errfmt = "%s: too many bitplanes (code %ld)";
errcode = np;
goto cleanup;
}
/* Load CMAP into palette arrays if present */
prop = FindProp(iff, ID_BMAP, ID_CMAP);
if (prop) {
@@ -819,7 +825,7 @@ amii_lprint_glyph(winid window, int color_index, int glyph)
/*
* Add it to the end of the buffer
*/
amii_glyph_buffer[glyph_buffer_index++] = glyph;
amii_glyph_buffer[glyph_buffer_index++] = (char) glyph;
amii_g_nodes[glyph_node_index - 1].len++;
} else {
/* See if we're out of glyph nodes */
+7 -2
View File
@@ -1219,9 +1219,9 @@ amii_init_nhwindows(int *argcp, char **argv)
if (WINVERS_AMIV) {
extern char *tilefile;
if (amii_numcolors >= 32) {
if (amii_numcolors >= AMIV_PALETTE_SIZE) {
tilefile = (char *) fqname("tiles/tiles32.iff", DATAPREFIX, 0);
amii_numcolors = 32;
amii_numcolors = AMIV_PALETTE_SIZE;
} else {
tilefile = (char *) fqname("tiles/tiles16.iff", DATAPREFIX, 0);
}
@@ -1257,6 +1257,11 @@ amii_init_nhwindows(int *argcp, char **argv)
Abort(AN_OpenScreen & ~AT_DeadEnd);
}
amii_numcolors = 1UL << NewHackScreen.Depth;
{
int palmax = WINVERS_AMIV ? AMIV_PALETTE_SIZE : AMII_PALETTE_SIZE;
if (amii_numcolors > palmax)
amii_numcolors = palmax;
}
if (HackScreen->Height > 300 && forcenobig == 0)
bigscreen = 1;
else