Fix up some validation bugs in Texture functions.

In several places we weren't handling certain errors, or were
returning the wrong error code. Several dEQP negative API
tests are affected in functional.negative_api.texture.

BUG=angle:571

Change-Id: I19d7250aab2c15d709fd591b8df90ce883f9ac60
Reviewed-on: https://chromium-review.googlesource.com/201250
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/validationES3.cpp b/src/libGLESv2/validationES3.cpp
index b3108a1..555c5e3 100644
--- a/src/libGLESv2/validationES3.cpp
+++ b/src/libGLESv2/validationES3.cpp
@@ -25,6 +25,11 @@
                                    GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                                    GLint border, GLenum format, GLenum type, const GLvoid *pixels)
 {
+    if (!ValidTexture2DDestinationTarget(context, target))
+    {
+        return gl::error(GL_INVALID_ENUM, false);
+    }
+
     // Validate image size
     if (!ValidImageSize(context, target, level, width, height, depth))
     {
@@ -37,6 +42,14 @@
         return gl::error(GL_INVALID_VALUE, false);
     }
 
+    if (xoffset < 0 || yoffset < 0 || zoffset < 0 ||
+        std::numeric_limits<GLsizei>::max() - xoffset < width ||
+        std::numeric_limits<GLsizei>::max() - yoffset < height ||
+        std::numeric_limits<GLsizei>::max() - zoffset < depth)
+    {
+        return gl::error(GL_INVALID_VALUE, false);
+    }
+
     gl::Texture *texture = NULL;
     bool textureCompressed = false;
     GLenum textureInternalFormat = GL_NONE;
@@ -156,6 +169,7 @@
 
     // Validate texture formats
     GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
+    int clientVersion = context->getClientVersion();
     if (isCompressed)
     {
         if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
@@ -163,7 +177,7 @@
             return gl::error(GL_INVALID_OPERATION, false);
         }
 
-        if (!gl::IsFormatCompressed(actualInternalFormat, context->getClientVersion()))
+        if (!gl::IsFormatCompressed(actualInternalFormat, clientVersion))
         {
             return gl::error(GL_INVALID_ENUM, false);
         }
@@ -175,14 +189,16 @@
     }
     else
     {
+        // Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid
+        // internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d)
         if (!gl::IsValidInternalFormat(actualInternalFormat, context) ||
-            !gl::IsValidFormat(format, context->getClientVersion()) ||
-            !gl::IsValidType(type, context->getClientVersion()))
+            !gl::IsValidFormat(format, clientVersion) ||
+            !gl::IsValidType(type, clientVersion))
         {
             return gl::error(GL_INVALID_ENUM, false);
         }
 
-        if (!gl::IsValidFormatCombination(actualInternalFormat, format, type, context->getClientVersion()))
+        if (!gl::IsValidFormatCombination(actualInternalFormat, format, type, clientVersion))
         {
             return gl::error(GL_INVALID_OPERATION, false);
         }
@@ -244,7 +260,11 @@
         size_t widthSize = static_cast<size_t>(width);
         size_t heightSize = static_cast<size_t>(height);
         size_t depthSize = static_cast<size_t>(depth);
-        size_t pixelBytes = static_cast<size_t>(gl::GetPixelBytes(actualInternalFormat, context->getClientVersion()));
+        GLenum sizedFormat = gl::IsSizedInternalFormat(actualInternalFormat, clientVersion) ?
+                             actualInternalFormat :
+                             gl::GetSizedInternalFormat(actualInternalFormat, type, clientVersion);
+
+        size_t pixelBytes = static_cast<size_t>(gl::GetPixelBytes(sizedFormat, clientVersion));
 
         if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) ||
             !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) ||
@@ -257,7 +277,8 @@
         size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
         size_t offset = reinterpret_cast<size_t>(pixels);
 
-        if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) || ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->size())))
+        if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) ||
+            ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->size())))
         {
             // Overflow past the end of the buffer
             return gl::error(GL_INVALID_OPERATION, false);
@@ -283,12 +304,13 @@
 }
 
 bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat,
-                                       bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
-                                       GLsizei width, GLsizei height, GLint border)
+                                       bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset,
+                                       GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
 {
     GLenum textureInternalFormat;
     if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
-                                            xoffset, yoffset, zoffset, x, y, width, height, border, &textureInternalFormat))
+                                            xoffset, yoffset, zoffset, x, y, width, height,
+                                            border, &textureInternalFormat))
     {
         return false;
     }
@@ -299,7 +321,8 @@
 
     if (isSubImage)
     {
-        if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, context->getReadFramebufferHandle(),
+        if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
+                                                context->getReadFramebufferHandle(),
                                                 context->getClientVersion()))
         {
             return gl::error(GL_INVALID_OPERATION, false);
@@ -307,7 +330,8 @@
     }
     else
     {
-        if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat, context->getReadFramebufferHandle(),
+        if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat,
+                                                context->getReadFramebufferHandle(),
                                                 context->getClientVersion()))
         {
             return gl::error(GL_INVALID_OPERATION, false);