Commit bd476221 authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Erik Verbruggen
Browse files

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: default avatarYuchen Deng <loaden@gmail.com>
Reviewed-by: default avatarThomas Hartmann <Thomas.Hartmann@nokia.com>
parent 3f4a9548
......@@ -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()); }
......
......@@ -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);
}
......
......@@ -11,7 +11,7 @@ op_ADD, op_SUB,
static const char *names[] = {
#gen true
# 2 "data/identifier-expansion.3.cpp"
"ADD"
"ADD"
,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment