From 8471ce28456d23d4e873bd29cfdc7883dc9db663 Mon Sep 17 00:00:00 2001
From: Enrico Guiraud <enrico.guiraud@cern.ch>
Date: Fri, 29 Sep 2017 16:40:17 +0200
Subject: [PATCH] [TDF] Fix out-of-bound access in `FillHelper::PartialUpdate`

---
 tree/treeplayer/inc/ROOT/TDFActionHelpers.hxx | 7 ++-----
 tree/treeplayer/src/TDFActionHelpers.cxx      | 2 +-
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/tree/treeplayer/inc/ROOT/TDFActionHelpers.hxx b/tree/treeplayer/inc/ROOT/TDFActionHelpers.hxx
index d6d89d92ef0..b4664feb121 100644
--- a/tree/treeplayer/inc/ROOT/TDFActionHelpers.hxx
+++ b/tree/treeplayer/inc/ROOT/TDFActionHelpers.hxx
@@ -83,10 +83,10 @@ class FillHelper {
    std::vector<Buf_t> fBuffers;
    std::vector<Buf_t> fWBuffers;
    const std::shared_ptr<Hist_t> fResultHist;
-   /// Histograms containing "snapshots" of partial results. Non-null only if a registered callback requires it.
-   std::vector<std::unique_ptr<Hist_t>> fPartialHists;
    unsigned int fNSlots;
    unsigned int fBufSize;
+   /// Histograms containing "snapshots" of partial results. Non-null only if a registered callback requires it.
+   std::vector<std::unique_ptr<Hist_t>> fPartialHists;
    Buf_t fMin;
    Buf_t fMax;
 
@@ -245,9 +245,6 @@ public:
    }
    void Finalize() { fTo->Merge(); }
 
-   // Must be implemented to activate callbacks for Histo1D<T> actions.
-   // Currently no-op, meaning we leave the result object as it is:
-   // the result object is already being filled because FillTOHelper keeps it in its working slot 0
    HIST *PartialUpdate(unsigned int slot) { return fTo->GetAtSlotRaw(slot); }
 };
 
diff --git a/tree/treeplayer/src/TDFActionHelpers.cxx b/tree/treeplayer/src/TDFActionHelpers.cxx
index 6f2344b342d..b742244f226 100644
--- a/tree/treeplayer/src/TDFActionHelpers.cxx
+++ b/tree/treeplayer/src/TDFActionHelpers.cxx
@@ -46,7 +46,7 @@ void FillHelper::UpdateMinMax(unsigned int slot, double v)
 }
 
 FillHelper::FillHelper(const std::shared_ptr<Hist_t> &h, const unsigned int nSlots)
-   : fResultHist(h), fNSlots(nSlots), fBufSize(fgTotalBufSize / nSlots),
+   : fResultHist(h), fNSlots(nSlots), fBufSize(fgTotalBufSize / nSlots), fPartialHists(fNSlots),
      fMin(nSlots, std::numeric_limits<BufEl_t>::max()), fMax(nSlots, std::numeric_limits<BufEl_t>::lowest())
 {
    fBuffers.reserve(fNSlots);
-- 
GitLab