Add robust math to constant folding.

Previously our multiplication and other operators could
do overflows, which can lead to security bugs.

BUG=chromium:637050

Change-Id: Icee22a87909e205b71bda1c5bc1627fcf5e26e90
Reviewed-on: https://chromium-review.googlesource.com/382678
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index fc852d7..49b6c74 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -2270,6 +2270,71 @@
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+// Test that multiplication ops are properly validated.
+TEST_P(GLSLTest, FoldedIntProductOutOfBounds)
+{
+    const std::string &fragmentShader =
+        "precision mediump float;\n"
+        "void main(void)\n"
+        "{\n"
+        " int prod = -2580 * 25800 * 25800;\n"
+        " gl_FragColor = vec4(float(prod));\n"
+        "}\n";
+
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
+    EXPECT_EQ(0u, program);
+    glDeleteProgram(program);
+}
+
+// Test that multiplication ops are properly validated.
+TEST_P(GLSLTest_ES3, FoldedUIntProductOutOfBounds)
+{
+    const std::string &fragmentShader =
+        "#version 300 es\n"
+        "precision mediump float;\n"
+        "void main()\n"
+        "{\n"
+        "   unsigned int prod = 2580u * 25800u * 25800u;\n"
+        "   gl_FragColor = vec4(float(prod));\n"
+        "}\n";
+
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
+    EXPECT_EQ(0u, program);
+    glDeleteProgram(program);
+}
+
+// Test that addition ops are properly validated.
+TEST_P(GLSLTest, FoldedIntSumOutOfBounds)
+{
+    const std::string &fragmentShader =
+        "precision mediump float;\n"
+        "void main(void)\n"
+        "{\n"
+        " int sum = 2147483647 + 2147483647;\n"
+        " gl_FragColor = vec4(float(sum));\n"
+        "}\n";
+
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
+    EXPECT_EQ(0u, program);
+    glDeleteProgram(program);
+}
+
+// Test that subtraction ops are properly validated.
+TEST_P(GLSLTest, FoldedIntDifferenceOutOfBounds)
+{
+    const std::string &fragmentShader =
+        "precision mediump float;\n"
+        "void main(void)\n"
+        "{\n"
+        " int diff = -2147483000 - 2147483000;\n"
+        " gl_FragColor = vec4(float(diff));\n"
+        "}\n";
+
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
+    EXPECT_EQ(0u, program);
+    glDeleteProgram(program);
+}
+
 }  // anonymous namespace
 
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.