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
This commit is contained in:
Russ Cox 2014-09-25 13:24:43 -04:00
parent 52e9bcafe1
commit 870f4e190c
2 changed files with 41 additions and 13 deletions

View file

@ -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;

View file

@ -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"
}