shader_api: Fix bounds checking of glUniform and glUniformMatrix
authorNicolai Hähnle <nhaehnle@gmail.com>
Sat, 3 Oct 2009 14:30:16 +0000 (16:30 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Wed, 7 Oct 2009 18:36:23 +0000 (20:36 +0200)
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/shader/shader_api.c

index 178b7d0dbafb273d0f14c9d773c3de63622f44c8..b282d7af60af7f32e473b22b5928ed6cee932ebc 100644 (file)
@@ -1702,8 +1702,8 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
          /* we'll ignore extra data below */
       }
       else {
-         /* non-array: count must be one */
-         if (count != 1) {
+         /* non-array: count must be at most one; count == 0 is handled by the loop below */
+         if (count > 1) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
                         "glUniform(uniform is not an array)");
             return;
@@ -1880,20 +1880,27 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
                            GLboolean transpose, const GLfloat *values)
 {
    GLuint mat, row, col;
-   GLuint dst = index + offset, src = 0;
+   GLuint src = 0;
+   const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
+   const GLint slots = (param->Size + 3) / 4;
+   const GLint typeSize = sizeof_glsl_type(param->DataType);
    GLint nr, nc;
 
    /* check that the number of rows, columns is correct */
-   get_matrix_dims(program->Parameters->Parameters[index].DataType, &nr, &nc);
+   get_matrix_dims(param->DataType, &nr, &nc);
    if (rows != nr || cols != nc) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glUniformMatrix(matrix size mismatch)");
       return;
    }
 
-   if (index + offset > program->Parameters->Size) {
-      /* out of bounds! */
-      return;
+   if (param->Size <= typeSize) {
+      /* non-array: count must be at most one; count == 0 is handled by the loop below */
+      if (count > 1) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glUniformMatrix(uniform is not an array)");
+         return;
+      }
    }
 
    /*
@@ -1907,7 +1914,12 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
 
       /* each matrix: */
       for (col = 0; col < cols; col++) {
-         GLfloat *v = program->Parameters->ParameterValues[dst];
+         GLfloat *v;
+         if (offset >= slots) {
+            /* Ignore writes beyond the end of (the used part of) an array */
+            return;
+         }
+         v = program->Parameters->ParameterValues[index + offset];
          for (row = 0; row < rows; row++) {
             if (transpose) {
                v[row] = values[src + row * cols + col];
@@ -1916,7 +1928,8 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
                v[row] = values[src + col * rows + row];
             }
          }
-         dst++;
+
+         offset++;
       }
 
       src += rows * cols;  /* next matrix */