Check if patch data is valid before creating it

This commit is contained in:
Lactozilla 2025-01-28 20:29:51 -03:00
parent 8701ef41f6
commit 6ba33a39e5
8 changed files with 52 additions and 44 deletions

View file

@ -1737,6 +1737,8 @@ static void CON_DrawBackpic(void)
// Cache the patch.
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
if (con_backpic == NULL)
return;
// Center the backpic, and draw a vertically cropped patch.
w = con_backpic->width * vid.dup;

View file

@ -483,10 +483,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
}
HWR_DrawTexturePatchInCache(mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (realpatch != NULL)
{
HWR_DrawTexturePatchInCache(mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (free_patch)
Patch_Free(realpatch);
if (free_patch)
Patch_Free(realpatch);
}
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(mipmap->format)==4)

View file

@ -31,14 +31,12 @@ patch_t *Patch_Create(INT16 width, INT16 height)
return patch;
}
patch_t *Patch_CreateFromDoomPatch(softwarepatch_t *source)
patch_t *Patch_CreateFromDoomPatch(softwarepatch_t *source, size_t insize)
{
patch_t *patch = Patch_Create(0, 0);
if (!source)
return patch;
if (!Picture_CheckIfDoomPatch(source, insize))
return NULL;
patch->width = SHORT(source->width);
patch->height = SHORT(source->height);
patch_t *patch = Patch_Create(SHORT(source->width), SHORT(source->height));
patch->leftoffset = SHORT(source->leftoffset);
patch->topoffset = SHORT(source->topoffset);

View file

@ -19,7 +19,7 @@
// Patch functions
patch_t *Patch_Create(INT16 width, INT16 height);
patch_t *Patch_CreateFromDoomPatch(softwarepatch_t *source);
patch_t *Patch_CreateFromDoomPatch(softwarepatch_t *source, size_t insize);
void Patch_CalcDataSizes(softwarepatch_t *source, size_t *total_pixels, size_t *total_posts);
void Patch_MakeColumns(softwarepatch_t *source, size_t num_columns, INT16 width, UINT8 *pixels, column_t *columns, post_t *posts, boolean flip);
void Patch_Free(patch_t *patch);

View file

@ -87,7 +87,12 @@ void *Picture_Convert(
(void)insize;
if (Picture_IsPatchFormat(outformat))
return Picture_PatchConvert(informat, picture, outformat, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
{
void *converted = Picture_PatchConvert(informat, insize, picture, outformat, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
if (converted == NULL)
I_Error("Picture_Convert: conversion to patch did not result in a valid graphic");
return converted;
}
else if (Picture_IsFlatFormat(outformat))
return Picture_FlatConvert(informat, picture, outformat, outsize, inwidth, intopoffset, flags);
else
@ -235,8 +240,8 @@ static void *WritePatchPixel_i8o8(void *ptr, void *input)
* \return A pointer to the converted picture.
*/
void *Picture_PatchConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t *outsize,
pictureformat_t informat, size_t insize, void *picture,
pictureformat_t outformat, size_t *outsize,
INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
pictureflags_t flags)
{
@ -245,7 +250,7 @@ void *Picture_PatchConvert(
{
if (outsize != NULL)
*outsize = sizeof(patch_t);
return Patch_CreateFromDoomPatch(picture);
return Patch_CreateFromDoomPatch(picture, insize);
}
INT32 outbpp = Picture_FormatBPP(outformat);
@ -799,47 +804,38 @@ boolean Picture_IsFlatFormat(pictureformat_t format)
}
/** Returns true if the lump is a valid Doom patch.
* PICFMT_DOOMPATCH only.
*
* \param patch Input patch.
* \param picture Input patch size.
* \return True if the input patch is valid.
* \return True if the input patch is valid, false if not.
*/
boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size)
{
INT16 width, height;
boolean result;
// minimum length of a valid Doom patch
// Minimum length of a valid Doom patch
if (size < 13)
return false;
width = SHORT(patch->width);
height = SHORT(patch->height);
result = (height > 0 && height <= 16384 && width > 0 && width <= 16384);
INT16 width = SHORT(patch->width);
INT16 height = SHORT(patch->height);
if (width <= 0 || height <= 0)
return false;
if (result)
// The dimensions seem like they might be valid for a patch, so
// check the column directory for extra security. All columns
// must begin after the column directory, and none of them must
// point past the end of the patch.
for (INT16 x = 0; x < width; x++)
{
// The dimensions seem like they might be valid for a patch, so
// check the column directory for extra security. All columns
// must begin after the column directory, and none of them must
// point past the end of the patch.
INT16 x;
UINT32 ofs = LONG(patch->columnofs[x]);
for (x = 0; x < width; x++)
// Need one byte for an empty column (but there's patches that don't know that!)
if (ofs < (UINT32)width * 4 + 8 || ofs >= (UINT32)size)
{
UINT32 ofs = LONG(patch->columnofs[x]);
// Need one byte for an empty column (but there's patches that don't know that!)
if (ofs < (UINT32)width * 4 + 8 || ofs >= (UINT32)size)
{
result = false;
break;
}
return false;
}
}
return result;
return true;
}
/** Converts a texture to a flat.
@ -1373,7 +1369,9 @@ void *Picture_PNGConvert(
}
// Now, convert it!
converted = Picture_PatchConvert(informat, flat, outformat, outsize, (INT32)width, (INT32)height, *leftoffset, *topoffset, flags);
converted = Picture_PatchConvert(informat, flatsize, flat, outformat, outsize, (INT32)width, (INT32)height, *leftoffset, *topoffset, flags);
if (converted == NULL)
I_Error("Picture_PNGConvert: conversion to patch did not result in a valid graphic");
Z_Free(flat);
return converted;
}

View file

@ -62,8 +62,8 @@ void *Picture_Convert(
pictureflags_t flags);
void *Picture_PatchConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t *outsize,
pictureformat_t informat, size_t insize, void *picture,
pictureformat_t outformat, size_t *outsize,
INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
pictureflags_t flags);
void *Picture_FlatConvert(

View file

@ -430,6 +430,10 @@ UINT8 *R_GenerateTexture(size_t texnum)
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
}
// Well, it's not valid...
if (realpatch == NULL)
continue;
x1 = patch->originx;
width = realpatch->width;
height = realpatch->height;

View file

@ -2383,9 +2383,12 @@ static void *W_GetPatchPwad(UINT16 wad, UINT16 lump, INT32 tag)
#endif
}
dest = Patch_CreateFromDoomPatch(ptr);
dest = Patch_CreateFromDoomPatch(ptr, len);
Z_Free(ptr);
if (dest == NULL)
return NULL;
Z_ChangeTag(dest, tag);
Z_SetUser(dest, &lumpcache[lump]);
}
@ -2403,7 +2406,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
patch_t *patch = W_GetPatchPwad(wad, lump, tag);
#ifdef HWRENDER
if (rendermode == render_opengl)
if (patch != NULL && rendermode == render_opengl)
Patch_CreateGL(patch);
#endif