Restrict BlitFramebuffer dimensions in WebGL mode

Don't allow blitFramebuffer dimensions to overflow 32-bit integer
range as specified in WebGL 2.0 section 5.41.

BUG=chromium:830046
TEST=WebGL 2 conformance tests, angle_end2end_tests

Change-Id: Ia232291b09c94e1e4f837441c6720a78bab672fb
Reviewed-on: https://chromium-review.googlesource.com/1023856
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 22c47a0..5bd5ad7 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -68,6 +68,16 @@
     return CompressedTextureFormatRequiresExactSize(internalFormat) ||
            IsETC2EACFormat(internalFormat);
 }
+
+bool DifferenceCanOverflow(GLint a, GLint b)
+{
+    CheckedNumeric<GLint> checkedA(a);
+    checkedA -= b;
+    // Use negation to make sure that the difference can't overflow regardless of the order.
+    checkedA = -checkedA;
+    return !checkedA.IsValid();
+}
+
 bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex, GLint vertexCount)
 {
     const gl::State &state     = context->getGLState();
@@ -1298,6 +1308,16 @@
         return false;
     }
 
+    if (context->getExtensions().webglCompatibility)
+    {
+        if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
+            DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
+        {
+            ANGLE_VALIDATION_ERR(context, InvalidValue(), BlitDimensionsOutOfRange);
+            return false;
+        }
+    }
+
     bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
 
     if (mask & GL_COLOR_BUFFER_BIT)