Add size checks for WAL load

This commit is contained in:
Denis Pauk 2018-03-25 11:51:29 +03:00
parent 511b73baf9
commit 14af679b7e
4 changed files with 100 additions and 24 deletions

View file

@ -34,14 +34,21 @@ void
GetWalInfo(char *name, int *width, int *height)
{
miptex_t *mt;
int size;
ri.FS_LoadFile(name, (void **)&mt);
size = ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
return;
}
if (size < sizeof(miptex_t))
{
ri.FS_FreeFile((void *)mt);
return;
}
*width = LittleLong(mt->width);
*height = LittleLong(mt->height);

View file

@ -1013,10 +1013,10 @@ R_LoadPic(char *name, byte *pic, int width, int realwidth,
}
static image_t *
LoadWal(char *origname)
LoadWal(char *origname, imagetype_t type)
{
miptex_t *mt;
int width, height, ofs;
int width, height, ofs, size;
image_t *image;
char name[256];
@ -1028,7 +1028,7 @@ LoadWal(char *origname)
Q_strlcat(name, ".wal", sizeof(name));
}
ri.FS_LoadFile(name, (void **)&mt);
size = ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
@ -1036,11 +1036,26 @@ LoadWal(char *origname)
return r_notexture;
}
if (size < sizeof(miptex_t))
{
R_Printf(PRINT_ALL, "LoadWal: can't load %s, small header\n", name);
ri.FS_FreeFile((void *)mt);
return r_notexture;
}
width = LittleLong(mt->width);
height = LittleLong(mt->height);
ofs = LittleLong(mt->offsets[0]);
image = R_LoadPic(name, (byte *)mt + ofs, width, 0, height, 0, it_wall, 8);
if ((ofs <= 0) || (width <= 0) || (height <= 0) ||
(((size - ofs) / height) < width))
{
R_Printf(PRINT_ALL, "LoadWal: can't load %s, small body\n", name);
ri.FS_FreeFile((void *)mt);
return r_notexture;
}
image = R_LoadPic(name, (byte *)mt + ofs, width, 0, height, 0, type, 8);
ri.FS_FreeFile((void *)mt);
@ -1078,7 +1093,7 @@ R_FindImage(char *name, imagetype_t type)
/* Remove the extension */
memset(namewe, 0, 256);
memcpy(namewe, name, len - 4);
memcpy(namewe, name, len - (strlen(ext) + 1));
if (len < 5)
{
@ -1175,7 +1190,7 @@ R_FindImage(char *name, imagetype_t type)
else
{
/* WAL if no TGA/PNG/JPEG available (exists always) */
image = LoadWal(namewe);
image = LoadWal(namewe, type);
}
if (!image)
@ -1186,7 +1201,7 @@ R_FindImage(char *name, imagetype_t type)
}
else /* gl_retexture is not set */
{
image = LoadWal(name);
image = LoadWal(name, type);
if (!image)
{

View file

@ -550,10 +550,10 @@ GL3_LoadPic(char *name, byte *pic, int width, int realwidth,
}
static gl3image_t *
LoadWal(char *origname)
LoadWal(char *origname, imagetype_t type)
{
miptex_t *mt;
int width, height, ofs;
int width, height, ofs, size;
gl3image_t *image;
char name[256];
@ -565,7 +565,7 @@ LoadWal(char *origname)
Q_strlcat(name, ".wal", sizeof(name));
}
ri.FS_LoadFile(name, (void **)&mt);
size = ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
@ -573,11 +573,26 @@ LoadWal(char *origname)
return gl3_notexture;
}
if (size < sizeof(miptex_t))
{
R_Printf(PRINT_ALL, "LoadWal: can't load %s, small header\n", name);
ri.FS_FreeFile((void *)mt);
return gl3_notexture;
}
width = LittleLong(mt->width);
height = LittleLong(mt->height);
ofs = LittleLong(mt->offsets[0]);
image = GL3_LoadPic(name, (byte *)mt + ofs, width, 0, height, 0, it_wall, 8);
if ((ofs <= 0) || (width <= 0) || (height <= 0) ||
(((size - ofs) / height) < width))
{
R_Printf(PRINT_ALL, "LoadWal: can't load %s, small body\n", name);
ri.FS_FreeFile((void *)mt);
return gl3_notexture;
}
image = GL3_LoadPic(name, (byte *)mt + ofs, width, 0, height, 0, type, 8);
ri.FS_FreeFile((void *)mt);
@ -615,7 +630,7 @@ GL3_FindImage(char *name, imagetype_t type)
/* Remove the extension */
memset(namewe, 0, 256);
memcpy(namewe, name, len - 4);
memcpy(namewe, name, len - (strlen(ext) + 1));
if (len < 5)
{
@ -711,7 +726,7 @@ GL3_FindImage(char *name, imagetype_t type)
else
{
/* WAL if no TGA/PNG/JPEG available (exists always) */
image = LoadWal(namewe);
image = LoadWal(namewe, type);
}
if (!image)
@ -722,7 +737,7 @@ GL3_FindImage(char *name, imagetype_t type)
}
else /* gl_retexture is not set */
{
image = LoadWal(name);
image = LoadWal(name, type);
if (!image)
{

View file

@ -133,41 +133,80 @@ R_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type)
return image;
}
static void
R_Restore_Mip(unsigned char* src, unsigned char *dst, int height, int width)
{
int x, y;
for (y=0; y<height; y++)
{
for (x=0; x<width; x++)
{
dst[x + y * width] = src[(x + y * width)*2];
}
}
}
/*
================
R_LoadWal
================
*/
static image_t *
R_LoadWal (char *name)
R_LoadWal (char *name, imagetype_t type)
{
miptex_t *mt;
int ofs;
int ofs;
image_t *image;
int size;
int size, file_size;
ri.FS_LoadFile (name, (void **)&mt);
file_size = ri.FS_LoadFile (name, (void **)&mt);
if (!mt)
{
R_Printf(PRINT_ALL, "R_LoadWal: can't load %s\n", name);
return r_notexture_mip;
}
if (file_size < sizeof(miptex_t))
{
R_Printf(PRINT_ALL, "R_LoadWal: can't load %s, small header\n", name);
ri.FS_FreeFile ((void *)mt);
return r_notexture_mip;
}
image = R_FindFreeImage ();
strcpy (image->name, name);
image->width = LittleLong (mt->width);
image->height = LittleLong (mt->height);
image->type = it_wall;
image->type = type;
image->registration_sequence = registration_sequence;
ofs = LittleLong (mt->offsets[0]);
size = image->width * image->height * (256+64+16+4)/256;
if ((ofs <= 0) || (image->width <= 0) || (image->height <= 0) ||
((file_size - ofs) / image->width < image->height))
{
R_Printf(PRINT_ALL, "LoadWal: can't load %s, small body\n", name);
ri.FS_FreeFile((void *)mt);
return r_notexture_mip;
}
size = image->width*image->height * (256+64+16+4)/256;
image->pixels[0] = malloc (size);
image->pixels[1] = image->pixels[0] + image->width*image->height;
image->pixels[2] = image->pixels[1] + image->width*image->height/4;
image->pixels[3] = image->pixels[2] + image->width*image->height/16;
ofs = LittleLong (mt->offsets[0]);
memcpy ( image->pixels[0], (byte *)mt + ofs, size);
if (size > (file_size - ofs))
{
memcpy ( image->pixels[0], (byte *)mt + ofs, file_size - ofs);
// looks to short restore everything from first image
R_Restore_Mip(image->pixels[0], image->pixels[1], image->height/2, image->width/2);
R_Restore_Mip(image->pixels[1], image->pixels[2], image->height/4, image->width/4);
R_Restore_Mip(image->pixels[2], image->pixels[3], image->height/8, image->width/8);
}
else
{
memcpy ( image->pixels[0], (byte *)mt + ofs, size);
}
ri.FS_FreeFile ((void *)mt);
@ -228,7 +267,7 @@ image_t *R_FindImage (char *name, imagetype_t type)
}
else if (!strcmp(name+len-4, ".wal"))
{
image = R_LoadWal (name);
image = R_LoadWal (name, type);
}
else if (!strcmp(name+len-4, ".tga"))
return NULL; // ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s in software renderer", name);