From bd4762218373276b2f38e52d486db339c5428309 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Sun, 22 Apr 2012 12:04:00 +0200 Subject: [PATCH] Fix out-of-memory crash when indenting generated tokens. Generated tokens do not have a position in any source file, so not try to indent them. Previously, the 'source' used was the scratch buffer, which would not contain newlines, so the indent depth would be the length of the scratch buffer at that point. Task-number: QTCREATORBUG-7262 Change-Id: If94213d6dffd13dd2b47c7038ec2398ad925d904 Reviewed-by: Yuchen Deng Reviewed-by: Thomas Hartmann --- src/libs/cplusplus/PPToken.h | 7 ++++-- src/libs/cplusplus/pp-engine.cpp | 22 +++++++++++++------ .../data/identifier-expansion.3.out.cpp | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/libs/cplusplus/PPToken.h b/src/libs/cplusplus/PPToken.h index 3fbb3ad482b..eb59fc847be 100644 --- a/src/libs/cplusplus/PPToken.h +++ b/src/libs/cplusplus/PPToken.h @@ -96,8 +96,11 @@ public: const QByteArray &source() const { return m_src; } - const char *start() const - { return m_src.constData() + offset; } + const char *bufferStart() const + { return m_src.constData(); } + + const char *tokenStart() const + { return bufferStart() + offset; } ByteArrayRef asByteArrayRef() const { return ByteArrayRef(&m_src, offset, length()); } diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index b65f52fdfd4..02e09230b2f 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -852,7 +852,7 @@ bool Preprocessor::handleFunctionLikeMacro(PPToken *tk, const Macro *macro, QVec lineno = t.lineno; else if (t.whitespace()) newText.append(' '); - newText.append(t.start(), t.length()); + newText.append(t.tokenStart(), t.length()); } newText.replace("\\", "\\\\"); newText.replace("\"", "\\\""); @@ -973,8 +973,8 @@ _Lrestart: } else if (tk.isValid() && !prevTk.isValid() && tk.lineno == m_env->currentLine) { out(QByteArray(prevTk.length() + (tk.whitespace() ? 1 : 0), ' ')); } else if (prevTk.generated() != tk.generated() || !prevTk.isValid()) { - const char *begin = tk.source().constBegin(); - const char *end = begin + tk.offset; + const char *begin = tk.bufferStart(); + const char *end = tk.tokenStart(); const char *it = end - 1; for (; it >= begin; --it) if (*it == '\n') @@ -983,8 +983,8 @@ _Lrestart: for (; it < end; ++it) out(' '); } else { - const char *begin = tk.source().constBegin(); - const char *end = begin + tk.offset; + const char *begin = tk.bufferStart(); + const char *end = tk.tokenStart(); const char *it = end - 1; for (; it >= begin; --it) if (!pp_isspace(*it) || *it == '\n') @@ -1502,6 +1502,14 @@ bool Preprocessor::isQtReservedWord(const ByteArrayRef ¯oId) PPToken Preprocessor::generateToken(enum Kind kind, const char *content, int len, unsigned lineno, bool addQuotes) { + // When reconstructing the column position of a token, + // Preprocessor::preprocess will search for the last preceeding newline. + // When the token is a generated token, the column position cannot be + // reconstructed, but we also have to prevent it from searching the whole + // scratch buffer. So inserting a newline before the new token will give + // an indent width of 0 (zero). + m_scratchBuffer.append('\n'); + const size_t pos = m_scratchBuffer.size(); if (kind == T_STRING_LITERAL && addQuotes) @@ -1533,8 +1541,8 @@ PPToken Preprocessor::generateConcatenated(const PPToken &leftTk, const PPToken { QByteArray newText; newText.reserve(leftTk.length() + rightTk.length()); - newText.append(leftTk.start(), leftTk.length()); - newText.append(rightTk.start(), rightTk.length()); + newText.append(leftTk.tokenStart(), leftTk.length()); + newText.append(rightTk.tokenStart(), rightTk.length()); return generateToken(T_IDENTIFIER, newText.constData(), newText.size(), leftTk.lineno, true); } diff --git a/tests/auto/cplusplus/preprocessor/data/identifier-expansion.3.out.cpp b/tests/auto/cplusplus/preprocessor/data/identifier-expansion.3.out.cpp index 14724d9ccbf..689220f32e6 100644 --- a/tests/auto/cplusplus/preprocessor/data/identifier-expansion.3.out.cpp +++ b/tests/auto/cplusplus/preprocessor/data/identifier-expansion.3.out.cpp @@ -11,7 +11,7 @@ op_ADD, op_SUB, static const char *names[] = { #gen true # 2 "data/identifier-expansion.3.cpp" - "ADD" +"ADD" ,