[gtk+/wip/otte/shader: 24/26] gskslexpression: Detect out of range for array indexing
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 24/26] gskslexpression: Detect out of range for array indexing
- Date: Mon, 23 Oct 2017 03:19:15 +0000 (UTC)
commit 150003ea2116435da90505f963412a13a4a1015e
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]