Protect VBOs against buffer overflows.
parent
f8986cf39d
commit
0d4ecdefa4
|
|
@ -38,10 +38,10 @@ template <class Object> class LLStrider
|
|||
U32 mSkip;
|
||||
public:
|
||||
|
||||
LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); }
|
||||
LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); mBufferEnd = 0; }
|
||||
~LLStrider() { }
|
||||
|
||||
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
|
||||
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; mBufferEnd = 0; return *this;}
|
||||
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
|
||||
|
||||
LLStrider<Object> operator+(const S32& index)
|
||||
|
|
@ -49,19 +49,102 @@ public:
|
|||
LLStrider<Object> 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)); }
|
||||
// <FS:ND> 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;
|
||||
// <FS:ND>
|
||||
};
|
||||
|
||||
#endif // LL_LLSTRIDER_H
|
||||
|
|
|
|||
|
|
@ -2056,6 +2056,13 @@ template <class T,S32 type> struct VertexBufferStrider
|
|||
|
||||
strider = (T*)ptr;
|
||||
strider.setStride(0);
|
||||
|
||||
// <FS:ND> protect against buffer overflows
|
||||
if( count == -1 )
|
||||
count = vbo.getNumIndices()-index;
|
||||
strider.setCount( count );
|
||||
// <FS:ND>
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (vbo.hasDataType(type))
|
||||
|
|
@ -2072,6 +2079,13 @@ template <class T,S32 type> struct VertexBufferStrider
|
|||
|
||||
strider = (T*)ptr;
|
||||
strider.setStride(stride);
|
||||
|
||||
// <FS:ND> protect against buffer overflows
|
||||
if( count == -1 )
|
||||
count = vbo.getNumVerts()-index;
|
||||
strider.setCount( count );
|
||||
// <FS:ND>
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -829,6 +829,12 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
|
|||
LLStrider<LLVector2> tc;
|
||||
tc = (LLVector2*) vf.mTexCoords; tc.setStride(8);
|
||||
|
||||
// <FS:ND> protect against buffer overflows
|
||||
pos.setCount( vf.mNumVertices );
|
||||
norm.setCount( vf.mNumVertices );
|
||||
tc.setCount( vf.mNumVertices );
|
||||
// </FS:ND>
|
||||
|
||||
for (U32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
*(vertex_strider++) = *pos++;
|
||||
|
|
|
|||
Loading…
Reference in New Issue