shithub: scc

Download patch

ref: a6cbaeb182ac4168f2213aa0afd7495c133e04b0
parent: cb444f385bf3ba8a4939844473be02af6ad69b95
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Apr 24 14:46:32 EDT 2015

Add security points in conditions and compounds

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -4,10 +4,13 @@
 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 */
--- 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 @@
 	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 @@
 	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 @@
 		if (accept(';'))
 			return;
 		do {
+			setsafe(END_LDECL);
+			setjmp(recover);
 			sym = declarator(base, ID_EXPECTED, NS_IDEN);
 			tp = sym->type;
 			sym->isstatic = 1;
--- a/cc1/error.c
+++ b/cc1/error.c
@@ -39,13 +39,10 @@
 	va_end(va);
 }
 
-bool
+void
 setsafe(uint8_t type)
 {
 	safe = type;
-	if (setjmp(recover))
-		return 0;
-	return 1;
 }
 
 void
@@ -53,6 +50,7 @@
 {
 	int c;
 	va_list va;
+	extern FILE *yyin;
 
 	va_start(va, fmt);
 	warn_helper(-1, fmt, va);
@@ -62,12 +60,24 @@
 	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;
--- 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 @@
 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 @@
 	}
 	linenum = 1;
 }
-
--- 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 @@
 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 @@
 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 @@
 	}
 	(*fun)(lbreak, lcont, lswitch);
 }
-