Skip to content

Commit e267a95

Browse files
committed
clang import: reject AST nodes without the ext tokens the handlers read
1 parent 99ad2a8 commit e267a95

2 files changed

Lines changed: 23 additions & 3 deletions

File tree

‎lib/clangimport.cpp‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,10 @@ namespace clangimport {
336336
public:
337337
AstNode(std::string nodeType, const std::string &ext, Data *data)
338338
: nodeType(std::move(nodeType)), mExtTokens(splitString(ext)), mData(data)
339-
{}
339+
{
340+
if (mExtTokens.empty())
341+
throw InternalError(nullptr, "invalid AST node: " + this->nodeType, InternalError::AST);
342+
}
340343
std::string nodeType;
341344
std::vector<AstNodePtr> children;
342345

@@ -1408,7 +1411,10 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList)
14081411
auto *nestedIn = const_cast<Scope *>(nameToken->scope());
14091412

14101413
if (prev) {
1411-
const std::string addr = *(std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev") + 1);
1414+
const auto it = std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev");
1415+
if (it + 1 == mExtTokens.cend())
1416+
throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST);
1417+
const std::string addr = *(it + 1);
14121418
mData->ref(addr, nameToken);
14131419
}
14141420
if (!nameToken->function()) {
@@ -1549,6 +1555,8 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList &tokenList)
15491555

15501556
Token * clangimport::AstNode::createTokensVarDecl(TokenList &tokenList)
15511557
{
1558+
if (mExtTokens.size() < 2)
1559+
throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST);
15521560
const std::string addr = mExtTokens.front();
15531561
if (contains(mExtTokens, "static"))
15541562
addtoken(tokenList, "static");

‎test/testclangimport.cpp‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ class TestClangImport : public TestFixture {
143143
TEST_CASE(crash);
144144
TEST_CASE(crash2);
145145
TEST_CASE(nullNodeInvalidLevel);
146+
TEST_CASE(invalidExtTokens);
146147
}
147148

148149
std::string parse(const char clang[]) {
@@ -1420,7 +1421,7 @@ class TestClangImport : public TestFixture {
14201421
// getSpelling() indexed mExtTokens[typeIndex - 1] without a lower-bound
14211422
// check, so a node whose line carries no ext tokens (typeIndex <= 0) read
14221423
// out of bounds.
1423-
(void)parse("`-RecordDecl "); // don't crash
1424+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-RecordDecl "), AST, "invalid AST node: RecordDecl");
14241425
}
14251426

14261427
void nullNodeInvalidLevel() {
@@ -1429,6 +1430,17 @@ class TestClangImport : public TestFixture {
14291430
"`-<<<NULL>>>\n";
14301431
ASSERT_EQUALS("void foo ( ) ;", parse(clang));
14311432
}
1433+
1434+
void invalidExtTokens() {
1435+
// nodes without the ext tokens the handlers read must not index out of bounds
1436+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 <a.cpp:1:1, col:20> col:5 f 'int ()'\n"
1437+
" `-CompoundStmt 0x2 <col:9, col:20>\n"
1438+
" `-ReturnStmt 0x3 <col:11, col:18>\n"
1439+
" `-IntegerLiteral \n"), AST, "invalid AST node: IntegerLiteral");
1440+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-EnumDecl "), AST, "invalid AST node: EnumDecl");
1441+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1"), AST, "invalid AST node: VarDecl");
1442+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 <a.cpp:1:1, col:20> col:5 f 'int ()' prev"), AST, "invalid AST node: FunctionDecl");
1443+
}
14321444
};
14331445

14341446
REGISTER_TEST(TestClangImport)

0 commit comments

Comments
 (0)