mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
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:
parent
52e9bcafe1
commit
870f4e190c
2 changed files with 41 additions and 13 deletions
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue