diff --git a/tree/ntuple/src/RMiniFile.cxx b/tree/ntuple/src/RMiniFile.cxx index 1603b7414902d..5191d82f449a0 100644 --- a/tree/ntuple/src/RMiniFile.cxx +++ b/tree/ntuple/src/RMiniFile.cxx @@ -763,25 +763,27 @@ ROOT::RResult ROOT::Internal::RMiniFileReader::GetNTupleProper(st if (key.fObjLen < kMinNTupleSize) { return R__FAIL("invalid anchor size: " + std::to_string(key.fObjLen) + " < " + std::to_string(sizeof(RTFNTuple))); } + // The object length can be smaller than the size of RTFNTuple if it comes from a past RNTuple class version, // or larger than it if it comes from a future RNTuple class version. auto bufAnchor = MakeUninitArray(std::max(key.fObjLen, sizeof(RTFNTuple))); RTFNTuple *ntuple = new (bufAnchor.get()) RTFNTuple; - auto objNbytes = key.GetSize() - key.fKeyLen; - ReadBuffer(ntuple, objNbytes, offset); + const auto objNbytes = key.GetSize() - key.fKeyLen; if (objNbytes != key.fObjLen) { - // Decompress into a temporary buffer - auto unzipBuf = MakeUninitArray(key.fObjLen); - RNTupleDecompressor::Unzip(bufAnchor.get(), objNbytes, key.fObjLen, unzipBuf.get()); - // Then copy back to bufAnchor - memcpy(bufAnchor.get(), unzipBuf.get(), key.fObjLen); + // Read into a temporary buffer + auto unzipBuf = MakeUninitArray(std::max(key.fObjLen, sizeof(RTFNTuple))); + ReadBuffer(unzipBuf.get(), objNbytes, offset); + // Unzip into the final buffer + RNTupleDecompressor::Unzip(unzipBuf.get(), objNbytes, key.fObjLen, ntuple); + } else { + ReadBuffer(ntuple, objNbytes, offset); } // We require that future class versions only append members and store the checksum in the last 8 bytes // Checksum calculation: strip byte count, class version, fChecksum member - auto lenCkData = key.fObjLen - ntuple->GetOffsetCkData() - sizeof(uint64_t); - auto ckCalc = XXH3_64bits(ntuple->GetPtrCkData(), lenCkData); + const auto lenCkData = key.fObjLen - ntuple->GetOffsetCkData() - sizeof(uint64_t); + const auto ckCalc = XXH3_64bits(ntuple->GetPtrCkData(), lenCkData); uint64_t ckOnDisk; RUInt64BE *ckOnDiskPtr = reinterpret_cast(bufAnchor.get() + key.fObjLen - sizeof(uint64_t));