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/formatutils.cpp b/src/libANGLE/formatutils.cpp
index c0adf4b..c9c701e 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -11,6 +11,8 @@
 #include "libANGLE/Context.h"
 #include "libANGLE/Framebuffer.h"
 
+using namespace angle;
+
 namespace gl
 {
 
@@ -677,28 +679,36 @@
     }
 }
 
-GLuint InternalFormat::computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const
+gl::ErrorOrResult<GLuint> InternalFormat::computeRowPitch(GLenum formatType,
+                                                          GLsizei width,
+                                                          GLint alignment,
+                                                          GLint rowLength) const
 {
     ASSERT(alignment > 0 && isPow2(alignment));
     GLuint rowBytes;
     if (rowLength > 0)
     {
         ASSERT(!compressed);
-        rowBytes = pixelBytes * rowLength;
+        CheckedNumeric<GLuint> checkedBytes(pixelBytes);
+        checkedBytes *= rowLength;
+        ANGLE_TRY_CHECKED_MATH(checkedBytes);
+        rowBytes = checkedBytes.ValueOrDie();
     }
     else
     {
-        rowBytes = computeBlockSize(formatType, width, 1);
+        ANGLE_TRY_RESULT(computeBlockSize(formatType, width, 1), rowBytes);
     }
-    return rx::roundUp(rowBytes, static_cast<GLuint>(alignment));
+    auto checkedResult = rx::CheckedRoundUp(rowBytes, static_cast<GLuint>(alignment));
+    ANGLE_TRY_CHECKED_MATH(checkedResult);
+    return checkedResult.ValueOrDie();
 }
 
-GLuint InternalFormat::computeDepthPitch(GLenum formatType,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLint alignment,
-                                         GLint rowLength,
-                                         GLint imageHeight) const
+gl::ErrorOrResult<GLuint> InternalFormat::computeDepthPitch(GLenum formatType,
+                                                            GLsizei width,
+                                                            GLsizei height,
+                                                            GLint alignment,
+                                                            GLint rowLength,
+                                                            GLint imageHeight) const
 {
     GLuint rows;
     if (imageHeight > 0)
@@ -709,29 +719,37 @@
     {
         rows = height;
     }
-    return computeRowPitch(formatType, width, alignment, rowLength) * rows;
+    GLuint rowPitch = 0;
+    ANGLE_TRY_RESULT(computeRowPitch(formatType, width, alignment, rowLength), rowPitch);
+
+    CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
+    auto depthPitch = checkedRowPitch * rows;
+    ANGLE_TRY_CHECKED_MATH(depthPitch);
+    return depthPitch.ValueOrDie();
 }
 
-GLuint InternalFormat::computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const
+gl::ErrorOrResult<GLuint> InternalFormat::computeBlockSize(GLenum formatType,
+                                                           GLsizei width,
+                                                           GLsizei height) const
 {
+    CheckedNumeric<GLuint> checkedWidth(width);
+    CheckedNumeric<GLuint> checkedHeight(height);
+
     if (compressed)
     {
-        GLsizei numBlocksWide = (width + compressedBlockWidth - 1) / compressedBlockWidth;
-        GLsizei numBlocksHight = (height + compressedBlockHeight - 1) / compressedBlockHeight;
-        return (pixelBytes * numBlocksWide * numBlocksHight);
+        auto numBlocksWide = (checkedWidth + compressedBlockWidth - 1u) / compressedBlockWidth;
+        auto numBlocksHigh = (checkedHeight + compressedBlockHeight - 1u) / compressedBlockHeight;
+        auto bytes         = numBlocksWide * numBlocksHigh * pixelBytes;
+        ANGLE_TRY_CHECKED_MATH(bytes);
+        return bytes.ValueOrDie();
     }
-    else
-    {
-        const Type &typeInfo = GetTypeInfo(formatType);
-        if (typeInfo.specialInterpretation)
-        {
-            return typeInfo.bytes * width * height;
-        }
-        else
-        {
-            return componentCount * typeInfo.bytes * width * height;
-        }
-    }
+
+    const Type &typeInfo = GetTypeInfo(formatType);
+    GLuint components    = typeInfo.specialInterpretation ? 1u : componentCount;
+
+    auto result = checkedWidth * checkedHeight * components * typeInfo.bytes;
+    ANGLE_TRY_CHECKED_MATH(result);
+    return result.ValueOrDie();
 }
 
 GLuint InternalFormat::computeSkipPixels(GLint rowPitch,