From 02067f973ec7fee8bbc85235e44b42a8ac1cd1ba Mon Sep 17 00:00:00 2001 From: Latif Khalifa Date: Tue, 29 Oct 2013 16:27:07 +0100 Subject: [PATCH] Prevent LLFace::getGeometryVolume from overwriting vbos past their end. Possible fix for a crash in LLFace::getGeometryVolume() Patch by NickyD/Firestorm Crash signature: 14 and 20 --- indra/newview/llface.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 0a885d305..d248a7371 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1189,6 +1189,21 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } + // The volume face vf can have more indices/vertices than this face. All striders below are aquired with a size of this face, but then written with num_verices/num_indices values, + // thus overflowing the buffer when vf holds more data. + // We can either clamp num_* down like here, or aquire all striders not using the face size, but the size if vf (that is swapping out mGeomCount with num_vertices and mIndicesCout with num_indices + // in all calls to nVertbuffer->get*Strider(...). Final solution is to just return FALSE and be done with it. + // + // The correct poison of choice is debatable, either copying not all data of vf (clamping) or writing more data than this face claims to have (aquiring bigger striders). Returning will not display this face at all. + // + // clamping it is for now. + + num_vertices = llclamp( num_vertices, (S32)0, (S32)mGeomCount ); + num_indices = llclamp( num_indices, (S32)0, (S32)mIndicesCount ); + + // + + //don't use map range (generates many redundant unmap calls) bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; @@ -1644,7 +1659,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (!do_xform) { LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM); - S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + + // Don't round up, or there's high risk to write past buffer + + // S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + S32 tc_size = (num_vertices*2*sizeof(F32)); + + // + LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size); } else