mirror of
https://github.com/golang/go
synced 2024-11-26 00:57:56 -07:00
cmd/gc: check for array bounds overflow in slice expression
The test for this is test/index.go, which is not run by default. That test does not currently pass even after this is applied, due to issue 4348. Fixes #4344. R=golang-dev, daniel.morsing, rsc CC=golang-dev https://golang.org/cl/6815085
This commit is contained in:
parent
0ead18c59e
commit
72bf3bc176
@ -905,7 +905,8 @@ reswitch:
|
||||
defaultlit(&n->left, T);
|
||||
defaultlit(&n->right->left, T);
|
||||
defaultlit(&n->right->right, T);
|
||||
if(isfixedarray(n->left->type)) {
|
||||
l = n->left;
|
||||
if(isfixedarray(l->type)) {
|
||||
if(!islvalue(n->left)) {
|
||||
yyerror("invalid operation %N (slice of unaddressable value)", n);
|
||||
goto error;
|
||||
@ -913,6 +914,26 @@ reswitch:
|
||||
n->left = nod(OADDR, n->left, N);
|
||||
n->left->implicit = 1;
|
||||
typecheck(&n->left, Erv);
|
||||
l = n->left;
|
||||
}
|
||||
if((t = l->type) == T)
|
||||
goto error;
|
||||
tp = nil;
|
||||
if(istype(t, TSTRING)) {
|
||||
n->type = t;
|
||||
n->op = OSLICESTR;
|
||||
} else if(isptr[t->etype] && isfixedarray(t->type)) {
|
||||
tp = t->type;
|
||||
n->type = typ(TARRAY);
|
||||
n->type->type = tp->type;
|
||||
n->type->bound = -1;
|
||||
dowidth(n->type);
|
||||
n->op = OSLICEARR;
|
||||
} else if(isslice(t)) {
|
||||
n->type = t;
|
||||
} else {
|
||||
yyerror("cannot slice %N (type %T)", l, t);
|
||||
goto error;
|
||||
}
|
||||
if(n->right->left != N) {
|
||||
if((t = n->right->left->type) == T)
|
||||
@ -921,8 +942,12 @@ reswitch:
|
||||
yyerror("invalid slice index %N (type %T)", n->right->left, t);
|
||||
goto error;
|
||||
}
|
||||
if(n->right->left->op == OLITERAL && mpgetfix(n->right->left->val.u.xval) < 0)
|
||||
yyerror("invalid slice index %N (index must be non-negative)", n->right->left);
|
||||
if(n->right->left->op == OLITERAL) {
|
||||
if(mpgetfix(n->right->left->val.u.xval) < 0)
|
||||
yyerror("invalid slice index %N (index must be non-negative)", n->right->left);
|
||||
else if(tp != nil && tp->bound > 0 && mpgetfix(n->right->left->val.u.xval) > tp->bound)
|
||||
yyerror("invalid slice index %N (out of bounds for %d-element array)", n->right->left, tp->bound);
|
||||
}
|
||||
}
|
||||
if(n->right->right != N) {
|
||||
if((t = n->right->right->type) == T)
|
||||
@ -931,31 +956,14 @@ reswitch:
|
||||
yyerror("invalid slice index %N (type %T)", n->right->right, t);
|
||||
goto error;
|
||||
}
|
||||
if(n->right->right->op == OLITERAL && mpgetfix(n->right->right->val.u.xval) < 0)
|
||||
yyerror("invalid slice index %N (index must be non-negative)", n->right->right);
|
||||
if(n->right->right->op == OLITERAL) {
|
||||
if(mpgetfix(n->right->right->val.u.xval) < 0)
|
||||
yyerror("invalid slice index %N (index must be non-negative)", n->right->right);
|
||||
else if(tp != nil && tp->bound > 0 && mpgetfix(n->right->right->val.u.xval) > tp->bound)
|
||||
yyerror("invalid slice index %N (out of bounds for %d-element array)", n->right->right, tp->bound);
|
||||
}
|
||||
}
|
||||
l = n->left;
|
||||
if((t = l->type) == T)
|
||||
goto error;
|
||||
if(istype(t, TSTRING)) {
|
||||
n->type = t;
|
||||
n->op = OSLICESTR;
|
||||
goto ret;
|
||||
}
|
||||
if(isptr[t->etype] && isfixedarray(t->type)) {
|
||||
n->type = typ(TARRAY);
|
||||
n->type->type = t->type->type;
|
||||
n->type->bound = -1;
|
||||
dowidth(n->type);
|
||||
n->op = OSLICEARR;
|
||||
goto ret;
|
||||
}
|
||||
if(isslice(t)) {
|
||||
n->type = t;
|
||||
goto ret;
|
||||
}
|
||||
yyerror("cannot slice %N (type %T)", l, t);
|
||||
goto error;
|
||||
goto ret;
|
||||
|
||||
/*
|
||||
* call and call like
|
||||
|
Loading…
Reference in New Issue
Block a user