Skip to content

Commit 7d49e01

Browse files
committed
clang import: reject AST nodes without the ext tokens the handlers read
1 parent e100161 commit 7d49e01

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

@@ -1413,7 +1416,10 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList)
14131416
auto *nestedIn = const_cast<Scope *>(nameToken->scope());
14141417

14151418
if (prev) {
1416-
const std::string addr = *(std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev") + 1);
1419+
const auto it = std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev");
1420+
if (it + 1 == mExtTokens.cend())
1421+
throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST);
1422+
const std::string addr = *(it + 1);
14171423
mData->ref(addr, nameToken);
14181424
}
14191425
if (!nameToken->function()) {
@@ -1556,6 +1562,8 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList &tokenList)
15561562

15571563
Token * clangimport::AstNode::createTokensVarDecl(TokenList &tokenList)
15581564
{
1565+
if (mExtTokens.size() < 2)
1566+
throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST);
15591567
const std::string addr = mExtTokens.front();
15601568
if (contains(mExtTokens, "static"))
15611569
addtoken(tokenList, "static");

‎test/testclangimport.cpp‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class TestClangImport : public TestFixture {
144144
TEST_CASE(crash2);
145145
TEST_CASE(crash3);
146146
TEST_CASE(nullNodeInvalidLevel);
147+
TEST_CASE(invalidExtTokens);
147148
}
148149

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

14271428
void nullNodeInvalidLevel() {
@@ -1442,6 +1443,17 @@ class TestClangImport : public TestFixture {
14421443
" `-CXXRecordDecl 0x2\n"); // don't crash
14431444
(void)parse("`-CXXRecordDecl 0x1"); // don't crash
14441445
}
1446+
1447+
void invalidExtTokens() {
1448+
// nodes without the ext tokens the handlers read must not index out of bounds
1449+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 <a.cpp:1:1, col:20> col:5 f 'int ()'\n"
1450+
" `-CompoundStmt 0x2 <col:9, col:20>\n"
1451+
" `-ReturnStmt 0x3 <col:11, col:18>\n"
1452+
" `-IntegerLiteral \n"), AST, "invalid AST node: IntegerLiteral");
1453+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-EnumDecl "), AST, "invalid AST node: EnumDecl");
1454+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1"), AST, "invalid AST node: VarDecl");
1455+
ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 <a.cpp:1:1, col:20> col:5 f 'int ()' prev"), AST, "invalid AST node: FunctionDecl");
1456+
}
14451457
};
14461458

14471459
REGISTER_TEST(TestClangImport)

0 commit comments

Comments
 (0)