commit 9950a5721f98eaffc6d8360c6d52ea9bcc0afb9c
Author: Daniel Gibson <metalcaedes@gmail.com>
Date:   Thu Dec 17 18:07:35 2015 +0100

    Fix heap corruption when loading (broken?) .ma models
    
    On FreeBSD, the game used to crash when loading the last level of RoE
    (d3xp), while loading models/david/hell_h7.ma.
    The problem could be reproduced on Linux whith #define USE_LIBC_MALLOC 1
    and clang's AddressSanitizer.
    Turns out that this file specifies a vertex transform for a non-existent
    vertex (index 31, while we only have 0-30) and thus the bounds of
    pMesh->vertexes[] are violated.
    I added a check to ensure the index is within the bounds and a Warning
    if it isn't.
    It should work now. If however it turns out that more files have this
    problem, maybe .ma is parsed incorrectly and we need a differently fix.
    
    (Should) fix #138

diff --git neo/renderer/Model_ma.cpp neo/renderer/Model_ma.cpp
index e31ca40..1cd672a 100644
--- renderer/Model_ma.cpp
+++ renderer/Model_ma.cpp
@@ -203,7 +203,7 @@ bool MA_ParseVertex(idParser& parser, maAttribHeader_t* header) {
 
 	//Allocate enough space for all the verts if this is the first attribute for verticies
 	if(!pMesh->vertexes) {
-		pMesh->numVertexes = header->size;
+		pMesh->numVertexes = header->size; // XXX: +1?
 		pMesh->vertexes = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numVertexes );
 	}
 
@@ -692,7 +692,16 @@ void MA_ParseMesh(idParser& parser) {
 
 	//Now apply the pt transformations
 	for(int i = 0; i < pMesh->numVertTransforms; i++) {
-		pMesh->vertexes[(int)pMesh->vertTransforms[i].w] +=  pMesh->vertTransforms[i].ToVec3();
+		int idx = (int)pMesh->vertTransforms[i].w;
+		if(idx < 0 || idx >= pMesh->numVertexes)
+		{
+			// this happens with d3xp/models/david/hell_h7.ma in the d3xp hell level
+			// TODO: if it happens for other models, too, maybe it's intended and the .ma parsing is broken
+			common->Warning( "Model %s tried to set an out-of-bounds vertex transform (%d, but max vert. index is %d)!",
+							 parser.GetFileName(), idx, pMesh->numVertexes-1 );
+			continue;
+		}
+		pMesh->vertexes[idx] +=  pMesh->vertTransforms[i].ToVec3();
 	}
 
 	MA_VERBOSE((va("MESH %s - parent %s\n", header.name, header.parent)));
