From 5d334de541096850bd885817be4c3c0da121af94 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev@gmail.com>
Date: Tue, 9 Apr 2019 10:01:17 +0300
Subject: [PATCH] [cling] Resize the memory cache before entering the loop.

This prevents the vector to be reallocated if the size exceeds the capacity of
the vector causing invalid pointer accesses.

Fixes ROOT-7749.
---
 .../cling/lib/Interpreter/LookupHelper.cpp    | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/interpreter/cling/lib/Interpreter/LookupHelper.cpp b/interpreter/cling/lib/Interpreter/LookupHelper.cpp
index c550bc9129c..2f27e5d9ac0 100644
--- a/interpreter/cling/lib/Interpreter/LookupHelper.cpp
+++ b/interpreter/cling/lib/Interpreter/LookupHelper.cpp
@@ -1588,22 +1588,18 @@ namespace cling {
       //
       //  Create the array of Expr from the array of Types.
       //
-
-      typedef llvm::SmallVectorImpl<QualType>::const_iterator iterator;
-      for(iterator iter = GivenTypes.begin(), end = GivenTypes.end();
-          iter != end;
-          ++iter) {
-        const clang::QualType QT = iter->getCanonicalType();
+      assert(!ExprMemory.size() && "Size must be 0");
+      ExprMemory.resize(GivenTypes.size() + 1);
+      for(size_t i = 0, e = GivenTypes.size(); i < e; ++i) {
+        const clang::QualType QT = GivenTypes[i].getCanonicalType();
         {
           ExprValueKind VK = VK_RValue;
           if (QT->getAs<LValueReferenceType>()) {
             VK = VK_LValue;
           }
           clang::QualType NonRefQT(QT.getNonReferenceType());
-          unsigned int slot = ExprMemory.size();
-          ExprMemory.resize(slot+1);
-          Expr* val = new (&ExprMemory[slot]) OpaqueValueExpr(SourceLocation(),
-                                                              NonRefQT, VK);
+          Expr* val = new (&ExprMemory[i]) OpaqueValueExpr(SourceLocation(),
+                                                           NonRefQT, VK);
           GivenArgs.push_back(val);
         }
       }
@@ -1656,6 +1652,9 @@ namespace cling {
           if (QT->getAs<LValueReferenceType>()) {
             VK = VK_LValue;
           }
+          // FIXME: This is potentially dangerous because if the capacity exceeds
+          // the reserved capacity of ExprMemory, it will reallocate and cause
+          // memory corruption on the OpaqueValueExpr. See ROOT-7749.
           clang::QualType NonRefQT(QT.getNonReferenceType());
           ExprMemory.resize(++nargs);
           new (&ExprMemory[nargs-1]) OpaqueValueExpr(TSI->getTypeLoc().getLocStart(),
-- 
GitLab