forked from qt-creator/qt-creator
MacroExpander: Prevent loop with subproviders
Prevent a loop where a subprovider of a macroexpander creates the macroexpander itself. Change-Id: Id2f3e29651aeb22c818091d8c785a6ea01545463 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -53,16 +53,22 @@ public:
|
||||
: m_accumulating(false), m_aborted(false), m_lockDepth(0)
|
||||
{}
|
||||
|
||||
bool resolveMacro(const QString &name, QString *ret)
|
||||
bool resolveMacro(const QString &name, QString *ret, QSet<AbstractMacroExpander *> &seen)
|
||||
{
|
||||
// Prevent loops:
|
||||
const int count = seen.count();
|
||||
seen.insert(this);
|
||||
if (seen.count() == count)
|
||||
return false;
|
||||
|
||||
bool found;
|
||||
*ret = value(name.toUtf8(), &found);
|
||||
if (found)
|
||||
return true;
|
||||
|
||||
found = Utils::anyOf(m_subProviders, [name, ret] (const MacroExpanderProvider &p) -> bool {
|
||||
found = Utils::anyOf(m_subProviders, [name, ret, &seen] (const MacroExpanderProvider &p) -> bool {
|
||||
MacroExpander *expander = p ? p() : 0;
|
||||
return expander && expander->resolveMacro(name, ret);
|
||||
return expander && expander->d->resolveMacro(name, ret, seen);
|
||||
});
|
||||
|
||||
if (found)
|
||||
@@ -75,7 +81,7 @@ public:
|
||||
if (found)
|
||||
return true;
|
||||
|
||||
return this == globalMacroExpander()->d ? false : globalMacroExpander()->d->resolveMacro(name, ret);
|
||||
return this == globalMacroExpander()->d ? false : globalMacroExpander()->d->resolveMacro(name, ret, seen);
|
||||
}
|
||||
|
||||
QString value(const QByteArray &variable, bool *found)
|
||||
@@ -243,7 +249,8 @@ MacroExpander::~MacroExpander()
|
||||
*/
|
||||
bool MacroExpander::resolveMacro(const QString &name, QString *ret) const
|
||||
{
|
||||
return d->resolveMacro(name, ret);
|
||||
QSet<AbstractMacroExpander*> seen;
|
||||
return d->resolveMacro(name, ret, seen);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <QDir>
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
@@ -153,7 +154,8 @@ bool AbstractMacroExpander::expandNestedMacros(const QString &str, int *pos, QSt
|
||||
*pos = i;
|
||||
return true;
|
||||
}
|
||||
if (resolveMacro(varName, ret)) {
|
||||
QSet<AbstractMacroExpander*> seen;
|
||||
if (resolveMacro(varName, ret, seen)) {
|
||||
*pos = i;
|
||||
if (!pattern.isEmpty() && currArg == &replace) {
|
||||
const QRegularExpression regexp(pattern);
|
||||
|
@@ -65,7 +65,7 @@ public:
|
||||
//! \param name The name of the expando
|
||||
//! \param ret Replacement string on output
|
||||
//! \return True if the expando was found
|
||||
virtual bool resolveMacro(const QString &name, QString *ret) = 0;
|
||||
virtual bool resolveMacro(const QString &name, QString *ret, QSet<AbstractMacroExpander *> &seen) = 0;
|
||||
private:
|
||||
bool expandNestedMacros(const QString &str, int *pos, QString *ret);
|
||||
};
|
||||
|
Reference in New Issue
Block a user