[gtk+/wip/otte/shader: 96/98] gskslexpression: Detect out of range for array indexing



commit 9d8ff423a0f89232c63616256841c3c82089438a
Author: Benjamin Otte <otte redhat com>
Date:   Mon Oct 23 03:53:27 2017 +0200

    gskslexpression: Detect out of range for array indexing
    
    Obviously this only works for constants, but that should be enough.

 gsk/gskslcompiler.h                                |    1 +
 gsk/gskslexpression.c                              |   51 +++++++++++++++-----
 .../gsksl/errors/array-index-out-of-range.glsl     |    8 +++
 testsuite/gsksl/errors/negative-array-index.glsl   |    8 +++
 4 files changed, 55 insertions(+), 13 deletions(-)
---
diff --git a/gsk/gskslcompiler.h b/gsk/gskslcompiler.h
index 8a549ab..ba82df7 100644
--- a/gsk/gskslcompiler.h
+++ b/gsk/gskslcompiler.h
@@ -32,6 +32,7 @@ typedef enum {
   GSK_SL_COMPILER_ERROR_CONSTANT,
   GSK_SL_COMPILER_ERROR_DECLARATION,
   GSK_SL_COMPILER_ERROR_PREPROCESSOR,
+  GSK_SL_COMPILER_ERROR_RANGE,
   GSK_SL_COMPILER_ERROR_SCOPE,
   GSK_SL_COMPILER_ERROR_SYNTAX,
   GSK_SL_COMPILER_ERROR_TOKENIZER,
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index bdabdbc..ba2e2de 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -2457,7 +2457,7 @@ gsk_sl_expression_parse_postfix (GskSlScope        *scope,
         {
           GskSlExpressionIndex *index;
           GskSlExpression *index_expr;
-          GskSlType *type;
+          GskSlType *type, *index_type;
 
           gsk_sl_preprocessor_consume (stream, NULL);
 
@@ -2472,23 +2472,48 @@ gsk_sl_expression_parse_postfix (GskSlScope        *scope,
             }
           gsk_sl_preprocessor_consume (stream, NULL);
 
-          type = gsk_sl_expression_get_return_type (index_expr);
-          if (!gsk_sl_type_equal (type, gsk_sl_type_get_scalar (GSK_SL_INT)) &&
-              !gsk_sl_type_equal (type, gsk_sl_type_get_scalar (GSK_SL_UINT)))
+          type = gsk_sl_expression_get_return_type (expr);
+          if (gsk_sl_type_get_length (type) == 0)
             {
-              gsk_sl_preprocessor_error (stream, SYNTAX, "Array index must be an integer type, not %s.", 
gsk_sl_type_get_name (type));
+              gsk_sl_preprocessor_error (stream, SYNTAX, "Cannot index values of type %s.", 
gsk_sl_type_get_name (type));
               gsk_sl_expression_unref (index_expr);
               continue;
             }
 
-          type = gsk_sl_expression_get_return_type (expr);
-          if (gsk_sl_type_get_length (type) == 0)
+          index_type = gsk_sl_expression_get_return_type (index_expr);
+          if (!gsk_sl_type_equal (index_type, gsk_sl_type_get_scalar (GSK_SL_INT)) &&
+              !gsk_sl_type_equal (index_type, gsk_sl_type_get_scalar (GSK_SL_UINT)))
             {
-              gsk_sl_preprocessor_error (stream, SYNTAX, "Cannot index values of type %s.", 
gsk_sl_type_get_name (type));
+              gsk_sl_preprocessor_error (stream, SYNTAX, "Array index must be an integer type, not %s.", 
gsk_sl_type_get_name (index_type));
               gsk_sl_expression_unref (index_expr);
               continue;
             }
-          /* XXX: do range check for constants here */
+          else
+            {
+              GskSlValue *constant;
+
+              constant = gsk_sl_expression_get_constant (index_expr);
+              if (constant)
+                {
+                  guint32 u = *(guint32 *) gsk_sl_value_get_data (constant);
+
+                  gsk_sl_value_free (constant);
+
+                  if (gsk_sl_type_equal (index_type, gsk_sl_type_get_scalar (GSK_SL_INT)) &&
+                      (gint32) u < 0)
+                    {
+                      gsk_sl_preprocessor_error (stream, RANGE, "Negative index %d not allowed for %s.", 
(int) (gint32) u, gsk_sl_type_get_name (type));
+                      gsk_sl_expression_unref (index_expr);
+                      continue;
+                    }
+                  if (u >= gsk_sl_type_get_length (type))
+                    {
+                      gsk_sl_preprocessor_error (stream, RANGE, "Index %u is out of range for %s.", (guint) 
u, gsk_sl_type_get_name (type));
+                      gsk_sl_expression_unref (index_expr);
+                      continue;
+                    }
+                }
+            }
 
           index = gsk_sl_expression_new (GskSlExpressionIndex, &GSK_SL_EXPRESSION_INDEX);
           index->expr = expr;
@@ -3117,14 +3142,14 @@ gsk_sl_expression_parse_integral_constant (GskSlScope        *scope,
 
       if (i < minimum)
         {
-          gsk_sl_preprocessor_error (preproc, CONSTANT,
+          gsk_sl_preprocessor_error (preproc, RANGE,
                                      "Constant expression evaluates to %d, but must be at least %d.",
                                      i, minimum);
           i = minimum;
         }
       else if (i > maximum)
         {
-          gsk_sl_preprocessor_error (preproc, CONSTANT,
+          gsk_sl_preprocessor_error (preproc, RANGE,
                                      "Constant expression evaluates to %d, but must be at most %d.",
                                      i, maximum);
           i = maximum;
@@ -3141,14 +3166,14 @@ gsk_sl_expression_parse_integral_constant (GskSlScope        *scope,
 
       if (minimum >= 0 && u < minimum)
         {
-          gsk_sl_preprocessor_error (preproc, CONSTANT,
+          gsk_sl_preprocessor_error (preproc, RANGE,
                                      "Constant expression evaluates to %u, but must be at least %d.",
                                      u, minimum);
           i = minimum;
         }
       else if (maximum > 0 && u > maximum)
         {
-          gsk_sl_preprocessor_error (preproc, CONSTANT,
+          gsk_sl_preprocessor_error (preproc, RANGE,
                                      "Constant expression evaluates to %u, but must be at most %d.",
                                      u, maximum);
           i = maximum;
diff --git a/testsuite/gsksl/errors/array-index-out-of-range.glsl 
b/testsuite/gsksl/errors/array-index-out-of-range.glsl
new file mode 100644
index 0000000..c99bf66
--- /dev/null
+++ b/testsuite/gsksl/errors/array-index-out-of-range.glsl
@@ -0,0 +1,8 @@
+
+void
+main  ()
+{
+  int x[10];
+  
+  int y = x[10];
+}
diff --git a/testsuite/gsksl/errors/negative-array-index.glsl 
b/testsuite/gsksl/errors/negative-array-index.glsl
new file mode 100644
index 0000000..16f5a39
--- /dev/null
+++ b/testsuite/gsksl/errors/negative-array-index.glsl
@@ -0,0 +1,8 @@
+
+void
+main  ()
+{
+  int x[10];
+  
+  int y = x[-3];
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]