diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index 282c3aff4920d5c58383c829f765ae1300e31830..178919291bf0eb72cc7d72dc539ca8ad047269fa 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -199,6 +199,8 @@ public:
     struct ParseCtx {
         int parens; // Nesting of non-functional parentheses
         int argc; // Number of arguments in current function call
+        int litCount; // Number of literals in current expression
+        int expCount; // Number of expansions in current expression
         Context context;
         ushort quote; // Enclosing quote type
         ushort terminator; // '}' if replace function call is braced, ':' if test function
@@ -266,7 +268,7 @@ public:
     static ProStringList split_value_list(const QString &vals);
     bool isActiveConfig(const QString &config, bool regex = false);
     ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
-    ProStringList expandVariableReferences(const ushort *&tokPtr, bool joined = false);
+    ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false);
     ProStringList evaluateExpandFunction(const ProString &function, const ProString &arguments);
     ProStringList evaluateExpandFunction(const ProString &function, const ushort *&tokPtr);
     ProStringList evaluateExpandFunction(const ProString &function, const ProStringList &args);
@@ -681,6 +683,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
     Context context = CtxTest;
     int parens = 0;
     int argc = 0;
+    int litCount = 0;
+    int expCount = 0;
     bool inError = false;
     bool putSpace = false; // Only ever true inside quoted string
     bool lineMarked = true; // For in-expression markers
@@ -714,6 +718,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
             xprPtr[-1] = tlen; \
             if (setSep) \
                 needSep = TokNewStr; \
+            litCount++; \
         } else { \
             ptr -= 2; \
             if (setSep && ptr != ((context == CtxValue) ? tokPtr : buf)) \
@@ -822,6 +827,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
                                 xprPtr[-2] = TokLiteral | needSep;
                                 xprPtr[-1] = tlen;
                                 needSep = 0;
+                                litCount++;
                             } else {
                                 ptr -= 2;
                             }
@@ -871,6 +877,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
                             tok |= TokQuoted;
                         tok |= needSep;
                         needSep = 0;
+                        expCount++;
                         tlen = ptr - xprPtr;
                         if (rtok == TokVariable) {
                             xprPtr[-4] = tok;
@@ -892,6 +899,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
                                 top.terminator = term;
                                 top.context = context;
                                 top.argc = argc;
+                                top.litCount = litCount;
+                                top.expCount = expCount;
                             }
                             parens = 0;
                             quote = 0;
@@ -962,6 +971,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
                                 term = top.terminator;
                                 context = top.context;
                                 argc = top.argc;
+                                litCount = top.litCount;
+                                expCount = top.expCount;
                                 xprStack.resize(xprStack.size() - 1);
                             }
                             if (term == ':') {
@@ -1070,7 +1081,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
                         putBlock(tokPtr, buf, tlen);
                         putTok(tokPtr, tok);
                         context = CtxValue;
-                        ptr = tokPtr;
+                        ptr = ++tokPtr;
+                        litCount = expCount = 0;
                         needSep = 0;
                         goto nextToken;
                     }
@@ -1109,6 +1121,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
                     return false;
                 }
                 if (context == CtxValue) {
+                    tokPtr[-1] = litCount ? litCount + expCount : 0;
                     tokPtr = ptr;
                     putTok(tokPtr, TokValueTerminator);
                 } else {
@@ -1837,7 +1850,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop(
     int index = 0;
     ProString variable;
     ProStringList oldVarVal;
-    ProString it_list = expandVariableReferences(exprPtr, true).at(0);
+    ProString it_list = expandVariableReferences(exprPtr, 0, true).at(0);
     if (_variable.isEmpty()) {
         if (it_list != statics.strever) {
             logMessage(format("Invalid loop expression."));
@@ -1919,6 +1932,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop(
 void ProFileEvaluator::Private::visitProVariable(
         ushort tok, const ProStringList &curr, const ushort *&tokPtr)
 {
+    int sizeHint = *tokPtr++;
+
     if (curr.size() != 1) {
         skipExpression(tokPtr);
         logMessage(format("Left hand side of assignment must expand to exactly one word."));
@@ -1929,7 +1944,7 @@ void ProFileEvaluator::Private::visitProVariable(
     if (tok == TokReplace) {      // ~=
         // DEFINES ~= s/a/b/?[gqi]
 
-        const ProStringList &varVal = expandVariableReferences(tokPtr, true);
+        const ProStringList &varVal = expandVariableReferences(tokPtr, sizeHint, true);
         const QString &val = varVal.at(0).toQString(m_tmp1);
         if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
             logMessage(format("the ~= operator can handle only the s/// function."));
@@ -1962,7 +1977,7 @@ void ProFileEvaluator::Private::visitProVariable(
             replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global, m_tmp2);
         }
     } else {
-        ProStringList varVal = expandVariableReferences(tokPtr);
+        ProStringList varVal = expandVariableReferences(tokPtr, sizeHint);
         switch (tok) {
         default: // whatever - cannot happen
         case TokAssign:          // =
@@ -2641,9 +2656,10 @@ bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex
 }
 
 ProStringList ProFileEvaluator::Private::expandVariableReferences(
-        const ushort *&tokPtr, bool joined)
+        const ushort *&tokPtr, int sizeHint, bool joined)
 {
     ProStringList ret;
+    ret.reserve(sizeHint);
     forever {
         evaluateExpression(tokPtr, &ret, joined);
         switch (*tokPtr) {
@@ -2761,7 +2777,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction(
         return evaluateFunction(*it, prepareFunctionArgs(tokPtr), 0);
 
     //why don't the builtin functions just use args_list? --Sam
-    return evaluateExpandFunction(func, expandVariableReferences(tokPtr, true));
+    return evaluateExpandFunction(func, expandVariableReferences(tokPtr, 5, true));
 }
 
 ProStringList ProFileEvaluator::Private::evaluateExpandFunction(
@@ -3179,7 +3195,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit
         return evaluateBoolFunction(*it, prepareFunctionArgs(tokPtr), function);
 
     //why don't the builtin functions just use args_list? --Sam
-    return evaluateConditionalFunction(function, expandVariableReferences(tokPtr, true));
+    return evaluateConditionalFunction(function, expandVariableReferences(tokPtr, 5, true));
 }
 
 ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateConditionalFunction(
diff --git a/src/shared/proparser/prowriter.cpp b/src/shared/proparser/prowriter.cpp
index 46ceca51232139ec31c0c98e0d8d84031d6cb6b0..756eff114622fec46d1956ad3ee6ea8724a0662d 100644
--- a/src/shared/proparser/prowriter.cpp
+++ b/src/shared/proparser/prowriter.cpp
@@ -137,6 +137,8 @@ static const ushort *skipToken(ushort tok, const ushort *&tokPtr, int &lineNo)
     case TokAppendUnique:
     case TokRemove:
     case TokReplace:
+        tokPtr++;
+        // fallthrough
     case TokTestCall:
         skipExpression(tokPtr, lineNo);
         break;
@@ -206,7 +208,7 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines,
                 lines->insert(lineNo, added);
                 return;
             }
-            skipExpression(tokPtr, lineNo);
+            skipExpression(++tokPtr, lineNo);
         } else {
             lastXpr = skipToken(tok, tokPtr, lineNo);
         }
@@ -236,7 +238,7 @@ static void findProVariables(const ushort *tokPtr, const QStringList &vars,
         } else if (tok == TokAssign || tok == TokAppend || tok == TokAppendUnique) {
             if (getLiteral(lastXpr, tokPtr - 1, tmp) && vars.contains(tmp))
                 *proVars << lineNo;
-            skipExpression(tokPtr, lineNo);
+            skipExpression(++tokPtr, lineNo);
         } else {
             lastXpr = skipToken(tok, tokPtr, lineNo);
         }