CPlusPlus: Check maximum include depth in lexer

We use a value of 200, which is also GCC's default.

Fixes: QTCREATORBUG-28770
Change-Id: Id02b324cd2ffa81a709441a5d93856bcd06501c3
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2023-02-07 14:32:25 +01:00
parent 06b579a75b
commit bd2ca236e1
4 changed files with 15 additions and 1 deletions

View File

@@ -57,6 +57,7 @@ using namespace Utils;
namespace { namespace {
enum { enum {
MAX_FUNCTION_LIKE_ARGUMENTS_COUNT = 100, MAX_FUNCTION_LIKE_ARGUMENTS_COUNT = 100,
MAX_INCLUDE_DEPTH = 200,
MAX_TOKEN_EXPANSION_COUNT = 5000, MAX_TOKEN_EXPANSION_COUNT = 5000,
MAX_TOKEN_BUFFER_DEPTH = 16000 // for when macros are using some kind of right-folding, this is the list of "delayed" buffers waiting to be expanded after the current one. MAX_TOKEN_BUFFER_DEPTH = 16000 // for when macros are using some kind of right-folding, this is the list of "delayed" buffers waiting to be expanded after the current one.
}; };
@@ -1677,6 +1678,15 @@ void Preprocessor::handleIncludeDirective(PPToken *tk, bool includeNext)
if (m_cancelChecker && m_cancelChecker()) if (m_cancelChecker && m_cancelChecker())
return; return;
GuardLocker depthLocker(m_includeDepthGuard);
if (m_includeDepthGuard.lockCount() > MAX_INCLUDE_DEPTH) {
// FIXME: Categorized logging!
#ifndef NO_DEBUG
std::cerr << "Maximum include depth exceeded" << m_state.m_currentFileName << std::endl;
#endif
return;
}
m_state.m_lexer->setScanAngleStringLiteralTokens(true); m_state.m_lexer->setScanAngleStringLiteralTokens(true);
lex(tk); // consume "include" token lex(tk); // consume "include" token
m_state.m_lexer->setScanAngleStringLiteralTokens(false); m_state.m_lexer->setScanAngleStringLiteralTokens(false);

View File

@@ -29,6 +29,8 @@
#include <cplusplus/Lexer.h> #include <cplusplus/Lexer.h>
#include <cplusplus/Token.h> #include <cplusplus/Token.h>
#include <utils/guard.h>
#include <QVector> #include <QVector>
#include <QBitArray> #include <QBitArray>
#include <QByteArray> #include <QByteArray>
@@ -241,6 +243,7 @@ private:
Environment *m_env; Environment *m_env;
QByteArray m_scratchBuffer; QByteArray m_scratchBuffer;
CancelChecker m_cancelChecker; CancelChecker m_cancelChecker;
Utils::Guard m_includeDepthGuard;
bool m_expandFunctionlikeMacros; bool m_expandFunctionlikeMacros;
bool m_keepComments; bool m_keepComments;

View File

@@ -16,6 +16,7 @@ public:
Guard(); Guard();
~Guard(); ~Guard();
bool isLocked() const; bool isLocked() const;
int lockCount() const { return m_lockCount; }
// Prefer using GuardLocker when possible. These two methods are provided only for cases // Prefer using GuardLocker when possible. These two methods are provided only for cases
// when locking and unlocking are done in separate methods, so that GuardLocker can't be // when locking and unlocking are done in separate methods, so that GuardLocker can't be

View File

@@ -1,4 +1,4 @@
add_qtc_test(tst_cplusplus_translationunit add_qtc_test(tst_cplusplus_translationunit
DEPENDS CppEditor DEPENDS CppEditor Utils
SOURCES tst_translationunit.cpp SOURCES tst_translationunit.cpp
) )