diff --git a/src/client/refresh/files/wal.c b/src/client/refresh/files/wal.c index 1999d67d..343b45ff 100644 --- a/src/client/refresh/files/wal.c +++ b/src/client/refresh/files/wal.c @@ -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); diff --git a/src/client/refresh/gl1/gl1_image.c b/src/client/refresh/gl1/gl1_image.c index 926409af..dd9829a4 100644 --- a/src/client/refresh/gl1/gl1_image.c +++ b/src/client/refresh/gl1/gl1_image.c @@ -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) { diff --git a/src/client/refresh/gl3/gl3_image.c b/src/client/refresh/gl3/gl3_image.c index 9e3a2704..12d047ee 100644 --- a/src/client/refresh/gl3/gl3_image.c +++ b/src/client/refresh/gl3/gl3_image.c @@ -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) { diff --git a/src/client/refresh/soft/sw_image.c b/src/client/refresh/soft/sw_image.c index f0c41b1e..c24cbebf 100644 --- a/src/client/refresh/soft/sw_image.c +++ b/src/client/refresh/soft/sw_image.c @@ -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; yname, 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);