]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: emit error for out-of-bounds slice of constant string
authorRuss Cox <rsc@golang.org>
Thu, 25 Sep 2014 17:24:43 +0000 (13:24 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 25 Sep 2014 17:24:43 +0000 (13:24 -0400)
Fixes #7200.

LGTM=gri, iant
R=golang-codereviews, gri, iant
CC=golang-codereviews, r
https://golang.org/cl/150020044

src/cmd/gc/typecheck.c
test/fixedbugs/issue4232.go

index 9440526060145fa51dc2c96d758429e3b8266de2..ff49fe6f92e5fa6e8b153660052e17fd9b19dd6f 100644 (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;
index e5daa656235e715d60c5778049ebb249ac812f80..755b1b1de076bb4ba19f87ac320d1ce6efe9e8e2 100644 (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"
 }