diff options
Diffstat (limited to 'src/mesa/main/eval.c')
-rw-r--r-- | src/mesa/main/eval.c | 95 |
1 files changed, 92 insertions, 3 deletions
diff --git a/src/mesa/main/eval.c b/src/mesa/main/eval.c index 9ab55072f00..e651715f788 100644 --- a/src/mesa/main/eval.c +++ b/src/mesa/main/eval.c @@ -545,7 +545,7 @@ _mesa_Map2d( GLenum target, static void GLAPIENTRY -_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) +_mesa_GetnMapdvARB( GLenum target, GLenum query, GLsizei bufSize, GLdouble *v ) { GET_CURRENT_CONTEXT(ctx); struct gl_1d_map *map1d; @@ -553,6 +553,7 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) GLint i, n; GLfloat *data; GLuint comps; + GLsizei numBytes; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -577,6 +578,9 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) n = map2d->Uorder * map2d->Vorder * comps; } if (data) { + numBytes = n * sizeof *v; + if (bufSize < numBytes) + goto overflow; for (i=0;i<n;i++) { v[i] = data[i]; } @@ -584,19 +588,31 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) break; case GL_ORDER: if (map1d) { + numBytes = 1 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = (GLdouble) map1d->Order; } else { + numBytes = 2 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = (GLdouble) map2d->Uorder; v[1] = (GLdouble) map2d->Vorder; } break; case GL_DOMAIN: if (map1d) { + numBytes = 2 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = (GLdouble) map1d->u1; v[1] = (GLdouble) map1d->u2; } else { + numBytes = 4 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = (GLdouble) map2d->u1; v[1] = (GLdouble) map2d->u2; v[2] = (GLdouble) map2d->v1; @@ -606,11 +622,22 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" ); } + return; + +overflow: + _mesa_error( ctx, GL_INVALID_OPERATION, + "glGetnMapdvARB(out of bounds: bufSize is %d," + " but %d bytes are required)", bufSize, numBytes ); } +static void GLAPIENTRY +_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) +{ + _mesa_GetnMapdvARB(target, query, INT_MAX, v); +} static void GLAPIENTRY -_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) +_mesa_GetnMapfvARB( GLenum target, GLenum query, GLsizei bufSize, GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); struct gl_1d_map *map1d; @@ -618,6 +645,7 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) GLint i, n; GLfloat *data; GLuint comps; + GLsizei numBytes; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -642,6 +670,9 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) n = map2d->Uorder * map2d->Vorder * comps; } if (data) { + numBytes = n * sizeof *v; + if (bufSize < numBytes) + goto overflow; for (i=0;i<n;i++) { v[i] = data[i]; } @@ -649,19 +680,31 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) break; case GL_ORDER: if (map1d) { + numBytes = 1 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = (GLfloat) map1d->Order; } else { + numBytes = 2 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = (GLfloat) map2d->Uorder; v[1] = (GLfloat) map2d->Vorder; } break; case GL_DOMAIN: if (map1d) { + numBytes = 2 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = map1d->u1; v[1] = map1d->u2; } else { + numBytes = 4 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = map2d->u1; v[1] = map2d->u2; v[2] = map2d->v1; @@ -671,11 +714,24 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" ); } + return; + +overflow: + _mesa_error( ctx, GL_INVALID_OPERATION, + "glGetnMapfvARB(out of bounds: bufSize is %d," + " but %d bytes are required)", bufSize, numBytes ); } static void GLAPIENTRY -_mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) +_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) +{ + _mesa_GetnMapfvARB(target, query, INT_MAX, v); +} + + +static void GLAPIENTRY +_mesa_GetnMapivARB( GLenum target, GLenum query, GLsizei bufSize, GLint *v ) { GET_CURRENT_CONTEXT(ctx); struct gl_1d_map *map1d; @@ -683,6 +739,7 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) GLuint i, n; GLfloat *data; GLuint comps; + GLsizei numBytes; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -707,6 +764,9 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) n = map2d->Uorder * map2d->Vorder * comps; } if (data) { + numBytes = n * sizeof *v; + if (bufSize < numBytes) + goto overflow; for (i=0;i<n;i++) { v[i] = IROUND(data[i]); } @@ -714,19 +774,31 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) break; case GL_ORDER: if (map1d) { + numBytes = 1 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = map1d->Order; } else { + numBytes = 2 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = map2d->Uorder; v[1] = map2d->Vorder; } break; case GL_DOMAIN: if (map1d) { + numBytes = 2 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = IROUND(map1d->u1); v[1] = IROUND(map1d->u2); } else { + numBytes = 4 * sizeof *v; + if (bufSize < numBytes) + goto overflow; v[0] = IROUND(map2d->u1); v[1] = IROUND(map2d->u2); v[2] = IROUND(map2d->v1); @@ -736,9 +808,21 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" ); } + return; + +overflow: + _mesa_error( ctx, GL_INVALID_OPERATION, + "glGetnMapivARB(out of bounds: bufSize is %d," + " but %d bytes are required)", bufSize, numBytes ); } +static void GLAPIENTRY +_mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) +{ + _mesa_GetnMapivARB(target, query, INT_MAX, v); +} + static void GLAPIENTRY _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) @@ -832,6 +916,11 @@ _mesa_init_eval_dispatch(struct _glapi_table *disp) SET_MapGrid1f(disp, _mesa_MapGrid1f); SET_MapGrid2d(disp, _mesa_MapGrid2d); SET_MapGrid2f(disp, _mesa_MapGrid2f); + + /* GL_ARB_robustness */ + SET_GetnMapdvARB(disp, _mesa_GetnMapdvARB); + SET_GetnMapfvARB(disp, _mesa_GetnMapfvARB); + SET_GetnMapivARB(disp, _mesa_GetnMapivARB); } |