diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index ed9284d2c5..a903655ed7 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -38,10 +38,10 @@ template class LLStrider U32 mSkip; public: - LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); } + LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); mBufferEnd = 0; } ~LLStrider() { } - const LLStrider& operator = (Object *first) { mObjectp = first; return *this;} + const LLStrider& operator = (Object *first) { mObjectp = first; mBufferEnd = 0; return *this;} void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} LLStrider operator+(const S32& index) @@ -49,19 +49,102 @@ public: LLStrider ret; ret.mBytep = mBytep + mSkip*index; ret.mSkip = mSkip; + ret.mBufferEnd = mBufferEnd; return ret; } - void skip(const U32 index) { mBytep += mSkip*index;} - U32 getSkip() const { return mSkip; } - Object* get() { return mObjectp; } - Object* operator->() { return mObjectp; } - Object& operator *() { return *mObjectp; } - Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; } - Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; } + void skip(const U32 index) { mBytep += mSkip*index;} + U32 getSkip() const { return mSkip; } - Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); } + // protect against buffer overflows + + // Object* get() { return mObjectp; } + // Object* operator->() { return mObjectp; } + // Object& operator *() { return *mObjectp; } + // Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; } + // Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; } + + // Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); } + + Object* get() + { + if( !assertValid( mBytep ) ) + return &mDummy; + + return mObjectp; + } + + Object* operator->() + { + if( !assertValid( mBytep ) ) + return &mDummy; + + return mObjectp; + } + + Object& operator *() + { + if( !assertValid( mBytep ) ) + return mDummy; + + return *mObjectp; + } + + Object* operator ++(int) + { + Object* old = mObjectp; + mBytep += mSkip; + + if( !assertValid( (U8*)old ) ) + return &mDummy; + + return old; + } + + Object* operator +=(int i) + { + mBytep += mSkip*i; + assertValid( mBytep ); + return mObjectp; + } + + Object& operator[](U32 index) + { + if( !assertValid( mBytep + mSkip*index ) ) + return mDummy; + + return *(Object*)(mBytep + (mSkip * index)); + } + + void setCount( U32 aCount ) + { + mBufferEnd = mBytep + mSkip*aCount; +#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG + mCount = aCount; +#endif + } + + bool assertValid( U8 const *aBuffer ) + { + if( !aBuffer || !mBufferEnd ) + return true; + if( aBuffer < mBufferEnd ) + return true; + + llerrs << "Vertex buffer access beyond end of VBO" << llendl; + return false; + } + +private: + U8 *mBufferEnd; + +#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG + U32 mCount; +#endif + + Object mDummy; + // }; #endif // LL_LLSTRIDER_H diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 2e5d460e49..7df848fb23 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2056,6 +2056,13 @@ template struct VertexBufferStrider strider = (T*)ptr; strider.setStride(0); + + // protect against buffer overflows + if( count == -1 ) + count = vbo.getNumIndices()-index; + strider.setCount( count ); + // + return true; } else if (vbo.hasDataType(type)) @@ -2072,6 +2079,13 @@ template struct VertexBufferStrider strider = (T*)ptr; strider.setStride(stride); + + // protect against buffer overflows + if( count == -1 ) + count = vbo.getNumVerts()-index; + strider.setCount( count ); + // + return true; } else diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 5160cc0ddb..546f810458 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -829,6 +829,12 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) LLStrider tc; tc = (LLVector2*) vf.mTexCoords; tc.setStride(8); + // protect against buffer overflows + pos.setCount( vf.mNumVertices ); + norm.setCount( vf.mNumVertices ); + tc.setCount( vf.mNumVertices ); + // + for (U32 i = 0; i < num_vertices; i++) { *(vertex_strider++) = *pos++;