X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fapi_validate.c;h=4fb7b5ad61f92fd5d38a812e252edfabfa4b2522;hb=bef912abd3345268168fdff82b4a36f64f1d78a0;hp=2df4f173893af28e2838c06aae55bb466f91805a;hpb=4b1cbfcbe66161a7b56d56cd9e2c35ce49b3a91d;p=mesa.git diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 2df4f173893..4fb7b5ad61f 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -28,8 +28,7 @@ #include "context.h" #include "imports.h" #include "mtypes.h" -#include "state.h" - +#include "vbo/vbo.h" /** @@ -54,10 +53,10 @@ index_bytes(GLenum type, GLsizei count) /** * Find the max index in the given element/index buffer */ -static GLuint -max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, - const void *indices, - struct gl_buffer_object *elementBuf) +GLuint +_mesa_max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, + const void *indices, + struct gl_buffer_object *elementBuf) { const GLubyte *map = NULL; GLuint max = 0; @@ -125,6 +124,47 @@ check_valid_to_render(GLcontext *ctx, const char *function) } +/** + * Do bounds checking on array element indexes. Check that the vertices + * pointed to by the indices don't lie outside buffer object bounds. + * \return GL_TRUE if OK, GL_FALSE if any indexed vertex goes is out of bounds + */ +static GLboolean +check_index_bounds(GLcontext *ctx, GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex) +{ + struct _mesa_prim prim; + struct _mesa_index_buffer ib; + GLuint min, max; + + /* Only the X Server needs to do this -- otherwise, accessing outside + * array/BO bounds allows application termination. + */ + if (!ctx->Const.CheckArrayBounds) + return GL_TRUE; + + memset(&prim, 0, sizeof(prim)); + prim.count = count; + + memset(&ib, 0, sizeof(ib)); + ib.type = type; + ib.ptr = indices; + ib.obj = ctx->Array.ElementArrayBufferObj; + + vbo_get_minmax_index(ctx, &prim, &ib, &min, &max); + + if ((int)(min + basevertex) < 0 || + max + basevertex > ctx->Array.ArrayObj->_MaxElement) { + /* the max element is out of bounds of one or more enabled arrays */ + _mesa_warning(ctx, "glDrawElements() index=%u is out of bounds (max=%u)", + max, ctx->Array.ArrayObj->_MaxElement); + return GL_FALSE; + } + + return GL_TRUE; +} + + /** * Error checking for glDrawElements(). Includes parameter checking * and VBO bounds checking. @@ -133,7 +173,7 @@ check_valid_to_render(GLcontext *ctx, const char *function) GLboolean _mesa_validate_DrawElements(GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) + const GLvoid *indices, GLint basevertex) { ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); @@ -156,9 +196,6 @@ _mesa_validate_DrawElements(GLcontext *ctx, return GL_FALSE; } - if (ctx->NewState) - _mesa_update_state(ctx); - if (!check_valid_to_render(ctx, "glDrawElements")) return GL_FALSE; @@ -177,17 +214,8 @@ _mesa_validate_DrawElements(GLcontext *ctx, return GL_FALSE; } - if (ctx->Const.CheckArrayBounds) { - /* find max array index */ - GLuint max = max_buffer_index(ctx, count, type, indices, - ctx->Array.ElementArrayBufferObj); - if (max >= ctx->Array.ArrayObj->_MaxElement) { - /* the max element is out of bounds of one or more enabled arrays */ - _mesa_warning(ctx, "glDrawElements() index=%u is " - "out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement); - return GL_FALSE; - } - } + if (!check_index_bounds(ctx, count, type, indices, basevertex)) + return GL_FALSE; return GL_TRUE; } @@ -202,7 +230,7 @@ GLboolean _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const GLvoid *indices) + const GLvoid *indices, GLint basevertex) { ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); @@ -229,9 +257,6 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, return GL_FALSE; } - if (ctx->NewState) - _mesa_update_state(ctx); - if (!check_valid_to_render(ctx, "glDrawRangeElements")) return GL_FALSE; @@ -250,14 +275,8 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, return GL_FALSE; } - if (ctx->Const.CheckArrayBounds) { - GLuint max = max_buffer_index(ctx, count, type, indices, - ctx->Array.ElementArrayBufferObj); - if (max >= ctx->Array.ArrayObj->_MaxElement) { - /* the max element is out of bounds of one or more enabled arrays */ - return GL_FALSE; - } - } + if (!check_index_bounds(ctx, count, type, indices, basevertex)) + return GL_FALSE; return GL_TRUE; } @@ -285,9 +304,6 @@ _mesa_validate_DrawArrays(GLcontext *ctx, return GL_FALSE; } - if (ctx->NewState) - _mesa_update_state(ctx); - if (!check_valid_to_render(ctx, "glDrawArrays")) return GL_FALSE;