scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
Mcc1/decl.c | 12++++++++++++
Mcc1/expr.c | 4++++
Mcc1/stmt.c | 8++++++++
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(); /*