commit 1ea33a55b6d3df7fd73194f0f2a599960c67676e
parent e4c9da7e693f8c2ad9008ad2c895654d563905fe
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 18 Aug 2015 14:16:10 +0200
Limit the recursivity in declarations and expressions
Recursivity can generate a segfault or a heap-stack collition,
so it is a good idea limiting it with the values proposed by
c89 standard (if your code have more of 32 parentheses nested
try to use a lisp interpreter).
Diffstat:
3 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -207,9 +207,14 @@ static void
directdcl(struct declarators *dp, unsigned ns)
{
Symbol *sym;
+ static int nested;
if (accept('(')) {
+ if (nested == NR_SUBTYPE)
+ error("too declarators nested by parentheses");
+ ++nested;
declarator(dp, ns);
+ --nested;
expect(')');
} else {
if (yytoken == IDEN || yytoken == TYPEIDEN) {
@@ -409,6 +414,7 @@ structdcl(void)
{
Symbol *sym;
Type *tp;
+ static int nested;
sym = newtag();
tp = sym->type;
@@ -419,8 +425,14 @@ structdcl(void)
error("redefinition of struct/union '%s'", sym->name);
tp->defined = 1;
+ if (nested == NR_STRUCT_LEVEL)
+ error("too levels of nested structure or union definitions");
+
+ ++nested;
while (!accept('}'))
fieldlist(tp);
+ --nested;
+
return tp;
}
diff --git a/cc1/expr.c b/cc1/expr.c
@@ -4,6 +4,7 @@
#include <string.h>
#include "../inc/cc.h"
+#include "../inc/sizes.h"
#include "cc1.h"
@@ -870,6 +871,7 @@ cast(void)
{
Node *lp, *rp;
Type *tp;
+ static int nested;
if (!accept('('))
return unary();
@@ -893,6 +895,8 @@ cast(void)
}
break;
default:
+ if (nested == NR_SUBEXPR)
+ error("too expressions nested by parentheses");
rp = expr();
expect(')');
rp = postfix(rp);
diff --git a/cc1/stmt.c b/cc1/stmt.c
@@ -5,6 +5,7 @@
#include <stdio.h>
#include "../inc/cc.h"
+#include "../inc/sizes.h"
#include "cc1.h"
Symbol *curfun;
@@ -297,14 +298,21 @@ blockit(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
void
compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
+ static int nested;
+
pushctx();
expect('{');
+ if (nested == NR_BLOCK)
+ error("too nesting levels of compound statements");
+
+ ++nested;
for (;;) {
if (yytoken == '}')
break;
blockit(lbreak, lcont, lswitch);
}
+ --nested;
popctx();
/*