From patchwork Thu Mar 3 06:40:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 85235 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 4CE54B70E4 for ; Thu, 3 Mar 2011 17:41:13 +1100 (EST) Received: (qmail 27380 invoked by alias); 3 Mar 2011 06:41:06 -0000 Received: (qmail 27366 invoked by uid 22791); 3 Mar 2011 06:41:05 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 03 Mar 2011 06:41:00 +0000 Received: from wpaz1.hot.corp.google.com (wpaz1.hot.corp.google.com [172.24.198.65]) by smtp-out.google.com with ESMTP id p236ewSB006106 for ; Wed, 2 Mar 2011 22:40:58 -0800 Received: from iwn9 (iwn9.prod.google.com [10.241.68.73]) by wpaz1.hot.corp.google.com with ESMTP id p236efou029047 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Wed, 2 Mar 2011 22:40:57 -0800 Received: by iwn9 with SMTP id 9so860604iwn.37 for ; Wed, 02 Mar 2011 22:40:57 -0800 (PST) Received: by 10.42.75.129 with SMTP id a1mr1121809ick.226.1299134457337; Wed, 02 Mar 2011 22:40:57 -0800 (PST) Received: from coign.google.com ([216.239.45.130]) by mx.google.com with ESMTPS id z4sm641137ibg.19.2011.03.02.22.40.55 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 02 Mar 2011 22:40:56 -0800 (PST) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Don't crash on large composite literal index Date: Wed, 02 Mar 2011 22:40:53 -0800 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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())