From 41fbbba8c4b50fb42f394a2f6035ada5bcc1db43 Mon Sep 17 00:00:00 2001 From: vro Date: Tue, 16 May 2017 10:48:29 +0300 Subject: [PATCH] 0028736: An error to read a binary OCAF document of > 2Gb A binary file of OCAF document contains file-position of several sections (header section, shape section). This file-position represents an integer value. For document files of less than 2Gb it is enough to use "int" type to keep the file-position. But for greater document files we need more digits. The fix consists in extension of the type for keeping of file-position within the document file on disk: it was "int", now it is "uint64_t". --- src/BinLDrivers/BinLDrivers.cxx | 2 +- .../BinLDrivers_DocumentSection.cxx | 71 ++++++++++++------- .../BinLDrivers_DocumentSection.hxx | 12 ++-- src/FSD/FSD_BinaryFile.cxx | 15 ++-- src/FSD/FSD_BinaryFile.hxx | 2 + 5 files changed, 65 insertions(+), 37 deletions(-) diff --git a/src/BinLDrivers/BinLDrivers.cxx b/src/BinLDrivers/BinLDrivers.cxx index 7c689c8c50..17c0893a43 100644 --- a/src/BinLDrivers/BinLDrivers.cxx +++ b/src/BinLDrivers/BinLDrivers.cxx @@ -33,7 +33,7 @@ //#include static Standard_GUID BinLStorageDriver ("13a56835-8269-11d5-aab2-0050044b1af1"); static Standard_GUID BinLRetrievalDriver("13a56836-8269-11d5-aab2-0050044b1af1"); -#define CURRENT_DOCUMENT_VERSION 9 +#define CURRENT_DOCUMENT_VERSION 10 //======================================================================= //function : Factory diff --git a/src/BinLDrivers/BinLDrivers_DocumentSection.cxx b/src/BinLDrivers/BinLDrivers_DocumentSection.cxx index 1fab06a2a9..1032888a6a 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentSection.cxx +++ b/src/BinLDrivers/BinLDrivers_DocumentSection.cxx @@ -15,6 +15,7 @@ #include #include +#include //======================================================================= //function : BinLDrivers_DocumentSection @@ -58,7 +59,7 @@ const TCollection_AsciiString& BinLDrivers_DocumentSection::Name () const //purpose : //======================================================================= -Standard_Size BinLDrivers_DocumentSection::Offset () const +uint64_t BinLDrivers_DocumentSection::Offset () const { return myValue[0]; } @@ -68,7 +69,7 @@ Standard_Size BinLDrivers_DocumentSection::Offset () const //purpose : //======================================================================= -void BinLDrivers_DocumentSection::SetOffset (const Standard_Size theOffset) +void BinLDrivers_DocumentSection::SetOffset (const uint64_t theOffset) { myValue[0] = theOffset; } @@ -88,7 +89,7 @@ Standard_Boolean BinLDrivers_DocumentSection::IsPostRead () const //purpose : //======================================================================= -Standard_Size BinLDrivers_DocumentSection::Length () const +uint64_t BinLDrivers_DocumentSection::Length () const { return myValue[1]; } @@ -98,7 +99,7 @@ Standard_Size BinLDrivers_DocumentSection::Length () const //purpose : //======================================================================= -void BinLDrivers_DocumentSection::SetLength (const Standard_Size theLength) +void BinLDrivers_DocumentSection::SetLength (const uint64_t theLength) { myValue[1] = theLength; } @@ -131,14 +132,14 @@ void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream) // Write the buffer: size + string #if DO_INVERSE - aBufSz[0] = InverseSize ((Standard_Integer)aBufSize); + aBufSz[0] = InverseInt ((Standard_Integer)aBufSize); #else aBufSz[0] = (Standard_Integer)aBufSize; #endif theStream.write (&aBuf[0], aBufSize + sizeof(Standard_Integer)); // Store the address of Offset word in the file - myValue[0] = (Standard_Size) theStream.tellp(); + myValue[0] = (uint64_t) theStream.tellp(); myValue[1] = 0; // Write the placeholders of Offset and Length of the section that should @@ -146,7 +147,7 @@ void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream) aBufSz[0] = 0; aBufSz[1] = 0; aBufSz[2] = 0; - theStream.write (&aBuf[0], 3*sizeof(Standard_Integer)); + theStream.write (&aBuf[0], 3*sizeof(uint64_t)); } } @@ -156,24 +157,24 @@ void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream) //======================================================================= void BinLDrivers_DocumentSection::Write (Standard_OStream& theStream, - const Standard_Size theOffset) + const uint64_t theOffset) { - const Standard_Size aSectionEnd = (Standard_Size) theStream.tellp(); + const uint64_t aSectionEnd = (uint64_t) theStream.tellp(); theStream.seekp(myValue[0]); myValue[0] = theOffset; myValue[1] = aSectionEnd - theOffset; - Standard_Integer aVal[3] = { - Standard_Integer(myValue[0]), - Standard_Integer(myValue[1]), - Standard_Integer(myIsPostRead ? 1 : 0) + uint64_t aVal[3] = { + myValue[0], + myValue[1], + uint64_t(myIsPostRead ? 1 : 0) }; #if DO_INVERSE - aVal[0] = InverseSize(aVal[0]); - aVal[1] = InverseSize(aVal[1]); - aVal[2] = InverseSize(aVal[2]); + aVal[0] = InverseUint64(aVal[0]); + aVal[1] = InverseUint64(aVal[1]); + aVal[2] = InverseUint64(aVal[2]); #endif - theStream.write((char *)&aVal[0], 3*sizeof(Standard_Integer)); + theStream.write((char *)&aVal[0], 3*sizeof(uint64_t)); theStream.seekp(aSectionEnd); } @@ -195,15 +196,35 @@ void BinLDrivers_DocumentSection::ReadTOC if (aNameBufferSize > 0) { theStream.read ((char *)&aBuf[0], (Standard_Size)aNameBufferSize); theSection.myName = (Standard_CString)&aBuf[0]; - Standard_Integer aValue[3]; - theStream.read ((char *)&aValue[0], 3*sizeof(Standard_Integer)); + + uint64_t aValue[3]; + if (BinMDataStd::DocumentVersion() <= 9) + { + // Old documents stored file position as 4-bytes values. + Standard_Integer aValInt[3]; + theStream.read ((char *)&aValInt[0], 3*sizeof(Standard_Integer)); #if DO_INVERSE - aValue[0] = InverseSize (aValue[0]); - aValue[1] = InverseSize (aValue[1]); - aValue[2] = InverseSize (aValue[2]); + aValue[0] = InverseInt (aValInt[0]); + aValue[1] = InverseInt (aValInt[1]); + aValue[2] = InverseInt (aValInt[2]); +#else + aValue[0] = aValInt[0]; + aValue[1] = aValInt[1]; + aValue[2] = aValInt[2]; #endif - theSection.myValue[0] = (Standard_Size)aValue[0]; - theSection.myValue[1] = (Standard_Size)aValue[1]; - theSection.myIsPostRead = aValue[2] != 0; + } + else + { + theStream.read ((char *)&aValue[0], 3*sizeof(uint64_t)); +#if DO_INVERSE + aValue[0] = InverseUint64 (aValue[0]); + aValue[1] = InverseUint64 (aValue[1]); + aValue[2] = InverseUint64 (aValue[2]); +#endif + } + + theSection.myValue[0] = aValue[0]; + theSection.myValue[1] = aValue[1]; + theSection.myIsPostRead = (aValue[2] != 0); } } diff --git a/src/BinLDrivers/BinLDrivers_DocumentSection.hxx b/src/BinLDrivers/BinLDrivers_DocumentSection.hxx index bafc9df25a..0fd63f2b5d 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentSection.hxx +++ b/src/BinLDrivers/BinLDrivers_DocumentSection.hxx @@ -52,23 +52,23 @@ public: Standard_EXPORT Standard_Boolean IsPostRead() const; //! Query the offset of the section in the persistent file - Standard_EXPORT Standard_Size Offset() const; + Standard_EXPORT uint64_t Offset() const; //! Set the offset of the section in the persistent file - Standard_EXPORT void SetOffset (const Standard_Size theOffset); + Standard_EXPORT void SetOffset (const uint64_t theOffset); //! Query the length of the section in the persistent file - Standard_EXPORT Standard_Size Length() const; + Standard_EXPORT uint64_t Length() const; //! Set the length of the section in the persistent file - Standard_EXPORT void SetLength (const Standard_Size theLength); + Standard_EXPORT void SetLength (const uint64_t theLength); //! Create a Section entry in the Document TOC (list of sections) Standard_EXPORT void WriteTOC (Standard_OStream& theOS); //! Save Offset and Length data into the Section entry //! in the Document TOC (list of sections) - Standard_EXPORT void Write (Standard_OStream& theOS, const Standard_Size theOffset); + Standard_EXPORT void Write (Standard_OStream& theOS, const uint64_t theOffset); //! Fill a DocumentSection instance from the data that are read //! from TOC. @@ -88,7 +88,7 @@ private: TCollection_AsciiString myName; - Standard_Size myValue[2]; + uint64_t myValue[2]; Standard_Boolean myIsPostRead; diff --git a/src/FSD/FSD_BinaryFile.cxx b/src/FSD/FSD_BinaryFile.cxx index a978db71ef..8cc23444cf 100644 --- a/src/FSD/FSD_BinaryFile.cxx +++ b/src/FSD/FSD_BinaryFile.cxx @@ -1860,20 +1860,20 @@ Standard_ShortReal FSD_BinaryFile::InverseShortReal (const Standard_ShortReal th //======================================================================= template -inline Standard_Size OCCT_InverseSizeSpecialized (const Standard_Size theValue, int); +inline uint64_t OCCT_InverseSizeSpecialized (const uint64_t theValue, int); template<> -inline Standard_Size OCCT_InverseSizeSpecialized <4> (const Standard_Size theValue, int) +inline uint64_t OCCT_InverseSizeSpecialized <4> (const uint64_t theValue, int) { return FSD_BinaryFile::InverseInt(static_cast(theValue)); } template<> -inline Standard_Size OCCT_InverseSizeSpecialized <8> (const Standard_Size theValue, int) +inline uint64_t OCCT_InverseSizeSpecialized <8> (const uint64_t theValue, int) { union { Standard_Integer i[2]; - Standard_Size aValue; + uint64_t aValue; } aWrapUnion; aWrapUnion.aValue = theValue; @@ -1887,5 +1887,10 @@ inline Standard_Size OCCT_InverseSizeSpecialized <8> (const Standard_Size theVal Standard_Size FSD_BinaryFile::InverseSize (const Standard_Size theValue) { - return OCCT_InverseSizeSpecialized (theValue, 0); + return (Standard_Size) OCCT_InverseSizeSpecialized (theValue, 0); +} + +uint64_t FSD_BinaryFile::InverseUint64 (const uint64_t theValue) +{ + return OCCT_InverseSizeSpecialized (theValue, 0); } diff --git a/src/FSD/FSD_BinaryFile.hxx b/src/FSD/FSD_BinaryFile.hxx index 3060a1d87a..09921b8b30 100644 --- a/src/FSD/FSD_BinaryFile.hxx +++ b/src/FSD/FSD_BinaryFile.hxx @@ -335,6 +335,8 @@ Storage_BaseDriver& operator >> (Standard_ShortReal& aValue) ///Inverse bytes in size value Standard_EXPORT static Standard_Size InverseSize(const Standard_Size theValue); + ///Inverse bytes in 64bit unsigned int value + Standard_EXPORT static uint64_t InverseUint64(const uint64_t theValue); Standard_EXPORT static void ReadHeader (Standard_IStream& theIStream, FSD_FileHeader& theFileHeader); -- 2.20.1