Skip to content

Commit 3deb36d

Browse files
authored
Fix #14901: fuzzing timeout (hang) in Tokenizer::simplifyTypedef() (#8717)
1 parent a1beb84 commit 3deb36d

3 files changed

Lines changed: 27 additions & 2 deletions

File tree

lib/tokenize.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,12 +589,27 @@ namespace {
589589
}
590590
}
591591

592+
const auto checkForRecursion = [this]() {
593+
if (Token::Match(mTypedefToken, "typedef %name% %name% ;"))
594+
return;
595+
for (const Token *tok = mTypedefToken; tok != mEndToken; tok = tok->next()) {
596+
if (tok == mNameToken)
597+
continue;
598+
if (tok->str() != mNameToken->str())
599+
continue;
600+
if (Token::Match(tok->previous(), "struct|class|enum|union"))
601+
continue;
602+
throw InternalError(tok, "recursive typedef encountered");
603+
}
604+
};
605+
592606
for (Token* type = start; Token::Match(type, "%name%|*|&|&&"); type = type->next()) {
593607
if (type != start && Token::Match(type, "%name% ;") && !type->isStandardType()) {
594608
mRangeType.first = start;
595609
mRangeType.second = type;
596610
mNameToken = type;
597611
mEndToken = mNameToken->next();
612+
checkForRecursion();
598613
return;
599614
}
600615
if (type != start && Token::Match(type, "%name% [")) {
@@ -609,6 +624,7 @@ namespace {
609624
mEndToken = end->next();
610625
mRangeAfterVar.first = mNameToken->next();
611626
mRangeAfterVar.second = mEndToken;
627+
checkForRecursion();
612628
return;
613629
}
614630
if (Token::Match(type->next(), "( * const| %name% ) (") && Token::simpleMatch(type->linkAt(1)->linkAt(1), ") ;")) {
@@ -618,6 +634,7 @@ namespace {
618634
mRangeType.second = mNameToken;
619635
mRangeAfterVar.first = mNameToken->next();
620636
mRangeAfterVar.second = mEndToken;
637+
checkForRecursion();
621638
return;
622639
}
623640
if (type != start && Token::Match(type, "%name% ( !!(") && Token::simpleMatch(type->linkAt(1), ") ;") && !type->isStandardType()) {
@@ -627,6 +644,7 @@ namespace {
627644
mRangeType.second = type;
628645
mRangeAfterVar.first = mNameToken->next();
629646
mRangeAfterVar.second = mEndToken;
647+
checkForRecursion();
630648
return;
631649
}
632650
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
typedef const v*v,*;

test/testsimplifytypedef.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class TestSimplifyTypedef : public TestFixture {
233233
TEST_CASE(simplifyTypedef160);
234234
TEST_CASE(simplifyTypedef161);
235235
TEST_CASE(simplifyTypedef162);
236+
TEST_CASE(simplifyTypedef163);
236237

237238
TEST_CASE(simplifyTypedefFunction1);
238239
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@@ -3836,11 +3837,11 @@ class TestSimplifyTypedef : public TestFixture {
38363837
"}";
38373838
ASSERT_EQUALS(exp, tok(code));
38383839

3839-
const char code2[] = "typedef stuct T* T;\n" // #14669
3840+
const char code2[] = "typedef struct T* T;\n" // #14669
38403841
"struct T {\n"
38413842
" T p;\n"
38423843
"};\n";
3843-
const char exp2[] = "struct T { stuct T * p ; } ;";
3844+
const char exp2[] = "struct T { struct T * p ; } ;";
38443845
ASSERT_EQUALS(exp2, simplifyTypedefC(code2));
38453846
}
38463847

@@ -3868,6 +3869,11 @@ class TestSimplifyTypedef : public TestFixture {
38683869
ASSERT_EQUALS(exp, tok(code));
38693870
}
38703871

3872+
void simplifyTypedef163() {
3873+
const char code[] = "typedef v *v;";
3874+
ASSERT_THROW_INTERNAL(tok(code), INTERNAL);
3875+
}
3876+
38713877
void simplifyTypedefFunction1() {
38723878
{
38733879
const char code[] = "typedef void (*my_func)();\n"

0 commit comments

Comments
 (0)