moc: Fix crash parsing invalid macro invocation

When invoking a macro with less argument than it expect, we would
crash trying to access the vector of arguments from the invocation
as we are trying to substitute an argument.

(Note that we do not show an error in case of argument mismatch
because ithat might happen parsing valid code as moc's c++ parser
is not 100% accurate (that was QTBUG-29331))

Task-number: QTBUG-46210
Change-Id: I3f08d7f5049e593a5bdc02a594ea63cadf66e7a4
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>
This commit is contained in:
Olivier Goffart 2015-05-29 12:39:24 +02:00 committed by Olivier Goffart (Woboq GmbH)
parent 5b739a5b8c
commit 71c85c554a
2 changed files with 12 additions and 3 deletions

View File

@ -661,8 +661,10 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym
expansion += s;
}
} else if (mode == Hash) {
if (index < 0)
if (index < 0 || index >= arguments.size()) {
that->error("'#' is not followed by a macro parameter");
continue;
}
const Symbols &arg = arguments.at(index);
QByteArray stringified;
@ -681,7 +683,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym
expansion.pop_back();
Symbol next = s;
if (index >= 0) {
if (index >= 0 && index < arguments.size()) {
const Symbols &arg = arguments.at(index);
if (arg.size() == 0) {
mode = Normal;
@ -703,7 +705,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym
expansion += next;
}
if (index >= 0) {
if (index >= 0 && index < arguments.size()) {
const Symbols &arg = arguments.at(index);
for (int i = 1; i < arg.size(); ++i)
expansion += arg.at(i);

View File

@ -1882,6 +1882,13 @@ void tst_Moc::warnings_data()
<< 1
<< QString()
<< QString("standard input:5: Error: Class declaration lacks Q_OBJECT macro.");
QTest::newRow("QTBUG-46210: crash on invalid macro")
<< QByteArray("#define Foo(a, b, c) a b c #a #b #c a##b##c #d\n Foo(45);")
<< QStringList()
<< 1
<< QString("IGNORE_ALL_STDOUT")
<< QString(":2: Error: '#' is not followed by a macro parameter");
}
void tst_Moc::warnings()