Move validation from IndexDataManager to the API.
This validates all necessary buffer sizes for element array
buffers in the validation layer, before we start the draw.
BUG=angle:571
Change-Id: I602744ca1ea493e9f0f7e1ccbeb85fc4ae5c9f5a
Reviewed-on: https://chromium-review.googlesource.com/210648
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Buffer.h b/src/libGLESv2/Buffer.h
index b363c11..c39d7d7 100644
--- a/src/libGLESv2/Buffer.h
+++ b/src/libGLESv2/Buffer.h
@@ -58,7 +58,7 @@
rx::BufferImpl *mBuffer;
GLenum mUsage;
- GLsizeiptr mSize;
+ GLint64 mSize;
GLint mAccessFlags;
GLboolean mMapped;
GLvoid *mMapPointer;
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index ce46b3d..868ce8a 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -125,17 +125,7 @@
default: UNREACHABLE(); alignedOffset = false;
}
- // check for integer overflows
- if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeInfo.bytes) ||
- typeInfo.bytes * static_cast<unsigned int>(count) + offset < offset)
- {
- return GL_OUT_OF_MEMORY;
- }
-
- if (typeInfo.bytes * static_cast<unsigned int>(count) + offset > storage->getSize())
- {
- return GL_INVALID_OPERATION;
- }
+ ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
indices = static_cast<const GLubyte*>(storage->getData()) + offset;
}
@@ -197,11 +187,7 @@
}
}
- if (!indexBuffer)
- {
- ERR("No valid index buffer.");
- return GL_INVALID_OPERATION;
- }
+ ASSERT(indexBuffer);
if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
{
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index 4b9ff1c..8225df9 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -1489,6 +1489,32 @@
return gl::error(GL_INVALID_OPERATION, false);
}
+ if (elementArrayBuffer)
+ {
+ const gl::Type &typeInfo = gl::GetTypeInfo(type);
+
+ GLint64 offset = reinterpret_cast<GLint64>(indices);
+ GLint64 byteCount = static_cast<GLint64>(typeInfo.bytes) * static_cast<GLint64>(count)+offset;
+
+ // check for integer overflows
+ if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) ||
+ byteCount > static_cast<GLint64>(std::numeric_limits<GLuint>::max()))
+ {
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ // Check for reading past the end of the bound buffer object
+ if (byteCount > elementArrayBuffer->getSize())
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ }
+ else if (!indices)
+ {
+ // Catch this programming error here
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
// Use max index to validate if our vertex buffers are large enough for the pull.
// TODO: offer fast path, with disabled index validation.
// TODO: also disable index checking on back-ends that are robust to out-of-range accesses.