Commit 870f4e19 authored by Russ Cox's avatar Russ Cox

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
parent 52e9bcaf
...@@ -33,7 +33,7 @@ static void stringtoarraylit(Node**); ...@@ -33,7 +33,7 @@ static void stringtoarraylit(Node**);
static Node* resolve(Node*); static Node* resolve(Node*);
static void checkdefergo(Node*); static void checkdefergo(Node*);
static int checkmake(Type*, char*, Node*); static int checkmake(Type*, char*, Node*);
static int checksliceindex(Node*, Type*); static int checksliceindex(Node*, Node*, Type*);
static int checksliceconst(Node*, Node*); static int checksliceconst(Node*, Node*);
static NodeList* typecheckdefstack; static NodeList* typecheckdefstack;
...@@ -311,6 +311,7 @@ typecheck1(Node **np, int top) ...@@ -311,6 +311,7 @@ typecheck1(Node **np, int top)
Type *t, *tp, *missing, *have, *badtype; Type *t, *tp, *missing, *have, *badtype;
Val v; Val v;
char *why, *desc, descbuf[64]; char *why, *desc, descbuf[64];
vlong x;
n = *np; n = *np;
...@@ -895,11 +896,12 @@ reswitch: ...@@ -895,11 +896,12 @@ reswitch:
break; break;
} }
if(isconst(n->right, CTINT)) { 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); 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); 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); 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) else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
yyerror("invalid %s index %N (index too large)", why, n->right); yyerror("invalid %s index %N (index too large)", why, n->right);
...@@ -999,9 +1001,9 @@ reswitch: ...@@ -999,9 +1001,9 @@ reswitch:
yyerror("cannot slice %N (type %T)", l, t); yyerror("cannot slice %N (type %T)", l, t);
goto error; 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; 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; goto error;
if(checksliceconst(lo, hi) < 0) if(checksliceconst(lo, hi) < 0)
goto error; goto error;
...@@ -1048,11 +1050,11 @@ reswitch: ...@@ -1048,11 +1050,11 @@ reswitch:
yyerror("cannot slice %N (type %T)", l, t); yyerror("cannot slice %N (type %T)", l, t);
goto error; 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; 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; 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; goto error;
if(checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0) if(checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0)
goto error; goto error;
...@@ -1822,7 +1824,7 @@ out: ...@@ -1822,7 +1824,7 @@ out:
} }
static int static int
checksliceindex(Node *r, Type *tp) checksliceindex(Node *l, Node *r, Type *tp)
{ {
Type *t; Type *t;
...@@ -1839,6 +1841,9 @@ checksliceindex(Node *r, Type *tp) ...@@ -1839,6 +1841,9 @@ checksliceindex(Node *r, Type *tp)
} else if(tp != nil && tp->bound > 0 && mpgetfix(r->val.u.xval) > tp->bound) { } 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); yyerror("invalid slice index %N (out of bounds for %d-element array)", r, tp->bound);
return -1; 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) { } else if(mpcmpfixfix(r->val.u.xval, maxintval[TINT]) > 0) {
yyerror("invalid slice index %N (index too large)", r); yyerror("invalid slice index %N (index too large)", r);
return -1; return -1;
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// issue 4232
// issue 7200
package p package p
func f() { func f() {
...@@ -12,22 +15,42 @@ 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[:-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[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 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[-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[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 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[:-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 var t string
_ = t[-1] // ERROR "invalid string index -1|index out of bounds" _ = 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[:-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"
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment