Updated VertexBuffer's getSpaceRequired and storeVertexAttributes methods to return bools and fixed some validation of parameters to prevent under and overflows.
TRAC #23643
Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp
index 4a57d91..9e663e2 100644
--- a/src/libGLESv2/renderer/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/VertexDataManager.cpp
@@ -26,9 +26,15 @@
namespace rx
{
-static int ElementsInBuffer(const gl::VertexAttribute &attribute, int size)
+static int ElementsInBuffer(const gl::VertexAttribute &attribute, unsigned int size)
{
- int stride = attribute.stride();
+ // Size cannot be larger than a GLsizei
+ if (size > static_cast<unsigned int>(std::numeric_limits<int>::max()))
+ {
+ size = static_cast<unsigned int>(std::numeric_limits<int>::max());
+ }
+
+ GLsizei stride = attribute.stride();
return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
}
@@ -97,7 +103,7 @@
gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
- if (staticBuffer && staticBuffer->getBufferSize() > 0 && staticBuffer->lookupAttribute(attribs[i]) == -1 &&
+ if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) &&
!DirectStoragePossible(staticBuffer, attribs[i], currentValues[i]))
{
buffer->invalidateStaticData();
@@ -160,7 +166,7 @@
BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
bool directStorage = DirectStoragePossible(vertexBuffer, attribs[i], currentValues[i]);
- std::size_t streamOffset = -1;
+ unsigned int streamOffset = 0;
unsigned int outputElementSize = 0;
if (directStorage)
@@ -170,37 +176,41 @@
}
else if (staticBuffer)
{
- streamOffset = staticBuffer->lookupAttribute(attribs[i]);
- outputElementSize = staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0);
+ if (!staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize))
+ {
+ return GL_OUT_OF_MEMORY;
+ }
- if (streamOffset == -1)
+ if (!staticBuffer->lookupAttribute(attribs[i], &streamOffset))
{
// Convert the entire buffer
int totalCount = ElementsInBuffer(attribs[i], storage->getSize());
int startIndex = attribs[i].mOffset / attribs[i].stride();
- streamOffset = staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount, 0);
- }
-
- if (streamOffset != -1)
- {
- streamOffset += (attribs[i].mOffset / attribs[i].stride()) * outputElementSize;
-
- if (instances == 0 || attribs[i].mDivisor == 0)
+ if (!staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount,
+ 0, &streamOffset))
{
- streamOffset += start * outputElementSize;
+ return GL_OUT_OF_MEMORY;
}
}
+
+ unsigned int firstElementOffset = (attribs[i].mOffset / attribs[i].stride()) * outputElementSize;
+ unsigned int startOffset = (instances == 0 || attribs[i].mDivisor == 0) ? start * outputElementSize : 0;
+ if (streamOffset + firstElementOffset + startOffset < streamOffset)
+ {
+ return GL_OUT_OF_MEMORY;
+ }
+
+ streamOffset += firstElementOffset + startOffset;
}
else
{
- outputElementSize = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0);
- streamOffset = mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, count, instances);
- }
-
- if (streamOffset == -1)
- {
- return GL_OUT_OF_MEMORY;
+ if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) ||
+ !mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, count, instances,
+ &streamOffset))
+ {
+ return GL_OUT_OF_MEMORY;
+ }
}
translated[i].storage = directStorage ? storage : NULL;
@@ -229,8 +239,8 @@
return GL_OUT_OF_MEMORY;
}
- int streamOffset = buffer->storeVertexAttributes(attribs[i], currentValues[i], 0, 1, 0);
- if (streamOffset == -1)
+ unsigned int streamOffset;
+ if (!buffer->storeVertexAttributes(attribs[i], currentValues[i], 0, 1, 0, &streamOffset))
{
return GL_OUT_OF_MEMORY;
}