When validating image size, use format for SubImage calls.

internalFormat is GL_NONE when validating these calls for glTexSubImage
and leads to an expected minimum size of 0.

Add extra unsized formats that are never supported to the format tables.
These are needed for determining the size of input data.

BUG=angleproject:2054

Change-Id: Ic827a279a246ff92c9f279232574521692b1c6f2
Reviewed-on: https://chromium-review.googlesource.com/526356
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index 196e11b..008f581 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -711,13 +711,17 @@
     // Unsized formats
     //                 | Internal format    |sized | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Texture supported                           | Renderable                                  | Filterable    |
     AddRGBAFormat(&map, GL_RED,              false,  8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>,           AlwaysSupported,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RED,              false,  8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
     AddRGBAFormat(&map, GL_RG,               false,  8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>,           AlwaysSupported,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RG,               false,  8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
     AddRGBAFormat(&map, GL_RGB,              false,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, AlwaysSupported);
     AddRGBAFormat(&map, GL_RGB,              false,  5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGB,              false,  8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
     AddRGBAFormat(&map, GL_RGBA,             false,  4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RGBA,             false,  5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RGBA,             false,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
     AddRGBAFormat(&map, GL_RGBA,             false, 10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>,                              RequireES<2, 0>,                              AlwaysSupported);
+    AddRGBAFormat(&map, GL_RGBA,             false,  8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,                               NeverSupported,                               NeverSupported );
     AddRGBAFormat(&map, GL_SRGB,             false,  8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireExt<&Extensions::sRGB>,                NeverSupported,                               AlwaysSupported);
     AddRGBAFormat(&map, GL_SRGB_ALPHA_EXT,   false,  8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireExt<&Extensions::sRGB>,                RequireExt<&Extensions::sRGB>,                AlwaysSupported);
 
@@ -764,6 +768,8 @@
     AddRGBAFormat(&map, GL_RED,          false, 32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, UnsizedFloatRGSupport,        UnsizedFloatRGRenderableSupport,        RequireExt<&Extensions::textureFloatLinear>              );
     AddRGBAFormat(&map, GL_RG,           false, 32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, UnsizedFloatRGSupport,        UnsizedFloatRGRenderableSupport,        RequireExt<&Extensions::textureFloatLinear>              );
     AddRGBAFormat(&map, GL_RGB,          false, 32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, UnsizedFloatSupport,          UnsizedFloatRGBRenderableSupport,       RequireExt<&Extensions::textureFloatLinear>              );
+    AddRGBAFormat(&map, GL_RGB,          false,  9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT, false, NeverSupported,               NeverSupported,                         NeverSupported                                           );
+    AddRGBAFormat(&map, GL_RGB,          false, 11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, NeverSupported,               NeverSupported,                         NeverSupported                                           );
     AddRGBAFormat(&map, GL_RGBA,         false, 32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, UnsizedFloatSupport,          UnsizedFloatRGBARenderableSupport,      RequireExt<&Extensions::textureFloatLinear>              );
 
     // Unsized luminance alpha formats
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 1cc3882..bfdbc07 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -1170,7 +1170,7 @@
                         GLsizei width,
                         GLsizei height,
                         GLsizei depth,
-                        GLenum internalFormat,
+                        GLenum format,
                         GLenum type,
                         const void *pixels,
                         GLsizei imageSize)
@@ -1184,7 +1184,8 @@
 
     // ...the data would be unpacked from the buffer object such that the memory reads required
     // would exceed the data store size.
-    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format, type);
+    ASSERT(formatInfo.internalFormat != GL_NONE);
     const gl::Extents size(width, height, depth);
     const auto &unpack = context->getGLState().getUnpackState();
 
diff --git a/src/libANGLE/validationES.h b/src/libANGLE/validationES.h
index 6f831af..dca0c0c 100644
--- a/src/libANGLE/validationES.h
+++ b/src/libANGLE/validationES.h
@@ -65,7 +65,7 @@
                         GLsizei width,
                         GLsizei height,
                         GLsizei depth,
-                        GLenum internalFormat,
+                        GLenum format,
                         GLenum type,
                         const void *pixels,
                         GLsizei imageSize);
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index dc3b49b..80aa0fb 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -1336,7 +1336,8 @@
         }
     }
 
-    if (!ValidImageDataSize(context, target, width, height, 1, internalformat, type, pixels,
+    GLenum sizeCheckFormat = isSubImage ? format : internalformat;
+    if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
                             imageSize))
     {
         return false;
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 18b554e..44012b0 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -296,8 +296,9 @@
         }
     }
 
-    if (!ValidImageDataSize(context, target, width, height, depth, actualInternalFormat, type,
-                            pixels, imageSize))
+    GLenum sizeCheckFormat = isSubImage ? format : internalformat;
+    if (!ValidImageDataSize(context, target, width, height, depth, sizeCheckFormat, type, pixels,
+                            imageSize))
     {
         return false;
     }
diff --git a/src/tests/gl_tests/RobustClientMemoryTest.cpp b/src/tests/gl_tests/RobustClientMemoryTest.cpp
index 61b1bfa..62ea8e9 100644
--- a/src/tests/gl_tests/RobustClientMemoryTest.cpp
+++ b/src/tests/gl_tests/RobustClientMemoryTest.cpp
@@ -304,7 +304,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-// Test basic usage and validation of glTexImage2DRobustANGLE
+// Test basic usage and validation of glTexImage2DRobustANGLE and glTexSubImage2DRobustANGLE
 TEST_P(RobustClientMemoryTest, TexImage2D)
 {
     if (!extensionsPresent())
@@ -323,12 +323,22 @@
                             rgbaData.data());
     EXPECT_GL_NO_ERROR();
 
+    glTexSubImage2DRobustANGLE(GL_TEXTURE_2D, 0, 0, 0, dataDimension, dataDimension, GL_RGBA,
+                               GL_UNSIGNED_BYTE, static_cast<GLsizei>(rgbaData.size()),
+                               rgbaData.data());
+    EXPECT_GL_NO_ERROR();
+
     // Test with a data size that is too small
     glTexImage2DRobustANGLE(GL_TEXTURE_2D, 0, GL_RGBA, dataDimension, dataDimension, 0, GL_RGBA,
                             GL_UNSIGNED_BYTE, static_cast<GLsizei>(rgbaData.size()) / 2,
                             rgbaData.data());
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
+    glTexSubImage2DRobustANGLE(GL_TEXTURE_2D, 0, 0, 0, dataDimension, dataDimension, GL_RGBA,
+                               GL_UNSIGNED_BYTE, static_cast<GLsizei>(rgbaData.size()) / 2,
+                               rgbaData.data());
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
     if (getClientMajorVersion() >= 3)
     {
         // Set an unpack parameter that would cause the driver to read past the end of the buffer