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/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.