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 <loaden@gmail.com>
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com>
This commit is contained in:
Erik Verbruggen
2012-04-22 12:04:00 +02:00
committed by Erik Verbruggen
parent 3f4a9548be
commit bd47622183
3 changed files with 21 additions and 10 deletions

View File

@@ -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 &macroId)
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);
}