diff options
Diffstat (limited to 'src/renderer/tr_model.c')
-rw-r--r-- | src/renderer/tr_model.c | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/src/renderer/tr_model.c b/src/renderer/tr_model.c index 8fdd0adb..b4ca744f 100644 --- a/src/renderer/tr_model.c +++ b/src/renderer/tr_model.c @@ -405,13 +405,13 @@ static qboolean R_LoadMD3 (model_t *mod, int lod, void *buffer, const char *mod_ } +#ifdef RAVENMD4 /* ================= R_LoadMDR ================= */ -#ifdef RAVENMD4 static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char *mod_name ) { int i, j, k, l; @@ -445,10 +445,10 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char mod->type = MOD_MDR; - pinmodel->numFrames = LittleLong(pinmodel->numFrames); - pinmodel->numBones = LittleLong(pinmodel->numBones); - pinmodel->ofsFrames = LittleLong(pinmodel->ofsFrames); - + LL(pinmodel->numFrames); + LL(pinmodel->numBones); + LL(pinmodel->ofsFrames); + // This is a model that uses some type of compressed Bones. We don't want to uncompress every bone for each rendered frame // over and over again, we'll uncompress it in this function already, so we must adjust the size of the target md4. if(pinmodel->ofsFrames < 0) @@ -459,6 +459,14 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char size += pinmodel->numFrames * pinmodel->numBones * ((sizeof(mdrBone_t) - sizeof(mdrCompBone_t))); } + // simple bounds check + if(pinmodel->numBones < 0 || + sizeof(*mdr) + pinmodel->numFrames * (sizeof(*frame) + (pinmodel->numBones - 1) * sizeof(*frame->bones)) > size) + { + ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name); + return qfalse; + } + mod->dataSize += size; mod->md4 = mdr = ri.Hunk_Alloc( size, h_low ); @@ -471,8 +479,8 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char mdr->numBones = pinmodel->numBones; mdr->numLODs = LittleLong(pinmodel->numLODs); mdr->numTags = LittleLong(pinmodel->numTags); - // We don't care about offset values, we'll generate them ourselves while loading. - + // We don't care about the other offset values, we'll generate them ourselves while loading. + mod->numLods = mdr->numLODs; if ( mdr->numFrames < 1 ) @@ -491,7 +499,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char // compressed model... cframe = (mdrCompFrame_t *)((byte *) pinmodel - pinmodel->ofsFrames); - + for(i = 0; i < mdr->numFrames; i++) { for(j = 0; j < 3; j++) @@ -566,6 +574,13 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char // swap all the LOD's for ( l = 0 ; l < mdr->numLODs ; l++) { + // simple bounds check + if((byte *) (lod + 1) > (byte *) mdr + size) + { + ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name); + return qfalse; + } + lod->numSurfaces = LittleLong(curlod->numSurfaces); // swap all the surfaces @@ -573,7 +588,15 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char lod->ofsSurfaces = (int)((byte *) surf - (byte *) lod); cursurf = (mdrSurface_t *) ((byte *)curlod + LittleLong(curlod->ofsSurfaces)); - for ( i = 0 ; i < lod->numSurfaces ; i++) { + for ( i = 0 ; i < lod->numSurfaces ; i++) + { + // simple bounds check + if((byte *) (surf + 1) > (byte *) mdr + size) + { + ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name); + return qfalse; + } + // first do some copying stuff surf->ident = SF_MDR; @@ -617,6 +640,15 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char for(j = 0; j < surf->numVerts; j++) { + LL(curv->numWeights); + + // simple bounds check + if(curv->numWeights < 0 || (byte *) (v + 1) + (curv->numWeights - 1) * sizeof(*weight) > (byte *) mdr + size) + { + ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name); + return qfalse; + } + v->normal[0] = LittleFloat(curv->normal[0]); v->normal[1] = LittleFloat(curv->normal[1]); v->normal[2] = LittleFloat(curv->normal[2]); @@ -624,7 +656,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char v->texCoords[0] = LittleFloat(curv->texCoords[0]); v->texCoords[1] = LittleFloat(curv->texCoords[1]); - v->numWeights = LittleLong(curv->numWeights); + v->numWeights = curv->numWeights; weight = &v->weights[0]; curweight = &curv->weights[0]; @@ -651,6 +683,13 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char surf->ofsTriangles = (int)((byte *) tri - (byte *) surf); curtri = (mdrTriangle_t *)((byte *) cursurf + LittleLong(cursurf->ofsTriangles)); + // simple bounds check + if(surf->numTriangles < 0 || (byte *) (tri + surf->numTriangles) > (byte *) mdr + size) + { + ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name); + return qfalse; + } + for(j = 0; j < surf->numTriangles; j++) { tri->indexes[0] = LittleLong(curtri->indexes[0]); @@ -681,6 +720,13 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char tag = (mdrTag_t *) lod; mdr->ofsTags = (int)((byte *) tag - (byte *) mdr); curtag = (mdrTag_t *) ((byte *)pinmodel + LittleLong(pinmodel->ofsTags)); + + // simple bounds check + if(mdr->numTags < 0 || (byte *) (tag + mdr->numTags) > (byte *) mdr + size) + { + ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name); + return qfalse; + } for (i = 0 ; i < mdr->numTags ; i++) { @@ -691,7 +737,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char curtag++; } - // And finally we know the offset to the end. + // And finally we know the real offset to the end. mdr->ofsEnd = (int)((byte *) tag - (byte *) mdr); // phew! we're done. @@ -876,7 +922,7 @@ void RE_BeginRegistration( glconfig_t *glconfigOut ) { // NOTE: this sucks, for some reason the first stretch pic is never drawn // without this we'd see a white flash on a level load because the very // first time the level shot would not be drawn - RE_StretchPic(0, 0, 0, 0, 0, 0, 1, 1, 0); +// RE_StretchPic(0, 0, 0, 0, 0, 0, 1, 1, 0); } //============================================================================= |