Go patch committed: Don't crash on large composite literal index

Submitted by Ian Taylor on March 3, 2011, 6:40 a.m.

Details

Message ID mcrbp1s3dvu.fsf@google.com
State New
Headers show

Commit Message

Ian Taylor March 3, 2011, 6:40 a.m.
This patch to the Go frontend avoids crashing if the index in an array
or slice composite literal is very large.  Part of this patch tests for
an invalid value.  Part tests for a value which is too large for the
representation used in the frontend, which is to simply build an array
holding all the values.  The latter could be fixed at some time if there
is a real use for this case.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch hide | download patch | download mbox

diff -r 346e353e08f1 go/expressions.cc
--- a/go/expressions.cc	Wed Mar 02 22:18:13 2011 -0800
+++ b/go/expressions.cc	Wed Mar 02 22:34:20 2011 -0800
@@ -11885,6 +11885,7 @@ 
 	{
 	  mpz_t ival;
 	  mpz_init(ival);
+
 	  Type* dummy;
 	  if (!index_expr->integer_constant_value(true, ival, &dummy))
 	    {
@@ -11893,12 +11894,14 @@ 
 		       "index expression is not integer constant");
 	      return Expression::make_error(location);
 	    }
+
 	  if (mpz_sgn(ival) < 0)
 	    {
 	      mpz_clear(ival);
 	      error_at(index_expr->location(), "index expression is negative");
 	      return Expression::make_error(location);
 	    }
+
 	  index = mpz_get_ui(ival);
 	  if (mpz_cmp_ui(ival, index) != 0)
 	    {
@@ -11906,7 +11909,30 @@ 
 	      error_at(index_expr->location(), "index value overflow");
 	      return Expression::make_error(location);
 	    }
+
+	  Named_type* ntype = Type::lookup_integer_type("int");
+	  Integer_type* inttype = ntype->integer_type();
+	  mpz_t max;
+	  mpz_init_set_ui(max, 1);
+	  mpz_mul_2exp(max, max, inttype->bits() - 1);
+	  bool ok = mpz_cmp(ival, max) < 0;
+	  mpz_clear(max);
+	  if (!ok)
+	    {
+	      mpz_clear(ival);
+	      error_at(index_expr->location(), "index value overflow");
+	      return Expression::make_error(location);
+	    }
+
 	  mpz_clear(ival);
+
+	  // FIXME: Our representation isn't very good; this avoids
+	  // thrashing.
+	  if (index > 0x1000000)
+	    {
+	      error_at(index_expr->location(), "index too large for compiler");
+	      return Expression::make_error(location);
+	    }
 	}
 
       if (index == vals.size())