From 74fd5a560f6ae9ef309aa4a15375e1b9f61d423c Mon Sep 17 00:00:00 2001
From: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Date: Thu, 24 Jun 2010 11:03:52 +0200
Subject: [PATCH] avoid exponential resource consumption

the cumulative mode tries hard to never lose already assigned variable
values. the naive implementation turned assignments into additions,
which made the trivial construct "FOO = $$FOO" double the size of the
array each time it would be executed.
so instead let the assignments be assignments, and then re-add the
values that would be dropped.

Reviewed-by: dt
Task-number: QTCREATORBUG-1595
---
 src/shared/proparser/profileevaluator.cpp | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index f54fd06ea6f..d1c60db5ec5 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -1211,9 +1211,22 @@ void ProFileEvaluator::Private::visitProVariable(ProVariable *var)
                     m_valuemapStack.top()[varName] = varVal;
                     m_filevaluemap[currentProFile()][varName] = varVal;
                 }
-            } else {
-                // We are greedy for values.
-                valuesRef(varName) += varVal;
+            } else if (!varVal.isEmpty()) {
+                // We are greedy for values. But avoid exponential growth.
+                QStringList &v = valuesRef(varName);
+                if (v.isEmpty()) {
+                    v = varVal;
+                } else {
+                    QStringList old = v;
+                    v = varVal;
+                    QSet<QString> has = v.toSet();
+                    v.reserve(v.size() + old.size());
+                    foreach (const QString &s, old)
+                        if (!has.contains(s))
+                            v << s;
+                }
+                // These values will not be used for further processing inside
+                // the evaluator. Duplicate elimination happens later.
                 m_filevaluemap[currentProFile()][varName] += varVal;
             }
             break;
@@ -3346,7 +3359,7 @@ ProFileEvaluator::TemplateType ProFileEvaluator::templateType()
 {
     QStringList templ = values(statics.strTEMPLATE);
     if (templ.count() >= 1) {
-        const QString &t = templ.last();
+        const QString &t = templ.at(0);
         if (!t.compare(QLatin1String("app"), Qt::CaseInsensitive))
             return TT_Application;
         if (!t.compare(QLatin1String("lib"), Qt::CaseInsensitive))
-- 
GitLab