diff options
author | Andrey Nazarov <skuller@skuller.net> | 2013-03-16 19:19:00 +0400 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2013-03-20 22:04:53 +0400 |
commit | 579a26b4dfb7172bc29d9b853f335af310eb114c (patch) | |
tree | e839b21a3a3b1f7a1b0ad99e73c77d4c16b95d7e /src/refresh/sw/model.c | |
parent | f53832714d549a908a83b3528ea385197306b522 (diff) |
Clean up and sanitize alias model drawing.
Validate texture coordinates. Validate vertex normal indices. Check that
skin upload width/height matches model. Draw alias models in solid white
color when skin is missing or found to be invalid.
Diffstat (limited to 'src/refresh/sw/model.c')
-rw-r--r-- | src/refresh/sw/model.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/refresh/sw/model.c b/src/refresh/sw/model.c index 4cf61ec..3a60740 100644 --- a/src/refresh/sw/model.c +++ b/src/refresh/sw/model.c @@ -202,8 +202,8 @@ qerror_t MOD_LoadMD2(model_t *model, const void *rawdata, size_t length) dst_tri = model->tris; for (i = 0; i < header.num_tris; i++, src_tri++, dst_tri++) { for (j = 0; j < 3; j++) { - unsigned idx_xyz = LittleShort(src_tri->index_xyz[j]); - unsigned idx_st = LittleShort(src_tri->index_st[j]); + uint16_t idx_xyz = LittleShort(src_tri->index_xyz[j]); + uint16_t idx_st = LittleShort(src_tri->index_st[j]); if (idx_xyz >= header.num_xyz || idx_st >= header.num_st) { ret = Q_ERR_BAD_INDEX; @@ -218,12 +218,24 @@ qerror_t MOD_LoadMD2(model_t *model, const void *rawdata, size_t length) // load base s and t vertices model->sts = MOD_Malloc(header.num_st * sizeof(maliasst_t)); model->numsts = header.num_st; + model->skinwidth = header.skinwidth; + model->skinheight = header.skinheight; src_st = (dmd2stvert_t *)((byte *)rawdata + header.ofs_st); dst_st = model->sts; for (i = 0; i < header.num_st; i++, src_st++, dst_st++) { dst_st->s = (int16_t)LittleShort(src_st->s); dst_st->t = (int16_t)LittleShort(src_st->t); + + if (dst_st->s < 0 || dst_st->s >= header.skinwidth) { + ret = Q_ERR_BAD_INDEX; + goto fail; + } + + if (dst_st->t < 0 || dst_st->t >= header.skinheight) { + ret = Q_ERR_BAD_INDEX; + goto fail; + } } // load the frames @@ -238,12 +250,19 @@ qerror_t MOD_LoadMD2(model_t *model, const void *rawdata, size_t length) dst_frame->scale[j] = LittleFloat(src_frame->scale[j]); dst_frame->translate[j] = LittleFloat(src_frame->translate[j]); } + // verts are all 8 bit, so no swapping needed dst_frame->verts = MOD_Malloc(header.num_xyz * sizeof(maliasvert_t)); - - // TODO: check normal indices memcpy(dst_frame->verts, src_frame->verts, header.num_xyz * sizeof(maliasvert_t)); + // check normal indices + for (j = 0; j < header.num_xyz; j++) { + if (dst_frame->verts[j].lightnormalindex > NUMVERTEXNORMALS) { + ret = Q_ERR_BAD_INDEX; + goto fail; + } + } + src_frame = (dmd2frame_t *)((byte *)src_frame + header.framesize); } |