Fix clearing out-of-range default FB drawbuffer

The default framebuffer is initialized with just one drawbuffer slot
so the number of drawbuffers needs to be validated before checking if
a buffer is attached.

BUG=angleproject:2831
TEST=angle_end2end_tests

Change-Id: I960c39357853d1cd4575b06a992cff33223ab3df
Reviewed-on: https://chromium-review.googlesource.com/c/1264518
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index fa0edf9..3567e29 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -3547,49 +3547,67 @@
 
 void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
 {
+    Framebuffer *framebufferObject          = mGLState.getDrawFramebuffer();
+    const FramebufferAttachment *attachment = nullptr;
+    if (buffer == GL_DEPTH)
+    {
+        attachment = framebufferObject->getDepthbuffer();
+    }
+    if (buffer == GL_COLOR &&
+        static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorBuffers())
+    {
+        attachment = framebufferObject->getColorbuffer(drawbuffer);
+    }
     // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
     // that the backend doesn't need to take this case into account.
-    if (buffer == GL_DEPTH && !getGLState().getDrawFramebuffer()->getDepthbuffer())
-    {
-        return;
-    }
-    if (buffer == GL_COLOR && !getGLState().getDrawFramebuffer()->getColorbuffer(drawbuffer))
+    if (!attachment)
     {
         return;
     }
     ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
-    ANGLE_CONTEXT_TRY(
-        mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
+    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfv(this, buffer, drawbuffer, values));
 }
 
 void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
 {
+    Framebuffer *framebufferObject          = mGLState.getDrawFramebuffer();
+    const FramebufferAttachment *attachment = nullptr;
+    if (buffer == GL_COLOR &&
+        static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorBuffers())
+    {
+        attachment = framebufferObject->getColorbuffer(drawbuffer);
+    }
     // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
     // that the backend doesn't need to take this case into account.
-    if (buffer == GL_COLOR && !getGLState().getDrawFramebuffer()->getColorbuffer(drawbuffer))
+    if (!attachment)
     {
         return;
     }
     ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
-    ANGLE_CONTEXT_TRY(
-        mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
+    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferuiv(this, buffer, drawbuffer, values));
 }
 
 void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
 {
+    Framebuffer *framebufferObject          = mGLState.getDrawFramebuffer();
+    const FramebufferAttachment *attachment = nullptr;
+    if (buffer == GL_STENCIL)
+    {
+        attachment = framebufferObject->getStencilbuffer();
+    }
+    if (buffer == GL_COLOR &&
+        static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorBuffers())
+    {
+        attachment = framebufferObject->getColorbuffer(drawbuffer);
+    }
     // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
     // that the backend doesn't need to take this case into account.
-    if (buffer == GL_STENCIL && !getGLState().getDrawFramebuffer()->getStencilbuffer())
-    {
-        return;
-    }
-    if (buffer == GL_COLOR && !getGLState().getDrawFramebuffer()->getColorbuffer(drawbuffer))
+    if (!attachment)
     {
         return;
     }
     ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
-    ANGLE_CONTEXT_TRY(
-        mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
+    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferiv(this, buffer, drawbuffer, values));
 }
 
 void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)