From f67bc0793184a1937aa948f6d6059ad068e50999 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Thu, 18 Sep 2025 22:18:47 +0200 Subject: [PATCH 1/2] Add code to trigger an error when reading garbage data This prevents an infinite loop from happening and consuming all the memory. Tested on GCC 15 and Clang 20 with all the combinations of {Debug,RelWithDebInfo,Release} builds, in 5 out of 6 it triggers one of the errors and with GCC in Debug it crashes from ROOT. --- python/templates/CollectionData.cc.jinja2 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/python/templates/CollectionData.cc.jinja2 b/python/templates/CollectionData.cc.jinja2 index 6561d744a..b83a7429e 100644 --- a/python/templates/CollectionData.cc.jinja2 +++ b/python/templates/CollectionData.cc.jinja2 @@ -38,6 +38,21 @@ if (!isSubsetColl) { m_data.reset(buffers.dataAsVector<{{ class.full_type }}Data>()); + // The following is ugly code for the case when reading garbage data from ROOT + // after calling dataAsVector, which can trigger infinite loops that consume + // all the available memory and this works at least for GCC 15 and Clang 20 in + // {Debug,RelWithDebInfo,Release} modes. + // https://github.com/AIDASoft/podio/pull/817#issuecomment-3266748609 and + // https://github.com/AIDASoft/podio/pull/842 + volatile std::uint64_t s = m_data->size(); + if (s > 1e15) throw std::runtime_error("Bad data after reading: a collection is too big"); + else + if (s == 0) + for (const auto& _ : *m_data.get()) + throw std::runtime_error("Bad data after reading: zero-sized collection with data"); + // end of ugly + + {% for member in VectorMembers %} m_vec_{{ member.name }}.reset(podio::CollectionReadBuffers::asVector<{{ member.full_type }}>(m_vecmem_info[{{ loop.index0 }}].second)); {% endfor %} From 363ea4bb695e8c5151ba1af2753d95c85bbbd8d6 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Thu, 18 Sep 2025 22:28:36 +0200 Subject: [PATCH 2/2] Add a [[maybe_unused]] to silence warnings At least one happening with GCC < 15 --- python/templates/CollectionData.cc.jinja2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/templates/CollectionData.cc.jinja2 b/python/templates/CollectionData.cc.jinja2 index b83a7429e..a84710d16 100644 --- a/python/templates/CollectionData.cc.jinja2 +++ b/python/templates/CollectionData.cc.jinja2 @@ -48,7 +48,7 @@ if (s > 1e15) throw std::runtime_error("Bad data after reading: a collection is too big"); else if (s == 0) - for (const auto& _ : *m_data.get()) + for ([[maybe_unused]] const auto& _ : *m_data.get()) throw std::runtime_error("Bad data after reading: zero-sized collection with data"); // end of ugly