Skip to content

Commit 3eca2c9

Browse files
committed
ALICE3: add protections in reading clusters
1 parent 6fdfc6b commit 3eca2c9

1 file changed

Lines changed: 28 additions & 18 deletions

File tree

  • Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/include/ALICE3GlobalReconstruction

Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/include/ALICE3GlobalReconstruction/TimeFrameMixin.h

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -351,49 +351,59 @@ int TimeFrameMixin<nLayers, Base>::loadROFrameData(const std::array<gsl::span<co
351351
this->mClusterSize[iLayer].reserve(layerClusters[iLayer].size());
352352
}
353353

354+
std::array<std::vector<size_t>, nLayers> patternOffsetsPerLayer;
354355
for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
355-
const uint8_t* pattPtr = layerPatterns[iLayer].data();
356-
const uint8_t* pattEnd = pattPtr + layerPatterns[iLayer].size();
356+
auto& offsets = patternOffsetsPerLayer[iLayer];
357+
offsets.resize(layerClusters[iLayer].size(), std::numeric_limits<size_t>::max());
358+
size_t pattPos = 0;
359+
bool validPatterns = true;
360+
for (size_t clusterId{0}; clusterId < layerClusters[iLayer].size(); ++clusterId) {
361+
if (pattPos + 2 > layerPatterns[iLayer].size()) {
362+
validPatterns = false;
363+
break;
364+
}
365+
offsets[clusterId] = pattPos;
366+
const uint8_t rowSpan = layerPatterns[iLayer][pattPos];
367+
const uint8_t colSpan = layerPatterns[iLayer][pattPos + 1];
368+
const size_t nBytes = (size_t(rowSpan) * colSpan + 7) / 8;
369+
if (pattPos + 2 + nBytes > layerPatterns[iLayer].size()) {
370+
validPatterns = false;
371+
break;
372+
}
373+
pattPos += 2 + nBytes;
374+
}
375+
if (!validPatterns || pattPos != layerPatterns[iLayer].size()) {
376+
LOGP(fatal, "Malformed TRK pattern stream for layer {}: {} bytes for {} clusters",
377+
iLayer, layerPatterns[iLayer].size(), layerClusters[iLayer].size());
378+
}
379+
}
357380

381+
for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
358382
for (size_t iRof{0}; iRof < layerROFs[iLayer].size(); ++iRof) {
359383
const auto& rof = layerROFs[iLayer][iRof];
360384
const int first = rof.getFirstEntry();
361385
const int last = first + rof.getNEntries();
362386

363387
for (int clusterId{first}; clusterId < last; ++clusterId) {
364-
if (pattPtr + 2 > pattEnd) {
365-
LOGP(error, "Pattern stream exhausted while decoding layer {} cluster {}", iLayer, clusterId);
366-
break;
367-
}
368-
const uint8_t* pattForCluster = pattPtr;
369-
const int nBytes = (pattForCluster[0] * pattForCluster[1] + 7) / 8;
370-
if (pattPtr + 2 + nBytes > pattEnd) {
371-
LOGP(error, "Pattern stream truncated for layer {} cluster {}", iLayer, clusterId);
372-
break;
373-
}
374-
const int pattAdvance = 2 + nBytes;
375-
376388
if (clusterId < 0 || clusterId >= static_cast<int>(layerClusters[iLayer].size())) {
377389
LOGP(warning, "Skipping out-of-range TRK cluster {} on layer {}", clusterId, iLayer);
378-
pattPtr += pattAdvance;
379390
continue;
380391
}
381392

382393
const auto& c = layerClusters[iLayer][clusterId];
383394
if (c.subDetID < 0 || c.subDetID > 1 || c.disk != -1) {
384-
pattPtr += pattAdvance;
385395
continue;
386396
}
387397

388398
const int clusterLayer = startLayer[c.subDetID] + c.layer;
389399
if (clusterLayer != iLayer) {
390400
LOGP(error, "Skipping cluster from layer {} found in TRK layer stream {}", clusterLayer, iLayer);
391-
pattPtr += pattAdvance;
392401
continue;
393402
}
394403

404+
const auto pattOffset = patternOffsetsPerLayer[iLayer][clusterId];
405+
const uint8_t* pattForCluster = layerPatterns[iLayer].data() + pattOffset;
395406
auto locXYZ = Clusterer::getClusterLocalCoordinates(c, pattForCluster, yPlaneMLOT);
396-
pattPtr += pattAdvance;
397407

398408
const auto gloXYZ = geom->getMatrixL2G(c.chipID) * locXYZ;
399409

0 commit comments

Comments
 (0)