From e1b1232c3ac5a833fea224a2c87feeab10a88ff5 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:39:44 +0200 Subject: [PATCH 1/2] DPL: add guard for unsafe cursor --- Framework/Core/include/Framework/AnalysisHelpers.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Framework/Core/include/Framework/AnalysisHelpers.h b/Framework/Core/include/Framework/AnalysisHelpers.h index b723ee1d51f5d..c7d567c9eb810 100644 --- a/Framework/Core/include/Framework/AnalysisHelpers.h +++ b/Framework/Core/include/Framework/AnalysisHelpers.h @@ -514,6 +514,14 @@ struct WritingCursor { requires(sizeof...(Ts) == framework::pack_size(typename persistent_table_t::persistent_columns_t{})) { ++mCount; + if (mReserved >= 0 && mCount >= mReserved) [[unlikely]] { + // reserve() switched this cursor to UnsafeAppend, which does not grow its + // buffers. Writing row mCount (>= the reserved count) would overrun them and + // silently corrupt the heap, so fail here, naming the offending table and + // row, rather than crashing later somewhere unrelated. + LOG(fatal) << "Table '" << outputSpec.binding.value << "': writing row " << mCount + << " exceeds reserve(" << mReserved << ")."; + } cursor(0, extract(args)...); } From 056e9c13c5dbbd7bf7659957a63e303c9e740459 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:12:27 +0200 Subject: [PATCH 2/2] AOD Writer: correct reserve for cpvClusters --- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index b7e212cd97edc..73b852d550ffe 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -2585,7 +2585,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) // fill cpvcluster table if (mInputSources[GIndex::CPV]) { float posX, posZ; - cpvClustersCursor.reserve(cpvTrigRecs.size()); + cpvClustersCursor.reserve(cpvClusters.size()); for (auto& cpvEvent : cpvTrigRecs) { uint64_t bc = cpvEvent.getBCData().toLong(); auto item = bcsMap.find(bc);