fix attempted OOB access with broken swtich/case syntax
This commit is contained in:
parent
4d7e4f5f81
commit
9dc3d0d1d1
|
|
@ -1,7 +1,7 @@
|
||||||
module dscanner.analysis.base;
|
module dscanner.analysis.base;
|
||||||
|
|
||||||
import dparse.ast;
|
import dparse.ast;
|
||||||
import dparse.lexer : IdType, str, Token, tok;
|
import dparse.lexer : IdType, str, tok, Token;
|
||||||
import dscanner.analysis.nolint;
|
import dscanner.analysis.nolint;
|
||||||
import dsymbol.scope_ : Scope;
|
import dsymbol.scope_ : Scope;
|
||||||
import std.array;
|
import std.array;
|
||||||
|
|
@ -639,12 +639,13 @@ public:
|
||||||
{
|
{
|
||||||
// case and default statements always open new scopes and close
|
// case and default statements always open new scopes and close
|
||||||
// previous case scopes
|
// previous case scopes
|
||||||
bool close = switchStack.length && switchStack[$ - 1].inCase;
|
bool wasInCase = switchStack.length && switchStack[$ - 1].inCase;
|
||||||
bool b = switchStack[$ - 1].inCase;
|
if (switchStack.length)
|
||||||
switchStack[$ - 1].inCase = true;
|
switchStack[$ - 1].inCase = true;
|
||||||
scope (exit)
|
scope (exit)
|
||||||
switchStack[$ - 1].inCase = b;
|
if (switchStack.length)
|
||||||
if (close)
|
switchStack[$ - 1].inCase = wasInCase;
|
||||||
|
if (wasInCase)
|
||||||
{
|
{
|
||||||
popScope();
|
popScope();
|
||||||
pushScope();
|
pushScope();
|
||||||
|
|
@ -897,3 +898,52 @@ unittest
|
||||||
auto isOldScope = void;
|
auto isOldScope = void;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test previous segfault
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
import dparse.lexer : getTokensForParser, LexerConfig, StringCache;
|
||||||
|
import dparse.parser : parseModule;
|
||||||
|
import dparse.rollback_allocator : RollbackAllocator;
|
||||||
|
|
||||||
|
StringCache cache = StringCache(4096);
|
||||||
|
LexerConfig config;
|
||||||
|
RollbackAllocator rba;
|
||||||
|
auto tokens = getTokensForParser(q{
|
||||||
|
module derp;
|
||||||
|
|
||||||
|
void main(string[] args)
|
||||||
|
{
|
||||||
|
foreach
|
||||||
|
switch (x)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (y) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, config, &cache);
|
||||||
|
auto m = parseModule(tokens, "stdin", &rba);
|
||||||
|
|
||||||
|
class TestScopedAnalyzer : ScopedBaseAnalyzer
|
||||||
|
{
|
||||||
|
this()
|
||||||
|
{
|
||||||
|
super(BaseAnalyzerArguments("stdin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected void pushScope()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected void popScope()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new TestScopedAnalyzer().visit(m);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue