Initial work for bounds checking of vertex arrays and vertex buffer objects.
Only glDrawArrays() done so far.
Simplified glVertex/Color/etcPointer functions.
Misc casts added here and there.
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 945f68c..23a8012 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -26,6 +26,7 @@
 #include "glheader.h"
 #include "api_validate.h"
 #include "context.h"
+#include "image.h"  /* for _mesa_sizeof_type() */
 #include "imports.h"
 #include "mtypes.h"
 #include "state.h"
@@ -112,14 +113,40 @@
 }
 
 
+/**
+ * Helper routine for validating vertex array data to be sure the given
+ * element lies within the legal range (i.e. vertex buffer object).
+ */
+static INLINE GLboolean
+validate(GLcontext *ctx, GLint attribArray,
+         const struct gl_client_array *array, GLint element)
+{
+   if (ctx->VertexProgram.Enabled
+       && attribArray >= 0
+       && ctx->Array.VertexAttrib[attribArray].Enabled) {
+      if (element >= ctx->Array.VertexAttrib[attribArray]._MaxElement)
+         return GL_FALSE;
+   }
+   else if (array && array->Enabled) {
+      if (element >= array->_MaxElement)
+         return GL_FALSE;
+   }
+   return GL_TRUE;
+}
 
+
+/**
+ * Called from the tnl module to error check the function parameters and
+ * verify that we really can draw something.
+ */
 GLboolean
 _mesa_validate_DrawArrays(GLcontext *ctx,
 			  GLenum mode, GLint start, GLsizei count)
 {
+   GLint i;
    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
 
-   if (count<0) {
+   if (count < 0) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
       return GL_FALSE;
    }
@@ -132,9 +159,57 @@
    if (ctx->NewState)
       _mesa_update_state( ctx );
 
-   if (ctx->Array.Vertex.Enabled
-       || (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled))
-      return GL_TRUE;
-   else
+   /* Either the conventional vertex position array, or the 0th
+    * generic vertex attribute array is required to be enabled.
+    */
+   if (ctx->VertexProgram.Enabled
+       && ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Enabled) {
+      if (start + count >= ctx->Array.VertexAttrib[VERT_ATTRIB_POS]._MaxElement)
+         return GL_FALSE;
+   }
+   else if (ctx->Array.Vertex.Enabled) {
+      if (start + count >= ctx->Array.Vertex._MaxElement)
+         return GL_FALSE;
+   }
+   else {
+      /* no vertex position array! */
       return GL_FALSE;
+   }
+
+   /*
+    * OK, now check all the other enabled arrays to be sure the elements
+    * are in bounds.
+    */
+   if (!validate(ctx, VERT_ATTRIB_WEIGHT, NULL, start + count))
+      return GL_FALSE;
+
+   if (!validate(ctx, VERT_ATTRIB_NORMAL, &ctx->Array.Normal, start + count))
+      return GL_FALSE;
+
+   if (!validate(ctx, VERT_ATTRIB_COLOR0, &ctx->Array.Color, start + count))
+      return GL_FALSE;
+
+   if (!validate(ctx, VERT_ATTRIB_COLOR1, &ctx->Array.SecondaryColor, start + count))
+      return GL_FALSE;
+
+   if (!validate(ctx, VERT_ATTRIB_FOG, &ctx->Array.FogCoord, start + count))
+      return GL_FALSE;
+
+   if (!validate(ctx, VERT_ATTRIB_SIX, NULL, start + count))
+      return GL_FALSE;
+
+   if (!validate(ctx, VERT_ATTRIB_SEVEN, &ctx->Array.FogCoord, start + count))
+      return GL_FALSE;
+
+   for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++)
+      if (!validate(ctx, VERT_ATTRIB_TEX0 + i, &ctx->Array.TexCoord[i], start + count))
+         return GL_FALSE;
+
+   if (!validate(ctx, -1, &ctx->Array.Index, start + count))
+      return GL_FALSE;
+
+   if (!validate(ctx, -1, &ctx->Array.EdgeFlag, start + count))
+      return GL_FALSE;
+
+   return GL_TRUE;
 }