commit a6cbaeb182ac4168f2213aa0afd7495c133e04b0
parent cb444f385bf3ba8a4939844473be02af6ad69b95
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 24 Apr 2015 18:46:32 +0200
Add security points in conditions and compounds
Diffstat:
5 files changed, 47 insertions(+), 18 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -4,10 +4,13 @@ extern void error(char *fmt, ...);
extern void warn(char *fmt, ...);
extern void unexpected(void);
extern void softerror(char *fmt, ...);
-extern bool setsafe(uint8_t type);
+extern void setsafe(uint8_t type);
enum {
- END_DECL
+ END_DECL,
+ END_LDECL,
+ END_COMP,
+ END_COND
};
/* definitions of types */
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -1,5 +1,6 @@
#include <inttypes.h>
+#include <setjmp.h>
#include <string.h>
#include "../inc/sizes.h"
@@ -427,12 +428,17 @@ decl(void)
Type *tp;
Symbol *sym;
int8_t sclass, isfun;
+ extern jmp_buf recover;
+ setsafe(END_DECL);
+ setjmp(recover);
tp = specifier(&sclass);
if (accept(';'))
return;
do {
+ setsafe(END_LDECL);
+ setjmp(recover);
sym = declarator(tp, ID_EXPECTED, NS_IDEN);
isfun = sym->type->op == FTN;
@@ -492,9 +498,10 @@ extdecl(void)
int8_t sclass;
Symbol *sym;
extern Symbol *curfun;
+ extern jmp_buf recover;
- if (!setsafe(END_DECL))
- return;
+ setsafe(END_DECL);
+ setjmp(recover);
switch (yytoken) {
case IDEN: case TYPE: case TYPEIDEN: case SCLASS: case TQUALIFIER:
@@ -502,6 +509,8 @@ extdecl(void)
if (accept(';'))
return;
do {
+ setsafe(END_LDECL);
+ setjmp(recover);
sym = declarator(base, ID_EXPECTED, NS_IDEN);
tp = sym->type;
sym->isstatic = 1;
diff --git a/cc1/error.c b/cc1/error.c
@@ -39,13 +39,10 @@ warn(char *fmt, ...)
va_end(va);
}
-bool
+void
setsafe(uint8_t type)
{
safe = type;
- if (setjmp(recover))
- return 0;
- return 1;
}
void
@@ -53,6 +50,7 @@ error(char *fmt, ...)
{
int c;
va_list va;
+ extern FILE *yyin;
va_start(va, fmt);
warn_helper(-1, fmt, va);
@@ -62,12 +60,24 @@ error(char *fmt, ...)
c = yytoken;
do {
switch (safe) {
+ case END_COMP:
+ if (c == '}')
+ goto jump;
+ goto semicolon;
+ case END_COND:
+ if (c == ')')
+ goto jump;
+ break;
+ case END_LDECL:
+ if (c == ',')
+ goto jump;
case END_DECL:
+ semicolon:
if (c == ';')
goto jump;
break;
}
- } while ((c = getchar()) != EOF);
+ } while ((c = getc(yyin)) != EOF);
jump:
yytoken = c;
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -9,7 +9,7 @@
#include "../inc/cc.h"
#include "cc1.h"
-static FILE *yyin;
+FILE *yyin;
uint8_t lex_ns = NS_IDEN;
const char *filename;
unsigned linenum;
@@ -374,11 +374,10 @@ next(void)
void
expect(uint8_t tok)
{
- if (yytoken != tok) {
- softerror("unexpecetd '%s'", yytext);
- yytoken = tok;
- }
- next();
+ if (yytoken != tok)
+ softerror("expected '%c' before '%s'", tok, yytext);
+ else
+ next();
}
uint8_t
@@ -406,4 +405,3 @@ lexfile(const char *file)
}
linenum = 1;
}
-
diff --git a/cc1/stmt.c b/cc1/stmt.c
@@ -1,6 +1,7 @@
#include <stddef.h>
#include <inttypes.h>
+#include <setjmp.h>
#include <stdio.h>
#include "../inc/cc.h"
@@ -60,10 +61,16 @@ stmtexp(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
static Node *
condition(void)
{
+ extern jmp_buf recover;
+ extern Symbol *zero;
Node *np;
expect('(');
- np = iszero(expr());
+ setsafe(END_COND);
+ if (!setjmp(recover))
+ np = iszero(expr());
+ else
+ np = symbol(zero);
expect(')');
return np;
}
@@ -311,10 +318,13 @@ If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
void
compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
+ extern jmp_buf recover;
pushctx();
expect('{');
for (;;) {
+ setsafe(END_COMP);
+ setjmp(recover);
switch (yytoken) {
case '}':
goto end_compound;
@@ -369,4 +379,3 @@ stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
}
(*fun)(lbreak, lcont, lswitch);
}
-