mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
PP: Fix #1104: Missing check for #if overflow.
Also, rationalized this to generally make it safer and more readable. It could use a more modern approach, at some point...
This commit is contained in:
parent
1a4bbc4a95
commit
7d67c6cbc2
20
Test/baseResults/cppDeepNest.frag.out
Executable file
20
Test/baseResults/cppDeepNest.frag.out
Executable file
@ -0,0 +1,20 @@
|
||||
cppDeepNest.frag
|
||||
ERROR: 0:66: '#if/#ifdef/#ifndef' : maximum nesting depth exceeded
|
||||
ERROR: 0:66: '' : missing #endif
|
||||
ERROR: 0:66: '' : syntax error, unexpected $end
|
||||
ERROR: 3 compilation errors. No code generated.
|
||||
|
||||
|
||||
Shader version: 100
|
||||
ERROR: node is still EOpNull!
|
||||
0:? Linker Objects
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
ERROR: Linking fragment stage: Missing entry point: Each stage requires one entry point
|
||||
|
||||
Shader version: 100
|
||||
ERROR: node is still EOpNull!
|
||||
0:? Linker Objects
|
||||
|
117
Test/cppDeepNest.frag
Normal file
117
Test/cppDeepNest.frag
Normal file
@ -0,0 +1,117 @@
|
||||
#ifdef O
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#if
|
||||
#endif
|
@ -241,15 +241,20 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||
int nextAtom = atomStrings.getAtom(ppToken->name);
|
||||
if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) {
|
||||
depth++;
|
||||
if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
|
||||
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if/#ifdef/#ifndef", "");
|
||||
return EndOfInput;
|
||||
} else {
|
||||
ifdepth++;
|
||||
elsetracker++;
|
||||
}
|
||||
} else if (nextAtom == PpAtomEndif) {
|
||||
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
|
||||
elseSeen[elsetracker] = false;
|
||||
--elsetracker;
|
||||
if (depth == 0) {
|
||||
// found the #endif we are looking for
|
||||
if (ifdepth)
|
||||
if (ifdepth > 0)
|
||||
--ifdepth;
|
||||
break;
|
||||
}
|
||||
@ -266,7 +271,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
||||
/* we decrement ifdepth here, because CPPif will increment
|
||||
* it and we really want to leave it alone */
|
||||
if (ifdepth) {
|
||||
if (ifdepth > 0) {
|
||||
--ifdepth;
|
||||
elseSeen[elsetracker] = false;
|
||||
--elsetracker;
|
||||
@ -536,11 +541,12 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T
|
||||
int TPpContext::CPPif(TPpToken* ppToken)
|
||||
{
|
||||
int token = scanToken(ppToken);
|
||||
if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
|
||||
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
|
||||
return EndOfInput;
|
||||
} else {
|
||||
elsetracker++;
|
||||
ifdepth++;
|
||||
if (ifdepth > maxIfNesting) {
|
||||
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
|
||||
return 0;
|
||||
}
|
||||
int res = 0;
|
||||
bool err = false;
|
||||
@ -556,11 +562,14 @@ int TPpContext::CPPif(TPpToken* ppToken)
|
||||
int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
|
||||
{
|
||||
int token = scanToken(ppToken);
|
||||
if (++ifdepth > maxIfNesting) {
|
||||
if (ifdepth > maxIfNesting || elsetracker > maxIfNesting) {
|
||||
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
|
||||
return 0;
|
||||
}
|
||||
return EndOfInput;
|
||||
} else {
|
||||
elsetracker++;
|
||||
ifdepth++;
|
||||
}
|
||||
|
||||
if (token != PpAtomIdentifier) {
|
||||
if (defined)
|
||||
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
|
||||
@ -886,16 +895,16 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||
token = CPPdefine(ppToken);
|
||||
break;
|
||||
case PpAtomElse:
|
||||
if (elsetracker[elseSeen])
|
||||
if (elseSeen[elsetracker])
|
||||
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
|
||||
elsetracker[elseSeen] = true;
|
||||
if (! ifdepth)
|
||||
elseSeen[elsetracker] = true;
|
||||
if (ifdepth == 0)
|
||||
parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
|
||||
token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken));
|
||||
token = CPPelse(0, ppToken);
|
||||
break;
|
||||
case PpAtomElif:
|
||||
if (! ifdepth)
|
||||
if (ifdepth == 0)
|
||||
parseContext.ppError(ppToken->loc, "mismatched statements", "#elif", "");
|
||||
if (elseSeen[elsetracker])
|
||||
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
||||
@ -906,7 +915,7 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||
token = CPPelse(0, ppToken);
|
||||
break;
|
||||
case PpAtomEndif:
|
||||
if (! ifdepth)
|
||||
if (ifdepth == 0)
|
||||
parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
|
||||
else {
|
||||
elseSeen[elsetracker] = false;
|
||||
|
@ -309,7 +309,7 @@ protected:
|
||||
bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
|
||||
bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
|
||||
|
||||
static const int maxIfNesting = 64;
|
||||
static const int maxIfNesting = 65;
|
||||
|
||||
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
|
||||
bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
|
||||
|
@ -82,6 +82,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
"cppBad.vert",
|
||||
"cppBad2.vert",
|
||||
"cppComplexExpr.vert",
|
||||
"cppDeepNest.frag",
|
||||
"badChars.frag",
|
||||
"pointCoord.frag",
|
||||
"array.frag",
|
||||
|
Loading…
Reference in New Issue
Block a user