From b25a81d54e47288fb0354327082fc4127fe11332 Mon Sep 17 00:00:00 2001
From: Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de>
Date: Mon, 10 Jul 2023 14:43:23 +0000
Subject: [PATCH] algo::Unpack: Add protection against invalid equipment ids
 and system versions during parallel unpacking.

---
 algo/unpack/Unpack.cxx | 33 +++++++++++++++++++++++++--------
 algo/unpack/Unpack.h   | 22 +++++++++++++++++++---
 2 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/algo/unpack/Unpack.cxx b/algo/unpack/Unpack.cxx
index f3d4a6f5d3..f9cf7e11a8 100644
--- a/algo/unpack/Unpack.cxx
+++ b/algo/unpack/Unpack.cxx
@@ -28,19 +28,19 @@ namespace cbm::algo
     UnpackMonitorData& monitor = result.second;
 
     if (DetectorEnabled(Subsystem::STS)) {
-      ParallelMsLoop(Subsystem::STS, digiTs.fData.fSts.fDigis, monitor.fSts, *timeslice, fAlgoSts, 0x20);
+      ParallelMsLoop(Subsystem::STS, monitor, digiTs.fData.fSts.fDigis, monitor.fSts, *timeslice, fAlgoSts, 0x20);
     }
 
     if (DetectorEnabled(Subsystem::TOF)) {
-      ParallelMsLoop(Subsystem::TOF, digiTs.fData.fTof.fDigis, monitor.fTof, *timeslice, fAlgoTof, 0x00);
+      ParallelMsLoop(Subsystem::TOF, monitor, digiTs.fData.fTof.fDigis, monitor.fTof, *timeslice, fAlgoTof, 0x00);
     }
 
     if (DetectorEnabled(Subsystem::BMON)) {
-      ParallelMsLoop(Subsystem::BMON, digiTs.fData.fT0.fDigis, monitor.fBmon, *timeslice, fAlgoBmon, 0x00);
+      ParallelMsLoop(Subsystem::BMON, monitor, digiTs.fData.fT0.fDigis, monitor.fBmon, *timeslice, fAlgoBmon, 0x00);
     }
 
     if (DetectorEnabled(Subsystem::MUCH)) {
-      ParallelMsLoop(Subsystem::MUCH, digiTs.fData.fMuch.fDigis, monitor.fMuch, *timeslice, fAlgoMuch, 0x20);
+      ParallelMsLoop(Subsystem::MUCH, monitor, digiTs.fData.fMuch.fDigis, monitor.fMuch, *timeslice, fAlgoMuch, 0x20);
     }
 
     // ---  Component loop
@@ -104,17 +104,31 @@ namespace cbm::algo
 
   // ----------------------------------------------------------------------------
   std::pair<size_t, size_t> Unpack::ParallelInit(const fles::Timeslice& ts, Subsystem subsystem,
-                                                 std::vector<u16>& msEqIds,
+                                                 gsl::span<const uint16_t> legalEqIds, uint8_t sys_ver,
+                                                 UnpackMonitorData& monitor, std::vector<u16>& msEqIds,
                                                  std::vector<fles::MicrosliceDescriptor>& msDesc,
                                                  std::vector<const u8*>& msContent)
   {
     size_t numMs     = 0;
     size_t sizeBytes = 0;
+
     for (uint64_t comp = 0; comp < ts.num_components(); comp++) {
       auto this_subsystem = static_cast<Subsystem>(ts.descriptor(comp, 0).sys_id);
+
       if (this_subsystem == subsystem) {
         const u64 numMsInComp = ts.num_microslices(comp);
         const u16 componentId = ts.descriptor(comp, 0).eq_id;
+
+        if (ts.descriptor(comp, 0).sys_ver != sys_ver) {
+          monitor.fNumErrInvalidSysVer++;
+          continue;
+        }
+
+        if (std::find(legalEqIds.begin(), legalEqIds.end(), componentId) == legalEqIds.end()) {
+          monitor.fNumErrInvalidEqId++;
+          continue;
+        }
+
         sizeBytes += ts.size_component(comp);
         numMs += numMsInComp;
         for (u64 mslice = 0; mslice < numMsInComp; mslice++) {
@@ -133,15 +147,18 @@ namespace cbm::algo
 
   // ----------------------------------------------------------------------------
   template<class Digi, class UnpackAlgo, class Monitor>
-  void Unpack::ParallelMsLoop(const Subsystem subsystem, std::vector<Digi>& digisOut, std::vector<Monitor>& monitorOut,
-                              const fles::Timeslice& ts, const std::map<u16, UnpackAlgo>& algos, u8 sys_ver)
+  void Unpack::ParallelMsLoop(const Subsystem subsystem, UnpackMonitorData& genericMonitor, std::vector<Digi>& digisOut,
+                              std::vector<Monitor>& monitorOut, const fles::Timeslice& ts,
+                              const std::map<u16, UnpackAlgo>& algos, u8 sys_ver)
   {
     xpu::scoped_timer t_(fles::to_string(subsystem));
 
     std::vector<u16> msEqIds;                        // equipment ids of microslices
     std::vector<fles::MicrosliceDescriptor> msDesc;  // microslice descriptors
     std::vector<const u8*> msContent;                // pointer to microslice content
-    auto [numMs, sizeBytes] = ParallelInit(ts, subsystem, msEqIds, msDesc, msContent);
+    auto legalEqIds = GetEqIds(algos);
+    auto [numMs, sizeBytes] =
+      ParallelInit(ts, subsystem, gsl::make_span(legalEqIds), sys_ver, genericMonitor, msEqIds, msDesc, msContent);
     std::vector<std::vector<Digi>> msDigis(numMs);  // unpacked digis per microslice
     std::vector<Monitor> monitor(numMs);            // unpacking monitoring data per microslice
 
diff --git a/algo/unpack/Unpack.h b/algo/unpack/Unpack.h
index 2709977fd5..6804b37a6e 100644
--- a/algo/unpack/Unpack.h
+++ b/algo/unpack/Unpack.h
@@ -15,6 +15,7 @@
 #include "trd2d/Trd2dReadoutConfig.h"
 #include "trd2d/UnpackTrd2d.h"
 
+#include <gsl/span>
 #include <optional>
 #include <sstream>
 #include <vector>
@@ -140,10 +141,13 @@ namespace cbm::algo
 
     /** @brief Parallel microslice loop **/
     template<class Digi, class UnpackAlgo, class Monitor>
-    void ParallelMsLoop(const Subsystem subsystem, std::vector<Digi>& digisOut, std::vector<Monitor>& monitor,
-                        const fles::Timeslice& ts, const std::map<u16, UnpackAlgo>& algos, u8 sys_ver);
+    void ParallelMsLoop(const Subsystem subsystem, UnpackMonitorData& monitor, std::vector<Digi>& digisOut,
+                        std::vector<Monitor>& monitorOut, const fles::Timeslice& ts,
+                        const std::map<u16, UnpackAlgo>& algos, u8 sys_ver);
 
-    std::pair<size_t, size_t> ParallelInit(const fles::Timeslice& ts, Subsystem subsystem, std::vector<u16>& eqIds,
+    std::pair<size_t, size_t> ParallelInit(const fles::Timeslice& ts, Subsystem subsystem,
+                                           gsl::span<const uint16_t> legalEqIds, uint8_t sys_ver,
+                                           UnpackMonitorData& monitor, std::vector<u16>& eqIds,
                                            std::vector<fles::MicrosliceDescriptor>& msDesc,
                                            std::vector<const u8*>& msContent);
 
@@ -181,6 +185,18 @@ namespace cbm::algo
     std::map<Subsystem, int32_t> fSystemTimeOffset = {
       {Subsystem::STS, -970}, {Subsystem::MUCH, -980}, {Subsystem::RICH, 100},  {Subsystem::TOF, 40},
       {Subsystem::BMON, 0},   {Subsystem::TRD, 1300},  {Subsystem::TRD2D, -510}};
+
+  private:  // methods
+    template<typename UnpackAlgo>
+    std::vector<uint16_t> GetEqIds(const std::map<uint16_t, UnpackAlgo>& algoMap)
+    {
+      std::vector<uint16_t> eqIds;
+      eqIds.reserve(algoMap.size());
+      for (const auto& [eqId, algo] : algoMap) {
+        eqIds.push_back(eqId);
+      }
+      return eqIds;
+    }
   };
 }  // namespace cbm::algo
 
-- 
GitLab