diff options
author | Mikhail Voytenko <mav@openoffice.org> | 2012-07-27 17:30:37 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2012-07-27 17:50:22 +0200 |
commit | 10dc090b31776f21a09e32dd409348e2ddb00cc5 (patch) | |
tree | fb4337041dd3d259b404ae3590a3757406e8931a /sot/source/sdstor/stgelem.cxx | |
parent | c75e2ed27d5da71891ed7a148ff9603c58eaa58e (diff) |
sot: prevent some null pointer crashes
Diffstat (limited to 'sot/source/sdstor/stgelem.cxx')
-rw-r--r-- | sot/source/sdstor/stgelem.cxx | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/sot/source/sdstor/stgelem.cxx b/sot/source/sdstor/stgelem.cxx index efdaec2b853f..39fd406f4cf3 100644 --- a/sot/source/sdstor/stgelem.cxx +++ b/sot/source/sdstor/stgelem.cxx @@ -70,21 +70,44 @@ SvStream& operator <<( SvStream& r, const ClsId& rId ) ///////////////////////////// class StgHeader //////////////////////////// StgHeader::StgHeader() +: nVersion( 0 ) +, nByteOrder( 0 ) +, nPageSize( 0 ) +, nDataPageSize( 0 ) +, bDirty( 0 ) +, nFATSize( 0 ) +, nTOCstrm( 0 ) +, nReserved( 0 ) +, nThreshold( 0 ) +, nDataFAT( 0 ) +, nDataFATSize( 0 ) +, nMasterChain( 0 ) +, nMaster( 0 ) { - memset( this, 0, sizeof( StgHeader ) ); + memset( cSignature, 0, sizeof( cSignature ) ); + memset( &aClsId, 0, sizeof( ClsId ) ); + memset( cReserved, 0, sizeof( cReserved ) ); + memset( nMasterFAT, 0, sizeof( nMasterFAT ) ); } void StgHeader::Init() { - memset( this, 0, sizeof( StgHeader ) ); memcpy( cSignature, cStgSignature, 8 ); + memset( &aClsId, 0, sizeof( ClsId ) ); nVersion = 0x0003003B; nByteOrder = 0xFFFE; nPageSize = 9; // 512 bytes nDataPageSize = 6; // 64 bytes + bDirty = 0; + memset( cReserved, 0, sizeof( cReserved ) ); + nFATSize = 0; + nTOCstrm = 0; + nReserved = 0; nThreshold = 4096; + nDataFAT = 0; nDataFATSize = 0; nMasterChain = STG_EOF; + SetTOCStart( STG_EOF ); SetDataFATStart( STG_EOF ); for( short i = 0; i < 109; i++ ) @@ -93,9 +116,15 @@ void StgHeader::Init() sal_Bool StgHeader::Load( StgIo& rIo ) { - SvStream& r = *rIo.GetStrm(); - Load( r ); - return rIo.Good(); + sal_Bool bResult = sal_False; + if ( rIo.GetStrm() ) + { + SvStream& r = *rIo.GetStrm(); + bResult = Load( r ); + bResult = ( bResult && rIo.Good() ); + } + + return bResult; } sal_Bool StgHeader::Load( SvStream& r ) @@ -118,7 +147,8 @@ sal_Bool StgHeader::Load( SvStream& r ) >> nMaster; // 48 # of additional master blocks for( short i = 0; i < 109; i++ ) r >> nMasterFAT[ i ]; - return r.GetErrorCode() == ERRCODE_NONE; + + return ( r.GetErrorCode() == ERRCODE_NONE && Check() ); } sal_Bool StgHeader::Store( StgIo& rIo ) @@ -157,8 +187,15 @@ sal_Bool StgHeader::Check() { return sal_Bool( memcmp( cSignature, cStgSignature, 8 ) == 0 && (short) ( nVersion >> 16 ) == 3 ) + && nPageSize == 9 && lcl_wontoverflow(nPageSize) - && lcl_wontoverflow(nDataPageSize); + && lcl_wontoverflow(nDataPageSize) + && nFATSize > 0 + && nTOCstrm >= 0 + && nThreshold > 0 + && ( nDataFAT == -2 || ( nDataFAT >= 0 && nDataFATSize > 0 ) ) + && ( nMasterChain == -2 || ( nMasterChain >=0 && nMaster > 109 ) ) + && nMaster >= 0; } sal_Int32 StgHeader::GetFATPage( short n ) const @@ -213,7 +250,21 @@ void StgHeader::SetMasters( sal_Int32 n ) sal_Bool StgEntry::Init() { - memset( this, 0, sizeof (StgEntry) - sizeof( String ) ); + memset( nName, 0, sizeof( nName ) ); + nNameLen = 0; + cType = 0; + cFlags = 0; + nLeft = 0; + nRight = 0; + nChild = 0; + memset( &aClsId, 0, sizeof( aClsId ) ); + nFlags = 0; + nMtime[0] = 0; nMtime[1] = 0; + nAtime[0] = 0; nAtime[1] = 0; + nPage1 = 0; + nSize = 0; + nUnknown = 0; + SetLeaf( STG_LEFT, STG_FREE ); SetLeaf( STG_RIGHT, STG_FREE ); SetLeaf( STG_CHILD, STG_FREE ); @@ -306,9 +357,12 @@ short StgEntry::Compare( const StgEntry& r ) const // These load/store operations are a bit more complicated, // since they have to copy their contents into a packed structure. -sal_Bool StgEntry::Load( const void* pFrom ) +sal_Bool StgEntry::Load( const void* pFrom, sal_uInt32 nBufSize ) { - SvMemoryStream r( (sal_Char*) pFrom, 128, STREAM_READ ); + if ( nBufSize < 128 ) + return sal_False; + + SvMemoryStream r( (sal_Char*) pFrom, nBufSize, STREAM_READ ); for( short i = 0; i < 32; i++ ) r >> nName[ i ]; // 00 name as WCHAR r >> nNameLen // 40 size of name in bytes including 00H @@ -334,7 +388,7 @@ sal_Bool StgEntry::Load( const void* pFrom ) if (n > nMaxLegalStr) return sal_False; - if (nSize < 0 && cType != STG_STORAGE) + if ((nSize < 0 && cType != STG_STORAGE) || (nPage1 < 0 && nPage1 != -2)) { // the size makes no sense for the substorage // TODO/LATER: actually the size should be an unsigned value, but in this case it would mean a stream of more than 2Gb |