Add base::numerics for safe math and conversions.

This replaces are "IsUnsignedXXXSafe" family of methods.
Also add overflow checks to unpack block sizes.

BUG=angleproject:1397

Change-Id: Ib47be149b0486c70f795b0d0f8899441faac9340
Reviewed-on: https://chromium-review.googlesource.com/348062
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 2efebcd..d2e4e21 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -7,6 +7,7 @@
 // validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters
 
 #include "libANGLE/validationES3.h"
+
 #include "libANGLE/validationES.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Texture.h"
@@ -18,6 +19,8 @@
 #include "common/mathutil.h"
 #include "common/utilities.h"
 
+using namespace angle;
+
 namespace gl
 {
 
@@ -474,23 +477,31 @@
         size_t depthSize = static_cast<size_t>(depth);
         GLenum sizedFormat = GetSizedInternalFormat(actualInternalFormat, type);
 
-        size_t pixelBytes = static_cast<size_t>(gl::GetInternalFormatInfo(sizedFormat).pixelBytes);
+        CheckedNumeric<size_t> checkedBytes(gl::GetInternalFormatInfo(sizedFormat).pixelBytes);
+        checkedBytes *= widthSize;
+        checkedBytes *= heightSize;
+        checkedBytes *= depthSize;
 
-        if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) ||
-            !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) ||
-            !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes))
+        if (!checkedBytes.IsValid())
         {
             // Overflow past the end of the buffer
-            context->handleError(Error(GL_INVALID_OPERATION));
+            context->handleError(Error(GL_INVALID_OPERATION, "Integer overflow"));
             return false;
         }
 
         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat);
-        size_t copyBytes = formatInfo.computeBlockSize(type, width, height);
-        size_t offset = reinterpret_cast<size_t>(pixels);
+        auto copyBytesOrErr                  = formatInfo.computeBlockSize(type, width, height);
+        if (copyBytesOrErr.isError())
+        {
+            context->handleError(copyBytesOrErr.getError());
+            return false;
+        }
+        CheckedNumeric<size_t> checkedCopyBytes(copyBytesOrErr.getResult());
+        CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
+        checkedCopyBytes += checkedOffset;
 
-        if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) ||
-            ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->getSize())))
+        if (!checkedCopyBytes.IsValid() ||
+            (checkedCopyBytes.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
         {
             // Overflow past the end of the buffer
             context->handleError(Error(GL_INVALID_OPERATION));
@@ -503,7 +514,7 @@
         {
             size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
 
-            if ((offset % dataBytesPerPixel) != 0)
+            if ((checkedOffset.ValueOrDie() % dataBytesPerPixel) != 0)
             {
                 context->handleError(Error(GL_INVALID_OPERATION));
                 return false;
@@ -1538,10 +1549,21 @@
         return false;
     }
 
+    // Validate image size
+    if (!ValidImageSizeParameters(context, target, level, width, height, depth, false))
+    {
+        context->handleError(Error(GL_INVALID_VALUE));
+        return false;
+    }
+
     const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-    if (imageSize < 0 ||
-        static_cast<GLuint>(imageSize) !=
-            formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+    auto blockSizeOrErr              = formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height);
+    if (blockSizeOrErr.isError())
+    {
+        context->handleError(blockSizeOrErr.getError());
+        return false;
+    }
+    if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
         context->handleError(Error(GL_INVALID_VALUE));
         return false;
@@ -1883,9 +1905,13 @@
     }
 
     const InternalFormat &formatInfo = GetInternalFormatInfo(format);
-    if (imageSize < 0 ||
-        static_cast<GLuint>(imageSize) !=
-            formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+    auto blockSizeOrErr              = formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height);
+    if (blockSizeOrErr.isError())
+    {
+        context->handleError(blockSizeOrErr.getError());
+        return false;
+    }
+    if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
     {
         context->handleError(Error(GL_INVALID_VALUE));
         return false;