Skip to content

Commit 34a593b

Browse files
committed
fix attempted OOB access with broken swtich/case syntax
1 parent 4d7e4f5 commit 34a593b

File tree

1 file changed

+56
-6
lines changed

1 file changed

+56
-6
lines changed

src/dscanner/analysis/base.d

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module dscanner.analysis.base;
22

33
import dparse.ast;
4-
import dparse.lexer : IdType, str, Token, tok;
4+
import dparse.lexer : IdType, str, tok, Token;
55
import dscanner.analysis.nolint;
66
import dsymbol.scope_ : Scope;
77
import std.array;
@@ -639,12 +639,13 @@ public:
639639
{
640640
// case and default statements always open new scopes and close
641641
// previous case scopes
642-
bool close = switchStack.length && switchStack[$ - 1].inCase;
643-
bool b = switchStack[$ - 1].inCase;
644-
switchStack[$ - 1].inCase = true;
642+
bool wasInCase = switchStack.length && switchStack[$ - 1].inCase;
643+
if (switchStack.length)
644+
switchStack[$ - 1].inCase = true;
645645
scope (exit)
646-
switchStack[$ - 1].inCase = b;
647-
if (close)
646+
if (switchStack.length)
647+
switchStack[$ - 1].inCase = wasInCase;
648+
if (wasInCase)
648649
{
649650
popScope();
650651
pushScope();
@@ -897,3 +898,52 @@ unittest
897898
auto isOldScope = void;
898899
});
899900
}
901+
902+
// test previous segfault
903+
unittest
904+
{
905+
import dparse.lexer : getTokensForParser, LexerConfig, StringCache;
906+
import dparse.parser : parseModule;
907+
import dparse.rollback_allocator : RollbackAllocator;
908+
909+
StringCache cache = StringCache(4096);
910+
LexerConfig config;
911+
RollbackAllocator rba;
912+
auto tokens = getTokensForParser(q{
913+
module derp;
914+
915+
void main(string[] args)
916+
{
917+
foreach
918+
switch (x)
919+
{
920+
case 1:
921+
if (y) {
922+
continue;
923+
}
924+
break;
925+
default:
926+
break;
927+
}
928+
}
929+
}, config, &cache);
930+
auto m = parseModule(tokens, "stdin", &rba);
931+
932+
class TestScopedAnalyzer : ScopedBaseAnalyzer
933+
{
934+
this()
935+
{
936+
super(BaseAnalyzerArguments("stdin"));
937+
}
938+
939+
override protected void pushScope()
940+
{
941+
}
942+
943+
override protected void popScope()
944+
{
945+
}
946+
}
947+
948+
new TestScopedAnalyzer().visit(m);
949+
}

0 commit comments

Comments
 (0)