From c5b1e81de48de5d8830bf5d92ff767ad1985e46e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Oct 2003 22:59:07 +0000 Subject: 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. --- src/mesa/main/api_validate.c | 85 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) (limited to 'src/mesa/main/api_validate.c') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 945f68c174..23a8012a30 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 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, } +/** + * 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 @@ _mesa_validate_DrawArrays(GLcontext *ctx, 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; } -- cgit v1.2.3