Skip to content

Commit

Permalink
Separate patch validation from drawing.
Browse files Browse the repository at this point in the history
Once the format has been validated, further logic can be significantly
simplified since we know it's not going to lead to a buffer overflow
or similar.
  • Loading branch information
fragglet committed Aug 10, 2024
1 parent a01afc9 commit 973f437
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/conv/graphic.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,13 @@ VFILE *V_FlatFromImageFile(VFILE *input, const struct palette *pal)
return result;
}

static bool DrawPatch(const struct patch_header *hdr, uint8_t *srcbuf,
size_t srcbuf_len, uint8_t *dstbuf)
static bool ValidatePatch(const struct patch_header *hdr,
const uint8_t *srcbuf, size_t srcbuf_len)
{
uint32_t *columnofs =
(uint32_t *) (srcbuf + sizeof(struct patch_header));
uint32_t off;
int x, y, i, cnt;

memset(dstbuf, PALETTE_TRANSPARENT, hdr->width * hdr->height);
int x;

for (x = 0; x < hdr->width; ++x) {
off = columnofs[x];
Expand All @@ -248,6 +246,27 @@ static bool DrawPatch(const struct patch_header *hdr, uint8_t *srcbuf,
"overruns the end of lump", x);
return false;
}
off += 4 + srcbuf[off + 1];
}
}

return true;
}

static void DrawPatch(const struct patch_header *hdr, uint8_t *srcbuf,
size_t srcbuf_len, uint8_t *dstbuf)
{
uint32_t *columnofs =
(uint32_t *) (srcbuf + sizeof(struct patch_header));
uint32_t off;
int x, y, i, cnt;

memset(dstbuf, PALETTE_TRANSPARENT, hdr->width * hdr->height);

for (x = 0; x < hdr->width; ++x) {
off = columnofs[x];
SwapLE32(&off);
while (srcbuf[off] != 0xff) {
y = srcbuf[off];
cnt = srcbuf[off + 1];
off += 3;
Expand All @@ -261,8 +280,6 @@ static bool DrawPatch(const struct patch_header *hdr, uint8_t *srcbuf,
off++;
}
}

return true;
}

VFILE *V_ToImageFile(VFILE *input, const struct palette *pal)
Expand All @@ -282,10 +299,12 @@ VFILE *V_ToImageFile(VFILE *input, const struct palette *pal)
hdr = *((struct patch_header *) buf);
V_SwapPatchHeader(&hdr);
imgbuf = checked_malloc(hdr.width * hdr.height);
if (!DrawPatch(&hdr, buf, buf_len, imgbuf)) {
if (!ValidatePatch(&hdr, buf, buf_len)) {
goto fail;
}

DrawPatch(&hdr, buf, buf_len, imgbuf);

result = V_WritePalettizedPNG(&hdr, imgbuf, pal, true);

fail:
Expand Down

0 comments on commit 973f437

Please sign in to comment.