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

login
register
mail settings
Submitter Ian Taylor
Date March 3, 2011, 6:40 a.m.
Message ID <mcrbp1s3dvu.fsf@google.com>
Download mbox | patch
Permalink /patch/85235/
State New
Headers show

Comments

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

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())