From 336f18dff11da35ca253d09424d5c617b9d5c9b8 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Thu, 8 May 2025 11:10:57 +0200 Subject: [PATCH] [io] read versioned class from file even if in-memory-class is unversioned Fixes https://its.cern.ch/jira/browse/ROOT-5306 [io] add test for unversioned reading --- io/io/src/TBufferFile.cxx | 5 +-- .../io/evolution/versions/execROOT5306.cxx | 34 ++++++++++++++++++ .../io/evolution/versions/execROOT5306.ref | 3 ++ .../root/io/evolution/versions/mysub.root | Bin 0 -> 724 bytes 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 roottest/root/io/evolution/versions/execROOT5306.cxx create mode 100644 roottest/root/io/evolution/versions/execROOT5306.ref create mode 100644 roottest/root/io/evolution/versions/mysub.root diff --git a/io/io/src/TBufferFile.cxx b/io/io/src/TBufferFile.cxx index 82c0a9d9c0ed5..e6ac648781ec0 100644 --- a/io/io/src/TBufferFile.cxx +++ b/io/io/src/TBufferFile.cxx @@ -3617,9 +3617,10 @@ Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, const TClass // (tracking) was not enabled. So let's create the StreamerInfo if it is the // one for the current version, otherwise let's complain ... // We could also get here when reading a file prior to the introduction of StreamerInfo. - // We could also get here if there old class version was '1' and the new class version is higher than 1 + // We could also get here if the old class version was '1' and the new class version is higher than 1 + // We could also get here if the stored-in-file class version was '3' and the current-in-memory class version is not defined // AND the checksum is the same. - if (v2file || version == cl->GetClassVersion() || version == 1 ) { + if (v2file || version == cl->GetClassVersion() || version == 1 || (version > 0 && cl->GetClassVersion() == -1) ) { R__LOCKGUARD(gInterpreterMutex); // We need to check if another thread did not get here first diff --git a/roottest/root/io/evolution/versions/execROOT5306.cxx b/roottest/root/io/evolution/versions/execROOT5306.cxx new file mode 100644 index 0000000000000..68a4ead157ebf --- /dev/null +++ b/roottest/root/io/evolution/versions/execROOT5306.cxx @@ -0,0 +1,34 @@ +#include "TInterpreter.h" +#include "TFile.h" + +#ifndef SUBCLASS_HH +#define SUBCLASS_HH +class MySubClass +{ +public: + int id; +}; +#endif +#ifdef __ROOTCLING__ +#pragma link C++ class MySubClass+; +#endif + +// https://its.cern.ch/jira/browse/ROOT-5306 +int execROOT5306() +{ + // Original file was generated as: + // .L MySubClass.cxx+ + // TFile f("/tmp/mysub.root", "RECREATE"); + // MySubClass msc; + // msc.id = 33; + // f.WriteObjectAny(&msc, "MySubClass", "msc"); + // f.Close(); + // with MySubClass.cxx containing: class MySubClass { public: int id; ClassDef(MySubClass, 3) }; + TFile f("mysub.root", "READ"); + auto msc = f.Get("msc"); + if (msc->id != 33) { + printf("Error: id is %d vs 33\n", msc->id); + return 3; + } + return 0; +} diff --git a/roottest/root/io/evolution/versions/execROOT5306.ref b/roottest/root/io/evolution/versions/execROOT5306.ref new file mode 100644 index 0000000000000..e13c4aee6c80b --- /dev/null +++ b/roottest/root/io/evolution/versions/execROOT5306.ref @@ -0,0 +1,3 @@ + +Processing execROOT5306.cxx+... +(int) 0 diff --git a/roottest/root/io/evolution/versions/mysub.root b/roottest/root/io/evolution/versions/mysub.root new file mode 100644 index 0000000000000000000000000000000000000000..460813e36c436be96f0a46c4c7bf92f62c8f0349 GIT binary patch literal 724 zcma)4JxIe)5dM<14n^^25Jv@F6j}sb6eQLn2o?*?E=e0P+B79e(JW3*&Mpq_B94wC zf}1$jUBq3xx#@SWAQdb2;4Uxk-FM%;`(79XG4SyOpbF?M`We^Dbd8=*F}Pfh)2E@` z4_%e!+N1C1mw|S1cl*ZEzU&B6sF;*)b}_FilMP5)>t4+r&c%Ks=ON)bn7{xGo=mCBO2@AXV+uw_ zfNI*>^rCpM9EYy$yWvKCCm1UPO{bPj*1Y<@TjeK;S?L*R#Y9lYG!uCEq*>iyA-zV1 zaf0bGaxwv3tzqV|eav0M1Wpuw%h_8ELpu@dAsgf1akR5&G71cG@^v0Wz~$7s?