summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2017-06-07 16:50:04 +0200
committerTobias Hunger <tobias.hunger@qt.io>2017-06-20 12:53:38 +0000
commit4e96f2ce22e1a01b08b196e9b940034d50b87460 (patch)
tree96affc46818e609fdcaf2243e259a533c540f0fe
parentba8e7d11562f7d2c811fd3a211fc7c429cddf3c3 (diff)
downloadqt-creator-4e96f2ce22e1a01b08b196e9b940034d50b87460.tar.gz
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>
-rw-r--r--src/libs/utils/macroexpander.cpp17
-rw-r--r--src/libs/utils/stringutils.cpp4
-rw-r--r--src/libs/utils/stringutils.h2
3 files changed, 16 insertions, 7 deletions
diff --git a/src/libs/utils/macroexpander.cpp b/src/libs/utils/macroexpander.cpp
index 6aa965a942..755f2e0a89 100644
--- a/src/libs/utils/macroexpander.cpp
+++ b/src/libs/utils/macroexpander.cpp
@@ -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);
}
/*!
diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp
index 85813004de..04df87fb5f 100644
--- a/src/libs/utils/stringutils.cpp
+++ b/src/libs/utils/stringutils.cpp
@@ -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);
diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h
index 8e0c78f028..20f6063710 100644
--- a/src/libs/utils/stringutils.h
+++ b/src/libs/utils/stringutils.h
@@ -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);
};