From d86ac9e3ed8992538a160500c55ee640e8f9cf26 Mon Sep 17 00:00:00 2001 From: Alexander Mai Date: Tue, 2 Jun 2015 22:26:17 +0200 Subject: [PATCH] #6747 segmentation fault (invalid code) in Token::isAttributeConstructor --- lib/tokenize.cpp | 16 ++++++++++++++-- test/testgarbage.cpp | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d7b99a1ba..7323ce346 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9162,9 +9162,17 @@ void Tokenizer::simplifyAttribute() while (Token::Match(tok, "__attribute__|__attribute (") && tok->next()->link() && tok->next()->link()->next()) { if (Token::Match(tok->tokAt(2), "( constructor|__constructor__")) { // prototype for constructor is: void func(void); - if (tok->next()->link()->next()->str() == "void") // __attribute__((constructor)) void func() {} + if (!tok->next()->link()->next()) { + syntaxError(tok); + return; + } + if (tok->next()->link()->next()->str() == "void") { // __attribute__((constructor)) void func() {} + if (!tok->next()->link()->next()->next()) { + syntaxError(tok); + return; + } tok->next()->link()->next()->next()->isAttributeConstructor(true); - else if (tok->next()->link()->next()->str() == ";" && tok->linkAt(-1) && tok->previous()->link()->previous()) // void func() __attribute__((constructor)); + } else if (tok->next()->link()->next()->str() == ";" && tok->linkAt(-1) && tok->previous()->link()->previous()) // void func() __attribute__((constructor)); tok->previous()->link()->previous()->isAttributeConstructor(true); else // void __attribute__((constructor)) func() {} tok->next()->link()->next()->isAttributeConstructor(true); @@ -9172,6 +9180,10 @@ void Tokenizer::simplifyAttribute() else if (Token::Match(tok->tokAt(2), "( destructor|__destructor__")) { // prototype for destructor is: void func(void); + if (!tok->next()->link()->next()) { + syntaxError(tok); + return; + } if (tok->next()->link()->next()->str() == "void") // __attribute__((destructor)) void func() {} tok->next()->link()->next()->next()->isAttributeDestructor(true); else if (tok->next()->link()->next()->str() == ";" && tok->linkAt(-1) && tok->previous()->link()->previous()) // void func() __attribute__((destructor)); diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 36ce17af3..a46d1a7cf 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -108,6 +108,7 @@ private: TEST_CASE(garbageCode67); TEST_CASE(garbageCode68); TEST_CASE(garbageCode69); + TEST_CASE(garbageCode70); TEST_CASE(garbageValueFlow); TEST_CASE(garbageSymbolDatabase); @@ -605,6 +606,10 @@ private: ASSERT_THROW(checkCode("{ (make_mess, aux); } typedef void F(void); aux(void (*x)()) { } (void (*y)()) { } F*"), InternalError); } + void garbageCode70() { // #6747 + ASSERT_THROW(checkCode("{ } __attribute__((constructor)) void"), InternalError); + } + void garbageValueFlow() { // #6089 const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"