Commit 4e96f2ce authored by Tobias Hunger's avatar Tobias Hunger

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's avatarTim Jenssen <tim.jenssen@qt.io>
parent ba8e7d11
......@@ -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);
};
......
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