Fix issues with preprocessor on very malformed shaders

Trac #15236,#15237,#15238,#15239 Error out instead of continued processing when we already know the preprocessor directives are bungled. Generally be more careful about the order in which cpp->elsetracker and cpp->ifdepth are checked/operated on. Validate all accesses of cpp->elsedepth to ensure no out of bounds accesses occur. Also slipped in a few indentation/spacing fixes. Signed-off-by: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@540 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent a0ce7e61
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 539
#define BUILD_REVISION 540
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -59,6 +59,7 @@ typedef struct Options_Rec{
int DumpAtomTable;
} Options;
#define MAX_IF_NESTING 64
struct CPPStruct_Rec {
// Public members
SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers
......@@ -80,7 +81,7 @@ struct CPPStruct_Rec {
// Private members:
SourceLoc ltokenLoc;
int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor)
int elsedepth[64]; //Keep a track of #if depth..Max allowed is 64.
int elsedepth[MAX_IF_NESTING];//Keep a track of #if depth..Max allowed is 64.
int elsetracker; //#if-#else and #endif constructs...Counter.
const char *ErrMsg;
int CompileError; //Indicate compile error when #error, #else,#elif mismatch.
......
......@@ -84,7 +84,6 @@ static int extensionAtom = 0;
static Scope *macros = 0;
#define MAX_MACRO_ARGS 64
#define MAX_IF_NESTING 64
static SourceLoc ifloc; /* outermost #if */
......@@ -285,18 +284,30 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp)
atom = yylvalpp->sc_ident;
if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){
depth++; cpp->ifdepth++; cpp->elsetracker++;
if (cpp->ifdepth > MAX_IF_NESTING) {
CPPErrorToInfoLog("max #if nesting depth exceeded");
cpp->CompileError = 1;
return 0;
}
// sanity check elsetracker
if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
CPPErrorToInfoLog("mismatched #if/#endif statements");
cpp->CompileError = 1;
return 0;
}
cpp->elsedepth[cpp->elsetracker] = 0;
}
else if (atom == endifAtom) {
}
else if (atom == endifAtom) {
if(--depth<0){
--cpp->elsetracker;
if (cpp->elsetracker)
--cpp->elsetracker;
if (cpp->ifdepth)
--cpp->ifdepth;
break;
}
--cpp->elsetracker;
--cpp->ifdepth;
}
--cpp->elsetracker;
--cpp->ifdepth;
}
else if (((int)(matchelse) != 0)&& depth==0) {
if (atom == elseAtom ) {
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
......@@ -325,6 +336,7 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp)
else if((atom==elseAtom) && (!ChkCorrectElseNesting())){
CPPErrorToInfoLog("#else after a #else");
cpp->CompileError=1;
return 0;
}
};
return token;
......@@ -469,15 +481,24 @@ error:
static int CPPif(yystypepp * yylvalpp) {
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
int res = 0, err = 0;
cpp->elsetracker++;
cpp->elsedepth[cpp->elsetracker] = 0;
if (!cpp->ifdepth++)
ifloc = *cpp->tokenLoc;
if(cpp->ifdepth >MAX_IF_NESTING){
if(cpp->ifdepth > MAX_IF_NESTING){
CPPErrorToInfoLog("max #if nesting depth exceeded");
return 0;
}
token = eval(token, MIN_PREC, &res, &err, yylvalpp);
cpp->CompileError = 1;
return 0;
}
cpp->elsetracker++;
// sanity check elsetracker
if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
CPPErrorToInfoLog("mismatched #if/#endif statements");
cpp->CompileError = 1;
return 0;
}
cpp->elsedepth[cpp->elsetracker] = 0;
token = eval(token, MIN_PREC, &res, &err, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following #if preprocessor directive - expected a newline");
while (token != '\n') {
......@@ -499,12 +520,20 @@ static int CPPifdef(int defined, yystypepp * yylvalpp)
{
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
int name = yylvalpp->sc_ident;
if(++cpp->ifdepth >MAX_IF_NESTING){
CPPErrorToInfoLog("max #if nesting depth exceeded");
return 0;
}
cpp->elsetracker++;
if(++cpp->ifdepth > MAX_IF_NESTING){
CPPErrorToInfoLog("max #if nesting depth exceeded");
cpp->CompileError = 1;
return 0;
}
cpp->elsetracker++;
// sanity check elsetracker
if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
CPPErrorToInfoLog("mismatched #if/#endif statements");
cpp->CompileError = 1;
return 0;
}
cpp->elsedepth[cpp->elsetracker] = 0;
if (token != CPP_IDENTIFIER) {
defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef");
} else {
......@@ -748,6 +777,7 @@ int readCPPline(yystypepp * yylvalpp)
if (!cpp->ifdepth ){
CPPErrorToInfoLog("#else mismatch");
cpp->CompileError=1;
return 0;
}
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
......@@ -763,14 +793,17 @@ int readCPPline(yystypepp * yylvalpp)
token = CPPelse(0, yylvalpp);
}else{
CPPErrorToInfoLog("#else after a #else");
cpp->ifdepth=0;
cpp->ifdepth = 0;
cpp->elsetracker = 0;
cpp->pastFirstStatement = 1;
cpp->CompileError = 1;
return 0;
}
} else if (yylvalpp->sc_ident == elifAtom) {
if (!cpp->ifdepth){
CPPErrorToInfoLog("#elif mismatch");
cpp->CompileError=1;
return 0;
}
// this token is really a dont care, but we still need to eat the tokens
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
......@@ -779,18 +812,22 @@ int readCPPline(yystypepp * yylvalpp)
if (token <= 0) { // EOF or error
CPPErrorToInfoLog("unexpect tokens following #elif preprocessor directive - expected a newline");
cpp->CompileError = 1;
break;
return 0;
}
}
token = CPPelse(0, yylvalpp);
} else if (yylvalpp->sc_ident == endifAtom) {
--cpp->elsetracker;
if (!cpp->ifdepth){
CPPErrorToInfoLog("#endif mismatch");
cpp->CompileError=1;
return 0;
}
else
--cpp->ifdepth;
--cpp->ifdepth;
if (cpp->elsetracker)
--cpp->elsetracker;
} else if (yylvalpp->sc_ident == ifAtom) {
token = CPPif(yylvalpp);
} else if (yylvalpp->sc_ident == ifdefAtom) {
......@@ -1051,9 +1088,14 @@ int MacroExpand(int atom, yystypepp * yylvalpp)
int ChkCorrectElseNesting(void)
{
if(cpp->elsedepth[cpp->elsetracker]==0){
cpp->elsedepth[cpp->elsetracker]=1;
return 1;
// sanity check to make sure elsetracker is in a valid range
if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
return 0;
}
if (cpp->elsedepth[cpp->elsetracker] == 0) {
cpp->elsedepth[cpp->elsetracker] = 1;
return 1;
}
return 0;
}
......
......@@ -92,12 +92,12 @@ int ResetPreprocessor(void)
cpp->lastSourceLoc.file = 0;
cpp->lastSourceLoc.line = 0;
cpp->pC=0;
cpp->CompileError=0;
cpp->ifdepth=0;
for(cpp->elsetracker=0; cpp->elsetracker<64; cpp->elsetracker++)
cpp->elsedepth[cpp->elsetracker]=0;
cpp->elsetracker=0;
cpp->pC = 0;
cpp->CompileError = 0;
cpp->ifdepth = 0;
for(cpp->elsetracker = 0; cpp->elsetracker < MAX_IF_NESTING; cpp->elsetracker++)
cpp->elsedepth[cpp->elsetracker] = 0;
cpp->elsetracker = 0;
cpp->tokensBeforeEOF = 0;
return 1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment