Harden uniform array index parsing.

Add overflow handling when parsing uniform variables.

BUG=angleproject:2191
TEST=angle_unittests

Change-Id: Ib2a69be1cc11a94420bc923a2aaaef8dc664d562
Reviewed-on: https://chromium-review.googlesource.com/756209
Reviewed-by: Bryan Bernhart <bryan.bernhart@intel.com>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/common/utilities.cpp b/src/common/utilities.cpp
index aad2204..80abdd9 100644
--- a/src/common/utilities.cpp
+++ b/src/common/utilities.cpp
@@ -773,7 +773,6 @@
 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
 {
     ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
-    unsigned int subscript = GL_INVALID_INDEX;
 
     // Strip any trailing array operator and retrieve the subscript
     size_t open = name.find_last_of('[');
@@ -790,14 +789,22 @@
         }
         if (indexIsValidDecimalNumber)
         {
-            subscript                       = atoi(name.c_str() + open + 1);
-            *nameLengthWithoutArrayIndexOut = open;
-            return subscript;
+            errno = 0;  // reset global error flag.
+            unsigned long subscript =
+                strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
+
+            // Check if resulting integer is out-of-range or conversion error.
+            if ((subscript <= static_cast<unsigned long>(UINT_MAX)) &&
+                !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
+            {
+                *nameLengthWithoutArrayIndexOut = open;
+                return static_cast<unsigned int>(subscript);
+            }
         }
     }
 
     *nameLengthWithoutArrayIndexOut = name.length();
-    return subscript;
+    return GL_INVALID_INDEX;
 }
 
 const char *GetGenericErrorMessage(GLenum error)