commit d6954f1a841ffe95aacc8c0e8a9dca44a087b1a6
parent 55eb22f73fd61f6a5393869d99d9098aee5b7337
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 18 Aug 2015 18:44:46 +0200
Limit the number of parameters, fields and enum constants
These checks control integer overflows related to xrealloc.
Diffstat:
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -159,9 +159,9 @@ parameter(struct decl *dcl)
sym->type = tp;
sym->flags |= ISUSED; /* avoid non used warnings in prototypes */
- if (n++ == NR_FUNPARAM)
+ if (n == NR_FUNPARAM)
error("too much parameters in function definition");
- funtp->p.pars = xrealloc(funtp->p.pars, n * sizeof(Type *));
+ funtp->p.pars = xrealloc(funtp->p.pars, ++n * sizeof(Type *));
funtp->p.pars[n-1] = tp;
funtp->n.elem = n;
@@ -441,7 +441,7 @@ enumdcl(void)
{
Type *tp;
Symbol *sym, *tagsym;
- int val;
+ int val, nctes;
tagsym = newtag();
tp = tagsym->type;
@@ -451,13 +451,15 @@ enumdcl(void)
if (tp->defined)
error("redefinition of enumeration '%s'", tagsym->name);
tp->defined = 1;
- for (val = 0; yytoken != ')'; ++val) {
+ for (nctes = val = 0; yytoken != ')'; ++nctes, ++val) {
if (yytoken != IDEN)
unexpected();
if ((sym = install(NS_IDEN, yylval.sym)) == NULL) {
error("'%s' redeclared as different kind of symbol",
yytext);
}
+ if (nctes == NR_ENUM_CTES)
+ error("too much enum constants in a single enum");
next();
sym->flags |= ISCONSTANT;
sym->type = inttype;
@@ -517,9 +519,9 @@ field(struct decl *dcl)
sym->type = tp;
sym->flags |= ISFIELD;
- if (n++ == NR_FUNPARAM)
+ if (n == NR_FIELDS)
error("too much fields in struct/union");
- structp->p.fields = xrealloc(structp->p.fields, n * sizeof(*sym));
+ structp->p.fields = xrealloc(structp->p.fields, ++n * sizeof(*sym));
structp->p.fields[n-1] = sym;
structp->n.elem = n;
diff --git a/cc1/stmt.c b/cc1/stmt.c
@@ -226,7 +226,8 @@ Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
pcase->next = lswitch->head;
emit(OLABEL, pcase->label = newsym(NS_LABEL));
lswitch->head = pcase;
- ++lswitch->nr;
+ if (++lswitch->nr == NR_SWITCH)
+ error("too case labels for a switch statement");
stmt(lbreak, lcont, lswitch);
}