#6731 Tokenizer::eraseDeadCode causes heap corruption on invalid code. Better detection of invalid code inside Tokenizer::simplifyFlowControl()

This commit is contained in:
Alexander Mai 2016-01-01 23:32:10 +01:00
parent ca4f55ec4c
commit 37c3d5da7b
2 changed files with 15 additions and 6 deletions

View File

@ -4260,6 +4260,8 @@ void Tokenizer::simplifyFlowControl()
(Token::Match(tok->previous(), "[;{}] %name% (") &&
_settings->library.isnoreturn(tok)) ||
(isCPP() && tok->str() == "throw")) {
if (tok->next() == "}")
syntaxError(tok->next()); // invalid code like in #6731
//TODO: ensure that we exclude user-defined 'exit|abort|throw', except for 'noreturn'
//catch the first ';'
for (Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
@ -4270,7 +4272,7 @@ void Tokenizer::simplifyFlowControl()
eraseDeadCode(tok, 0);
break;
} else if (Token::Match(tok2, "[{}]"))
break; //Wrong code.
break;
}
//if everything is removed, then remove also the code after an inferior scope
//only if the actual scope is not special

View File

@ -217,6 +217,7 @@ private:
TEST_CASE(garbageCode166); // #7236
TEST_CASE(garbageCode167); // #7237
TEST_CASE(garbageCode168); // #7246
TEST_CASE(garbageCode169); // #6731
TEST_CASE(garbageValueFlow);
TEST_CASE(garbageSymbolDatabase);
TEST_CASE(garbageAST);
@ -965,11 +966,11 @@ private:
}
void garbageCode123() {
checkCode("namespace pr16989 {\n"
" class C {\n"
" C tpl_mem(T *) { return }\n"
" };\n"
"}");
ASSERT_THROW(checkCode("namespace pr16989 {\n"
" class C {\n"
" C tpl_mem(T *) { return }\n"
" };\n"
"}"), InternalError);
}
void garbageCode124() {
@ -1429,6 +1430,12 @@ private:
checkCode("long foo(void) { return *bar; }", false);
}
void garbageCode169() {
// 6713
ASSERT_THROW(checkCode("( ) { ( ) ; { return } switch ( ) i\n"
"set case break ; default: ( ) }", false), InternalError);
}
};
REGISTER_TEST(TestGarbage)