summaryrefslogtreecommitdiff
path: root/src/refresh/sw/model.c
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2013-03-16 19:19:00 +0400
committerAndrey Nazarov <skuller@skuller.net>2013-03-20 22:04:53 +0400
commit579a26b4dfb7172bc29d9b853f335af310eb114c (patch)
treee839b21a3a3b1f7a1b0ad99e73c77d4c16b95d7e /src/refresh/sw/model.c
parentf53832714d549a908a83b3528ea385197306b522 (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.c27
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);
}