From 870f4e190ccbc70900bd0ba724d4f4c1e14e3070 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 25 Sep 2014 13:24:43 -0400 Subject: [PATCH] cmd/gc: emit error for out-of-bounds slice of constant string Fixes #7200. LGTM=gri, iant R=golang-codereviews, gri, iant CC=golang-codereviews, r https://golang.org/cl/150020044 --- src/cmd/gc/typecheck.c | 25 +++++++++++++++---------- test/fixedbugs/issue4232.go | 29 ++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 9440526060..ff49fe6f92 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -33,7 +33,7 @@ static void stringtoarraylit(Node**); static Node* resolve(Node*); static void checkdefergo(Node*); static int checkmake(Type*, char*, Node*); -static int checksliceindex(Node*, Type*); +static int checksliceindex(Node*, Node*, Type*); static int checksliceconst(Node*, Node*); static NodeList* typecheckdefstack; @@ -311,6 +311,7 @@ typecheck1(Node **np, int top) Type *t, *tp, *missing, *have, *badtype; Val v; char *why, *desc, descbuf[64]; + vlong x; n = *np; @@ -895,11 +896,12 @@ reswitch: break; } if(isconst(n->right, CTINT)) { - if(mpgetfix(n->right->val.u.xval) < 0) + x = mpgetfix(n->right->val.u.xval); + if(x < 0) yyerror("invalid %s index %N (index must be non-negative)", why, n->right); - else if(isfixedarray(t) && t->bound > 0 && mpgetfix(n->right->val.u.xval) >= t->bound) + else if(isfixedarray(t) && t->bound > 0 && x >= t->bound) yyerror("invalid array index %N (out of bounds for %d-element array)", n->right, t->bound); - else if(isconst(n->left, CTSTR) && mpgetfix(n->right->val.u.xval) >= n->left->val.u.sval->len) + else if(isconst(n->left, CTSTR) && x >= n->left->val.u.sval->len) yyerror("invalid string index %N (out of bounds for %d-byte string)", n->right, n->left->val.u.sval->len); else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0) yyerror("invalid %s index %N (index too large)", why, n->right); @@ -999,9 +1001,9 @@ reswitch: yyerror("cannot slice %N (type %T)", l, t); goto error; } - if((lo = n->right->left) != N && checksliceindex(lo, tp) < 0) + if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0) goto error; - if((hi = n->right->right) != N && checksliceindex(hi, tp) < 0) + if((hi = n->right->right) != N && checksliceindex(l, hi, tp) < 0) goto error; if(checksliceconst(lo, hi) < 0) goto error; @@ -1048,11 +1050,11 @@ reswitch: yyerror("cannot slice %N (type %T)", l, t); goto error; } - if((lo = n->right->left) != N && checksliceindex(lo, tp) < 0) + if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0) goto error; - if((mid = n->right->right->left) != N && checksliceindex(mid, tp) < 0) + if((mid = n->right->right->left) != N && checksliceindex(l, mid, tp) < 0) goto error; - if((hi = n->right->right->right) != N && checksliceindex(hi, tp) < 0) + if((hi = n->right->right->right) != N && checksliceindex(l, hi, tp) < 0) goto error; if(checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0) goto error; @@ -1822,7 +1824,7 @@ out: } static int -checksliceindex(Node *r, Type *tp) +checksliceindex(Node *l, Node *r, Type *tp) { Type *t; @@ -1839,6 +1841,9 @@ checksliceindex(Node *r, Type *tp) } else if(tp != nil && tp->bound > 0 && mpgetfix(r->val.u.xval) > tp->bound) { yyerror("invalid slice index %N (out of bounds for %d-element array)", r, tp->bound); return -1; + } else if(isconst(l, CTSTR) && mpgetfix(r->val.u.xval) > l->val.u.sval->len) { + yyerror("invalid slice index %N (out of bounds for %d-byte string)", r, l->val.u.sval->len); + return -1; } else if(mpcmpfixfix(r->val.u.xval, maxintval[TINT]) > 0) { yyerror("invalid slice index %N (index too large)", r); return -1; diff --git a/test/fixedbugs/issue4232.go b/test/fixedbugs/issue4232.go index e5daa65623..755b1b1de0 100644 --- a/test/fixedbugs/issue4232.go +++ b/test/fixedbugs/issue4232.go @@ -4,6 +4,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// issue 4232 +// issue 7200 + package p func f() { @@ -12,22 +15,42 @@ func f() { _ = a[-1:] // ERROR "invalid slice index -1|index out of bounds" _ = a[:-1] // ERROR "invalid slice index -1|index out of bounds" _ = a[10] // ERROR "invalid array index 10|index out of bounds" + _ = a[9:10] + _ = a[10:10] + _ = a[9:12] // ERROR "invalid slice index 12|index out of bounds" + _ = a[11:12] // ERROR "invalid slice index 11|index out of bounds" + _ = a[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds" var s []int _ = s[-1] // ERROR "invalid slice index -1|index out of bounds" _ = s[-1:] // ERROR "invalid slice index -1|index out of bounds" _ = s[:-1] // ERROR "invalid slice index -1|index out of bounds" _ = s[10] + _ = s[9:10] + _ = s[10:10] + _ = s[9:12] + _ = s[11:12] + _ = s[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds" - const c = "foo" + const c = "foofoofoof" _ = c[-1] // ERROR "invalid string index -1|index out of bounds" _ = c[-1:] // ERROR "invalid slice index -1|index out of bounds" _ = c[:-1] // ERROR "invalid slice index -1|index out of bounds" - _ = c[3] // ERROR "invalid string index 3|index out of bounds" + _ = c[10] // ERROR "invalid string index 10|index out of bounds" + _ = c[9:10] + _ = c[10:10] + _ = c[9:12] // ERROR "invalid slice index 12|index out of bounds" + _ = c[11:12] // ERROR "invalid slice index 11|index out of bounds" + _ = c[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds" var t string _ = t[-1] // ERROR "invalid string index -1|index out of bounds" _ = t[-1:] // ERROR "invalid slice index -1|index out of bounds" _ = t[:-1] // ERROR "invalid slice index -1|index out of bounds" - _ = t[3] + _ = t[10] + _ = t[9:10] + _ = t[10:10] + _ = t[9:12] + _ = t[11:12] + _ = t[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds" } -- 2.50.0