From d5345bfb40d6e33087fd053cc220308a2bc2945e Mon Sep 17 00:00:00 2001 From: Mikhail Voytenko Date: Thu, 2 Aug 2012 12:04:04 +0200 Subject: sot: prevent some null pointer crashes Signed-off-by: Petr Mladek --- sot/source/sdstor/stg.cxx | 117 ++++++++++++++++++++++++++--------------- sot/source/sdstor/stgavl.cxx | 79 ++++++++++++++++++---------- sot/source/sdstor/stgcache.cxx | 59 ++++++++++++++------- sot/source/sdstor/stgcache.hxx | 2 +- sot/source/sdstor/stgdir.cxx | 58 ++++++++++++++++---- sot/source/sdstor/stgdir.hxx | 2 +- sot/source/sdstor/stgelem.cxx | 76 ++++++++++++++++++++++---- sot/source/sdstor/stgelem.hxx | 3 +- sot/source/sdstor/stgio.cxx | 31 ++++++++--- sot/source/sdstor/stgole.cxx | 35 ++++++------ sot/source/sdstor/stgstrms.cxx | 91 ++++++++++++++++++++++---------- sot/source/sdstor/stgstrms.hxx | 4 +- sot/source/sdstor/storinfo.cxx | 7 +-- 13 files changed, 396 insertions(+), 168 deletions(-) (limited to 'sot/source') diff --git a/sot/source/sdstor/stg.cxx b/sot/source/sdstor/stg.cxx index 1f8b5bd66bce..6ac988babad4 100644 --- a/sot/source/sdstor/stg.cxx +++ b/sot/source/sdstor/stg.cxx @@ -100,7 +100,8 @@ const SvStream* OLEStorageBase::GetSvStream_Impl() const OLEStorageBase::OLEStorageBase( StgIo* p, StgDirEntry* pe, StreamMode& nMode ) : nStreamMode( nMode ), pIo( p ), pEntry( pe ) { - p->IncRef(); + if ( p ) + p->IncRef(); if( pe ) pe->nRefCnt++; } @@ -117,21 +118,28 @@ OLEStorageBase::~OLEStorageBase() else pEntry->Close(); } + + pEntry = NULL; } - if( !pIo->DecRef() ) + if( pIo && !pIo->DecRef() ) + { delete pIo; + pIo = NULL; + } } // Validate the instance for I/O sal_Bool OLEStorageBase::Validate_Impl( sal_Bool bWrite ) const { - if( pEntry + if( pIo + && pIo->pTOC + && pEntry && !pEntry->bInvalid && ( !bWrite || !pEntry->bDirect || ( nStreamMode & STREAM_WRITE ) ) ) - return sal_True; + return sal_True; return sal_False; } @@ -170,7 +178,7 @@ StorageStream::StorageStream( StgIo* p, StgDirEntry* q, StreamMode m ) : OLEStorageBase( p, q, m_nMode ), nPos( 0L ) { // The dir entry may be 0; this means that the stream is invalid. - if( q ) + if( q && p ) { if( q->nRefCnt == 1 ) { @@ -278,14 +286,21 @@ sal_Bool StorageStream::Commit() sal_Bool StorageStream::Revert() { - pEntry->Revert(); - pIo->MoveError( *this ); - return Good(); + sal_Bool bResult = sal_False; + + if ( Validate() ) + { + pEntry->Revert(); + pIo->MoveError( *this ); + bResult = Good(); + } + + return bResult; } sal_Bool StorageStream::CopyTo( BaseStorageStream* pDest ) { - if( !Validate() || !pDest->Validate( sal_True ) || Equals( *pDest ) ) + if( !Validate() || !pDest || !pDest->Validate( sal_True ) || Equals( *pDest ) ) return sal_False; pEntry->Copy( *pDest ); pDest->Commit(); @@ -337,14 +352,20 @@ sal_Bool Storage::IsStorageFile( const String & rFileName ) sal_Bool Storage::IsStorageFile( SvStream* pStream ) { - StgHeader aHdr; - sal_uLong nPos = pStream->Tell(); - sal_Bool bRet = ( aHdr.Load( *pStream ) && aHdr.Check() ); + sal_Bool bRet = sal_False; + + if ( pStream ) + { + StgHeader aHdr; + sal_uLong nPos = pStream->Tell(); + bRet = ( aHdr.Load( *pStream ) && aHdr.Check() ); + + // It's not a stream error if it is too small for a OLE storage header + if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK ) + pStream->ResetError(); + pStream->Seek( nPos ); + } - // It's not a stream error if it is too small for a OLE storage header - if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK ) - pStream->ResetError(); - pStream->Seek( nPos ); return bRet; } @@ -459,7 +480,9 @@ void Storage::Init( sal_Bool bCreate ) pEntry = NULL; sal_Bool bHdrLoaded = sal_False; bIsRoot = sal_True; - if( pIo->Good() ) + + OSL_ENSURE( pIo, "The pointer may not be empty at this point!" ); + if( pIo->Good() && pIo->GetStrm() ) { sal_uLong nSize = pIo->GetStrm()->Seek( STREAM_SEEK_TO_END ); pIo->GetStrm()->Seek( 0L ); @@ -480,7 +503,7 @@ void Storage::Init( sal_Bool bCreate ) // the file is empty if( !bHdrLoaded ) pIo->Init(); - if( pIo->Good() ) + if( pIo->Good() && pIo->pTOC ) { pEntry = pIo->pTOC->GetRoot(); pEntry->nRefCnt++; @@ -535,7 +558,7 @@ const String& Storage::GetName() const void Storage::FillInfoList( SvStorageInfoList* pList ) const { - if( Validate() ) + if( Validate() && pList ) { StgIterator aIter( *pEntry ); StgDirEntry* p = aIter.First(); @@ -731,21 +754,24 @@ sal_Bool Storage::CopyTo( const String& rElem, BaseStorage* pDest, const String& BaseStorage* p1 = OpenStorage( rElem, INTERNAL_MODE ); BaseStorage* p2 = pDest->OpenOLEStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect ); - sal_uLong nTmpErr = p2->GetError(); - if( !nTmpErr ) + if ( p2 ) { - p2->SetClassId( p1->GetClassId() ); - p1->CopyTo( p2 ); - SetError( p1->GetError() ); - - nTmpErr = p2->GetError(); + sal_uLong nTmpErr = p2->GetError(); if( !nTmpErr ) - p2->Commit(); + { + p2->SetClassId( p1->GetClassId() ); + p1->CopyTo( p2 ); + SetError( p1->GetError() ); + + nTmpErr = p2->GetError(); + if( !nTmpErr ) + p2->Commit(); + else + pDest->SetError( nTmpErr ); + } else pDest->SetError( nTmpErr ); } - else - pDest->SetError( nTmpErr ); delete p1; delete p2; @@ -757,20 +783,23 @@ sal_Bool Storage::CopyTo( const String& rElem, BaseStorage* pDest, const String& BaseStorageStream* p1 = OpenStream( rElem, INTERNAL_MODE ); BaseStorageStream* p2 = pDest->OpenStream( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect ); - sal_uLong nTmpErr = p2->GetError(); - if( !nTmpErr ) + if ( p2 ) { - p1->CopyTo( p2 ); - SetError( p1->GetError() ); - - nTmpErr = p2->GetError(); + sal_uLong nTmpErr = p2->GetError(); if( !nTmpErr ) - p2->Commit(); + { + p1->CopyTo( p2 ); + SetError( p1->GetError() ); + + nTmpErr = p2->GetError(); + if( !nTmpErr ) + p2->Commit(); + else + pDest->SetError( nTmpErr ); + } else pDest->SetError( nTmpErr ); } - else - pDest->SetError( nTmpErr ); delete p1; delete p2; @@ -1028,17 +1057,23 @@ sal_Bool Storage::ValidateFAT() void Storage::SetDirty() { - pEntry->SetDirty(); + if ( pEntry ) + pEntry->SetDirty(); } void Storage::SetClassId( const ClsId& rId ) { - pEntry->aEntry.SetClassId( rId ); + if ( pEntry ) + pEntry->aEntry.SetClassId( rId ); } const ClsId& Storage::GetClassId() const { - return pEntry->aEntry.GetClassId(); + if ( pEntry ) + return pEntry->aEntry.GetClassId(); + + static ClsId aDummyId = {0,0,0,0,0,0,0,0,0,0,0}; + return aDummyId; } const SvStream* Storage::GetSvStream() const diff --git a/sot/source/sdstor/stgavl.cxx b/sot/source/sdstor/stgavl.cxx index 554236ad21e6..24a4e7716ae5 100644 --- a/sot/source/sdstor/stgavl.cxx +++ b/sot/source/sdstor/stgavl.cxx @@ -27,7 +27,7 @@ ************************************************************************/ - +#include #include "stgavl.hxx" StgAvlNode::StgAvlNode() @@ -44,13 +44,16 @@ StgAvlNode::~StgAvlNode() StgAvlNode* StgAvlNode::Find( StgAvlNode* pFind ) { - StgAvlNode* p = this; - while( p ) + if ( pFind ) { - short nRes = p->Compare( pFind ); - if( !nRes ) - return p; - else p = ( nRes < 0 ) ? p->pLeft : p->pRight; + StgAvlNode* p = this; + while( p ) + { + short nRes = p->Compare( pFind ); + if( !nRes ) + return p; + else p = ( nRes < 0 ) ? p->pLeft : p->pRight; + } } return NULL; } @@ -64,23 +67,28 @@ short StgAvlNode::Locate { short nRes = 0; StgAvlNode* pCur = this; + + OSL_ENSURE( pPivot && pParent && pPrev, "The pointers may not be NULL!" ); *pParent = *pPrev = NULL; *pPivot = this; // search tree for insertion point - - while( pCur != NULL ) + if ( pFind ) { - // check for pPivot - if( pCur->nBalance != 0 ) - *pPivot = pCur, *pParent = *pPrev; - // save pPrev location and see what direction to go - *pPrev = pCur; - nRes = pCur->Compare( pFind ); - if( nRes == 0 ) - break; - else pCur = ( nRes < 0 ) ? pCur->pLeft : pCur->pRight; + while( pCur != NULL ) + { + // check for pPivot + if( pCur->nBalance != 0 ) + *pPivot = pCur, *pParent = *pPrev; + // save pPrev location and see what direction to go + *pPrev = pCur; + nRes = pCur->Compare( pFind ); + if( nRes == 0 ) + break; + else pCur = ( nRes < 0 ) ? pCur->pLeft : pCur->pRight; + } } + return( nRes ); } @@ -92,8 +100,10 @@ short StgAvlNode::Adjust( StgAvlNode** pHeavy, StgAvlNode* pNew ) StgAvlNode* pCur = this; short nDelta; // no traversing - if( pCur == pNew ) + OSL_ENSURE( pHeavy && pNew, "The pointers is not allowed to be NULL!" ); + if( pCur == pNew || !pNew ) return nBalance; + short nRes = Compare( pNew ); if( nRes > 0 ) { @@ -130,6 +140,7 @@ short StgAvlNode::Adjust( StgAvlNode** pHeavy, StgAvlNode* pNew ) StgAvlNode* StgAvlNode::RotLL() { + OSL_ENSURE( pLeft, "The pointer is not allowed to be NULL!" ); StgAvlNode *pHeavy = pLeft; pLeft = pHeavy->pRight; pHeavy->pRight = this; @@ -141,7 +152,7 @@ StgAvlNode* StgAvlNode::RotLL() StgAvlNode* StgAvlNode::RotLR() { - + OSL_ENSURE( pLeft && pLeft->pRight, "The pointer is not allowed to be NULL!" ); StgAvlNode* pHeavy = pLeft; StgAvlNode* pNewRoot = pHeavy->pRight; @@ -173,6 +184,7 @@ StgAvlNode* StgAvlNode::RotLR() StgAvlNode* StgAvlNode::RotRR() { + OSL_ENSURE( pRight, "The pointer is not allowed to be NULL!" ); StgAvlNode* pHeavy = pRight; pRight = pHeavy->pLeft; pHeavy->pLeft = this; @@ -184,6 +196,7 @@ StgAvlNode* StgAvlNode::RotRR() StgAvlNode* StgAvlNode::RotRL() { + OSL_ENSURE( pRight && pRight->pLeft, "The pointer is not allowed to be NULL!" ); StgAvlNode* pHeavy = pRight; StgAvlNode* pNewRoot = pHeavy->pLeft; pHeavy->pLeft = pNewRoot->pRight; @@ -213,7 +226,7 @@ StgAvlNode* StgAvlNode::RotRL() StgAvlNode* StgAvlNode::Rem( StgAvlNode** p, StgAvlNode* pDel, sal_Bool bPtrs ) { - if( *p ) + if( p && *p && pDel ) { StgAvlNode* pCur = *p; short nRes = bPtrs ? short( pCur == pDel ) : short(pCur->Compare( pDel )); @@ -267,14 +280,11 @@ StgAvlNode* StgAvlNode::Rem( StgAvlNode** p, StgAvlNode* pDel, sal_Bool bPtrs ) void StgAvlNode::StgEnum( short& n ) { - if( this ) - { - if( pLeft ) - pLeft->StgEnum( n ); - nId = n++; - if( pRight ) - pRight->StgEnum( n ); - } + if( pLeft ) + pLeft->StgEnum( n ); + nId = n++; + if( pRight ) + pRight->StgEnum( n ); } // Add node to AVL tree. @@ -283,6 +293,9 @@ void StgAvlNode::StgEnum( short& n ) sal_Bool StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns ) { StgAvlNode* pPivot, *pHeavy, *pNewRoot, *pParent, *pPrev; + if ( !pRoot ) + return sal_False; + // special case - empty tree if( *pRoot == NULL ) { @@ -293,6 +306,8 @@ sal_Bool StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns ) short nRes = (*pRoot)->Locate( pIns, &pPivot, &pParent, &pPrev ); if( !nRes ) return sal_False; + OSL_ENSURE( pPivot && pPrev, "The pointers may not be NULL!" ); + // add new node if( nRes < 0 ) pPrev->pLeft = pIns; @@ -330,6 +345,9 @@ sal_Bool StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns ) sal_Bool StgAvlNode::Remove( StgAvlNode** pRoot, StgAvlNode* pDel, sal_Bool bDel ) { + if ( !pRoot ) + return sal_False; + // special case - empty tree if( *pRoot == NULL ) return sal_False; @@ -360,6 +378,9 @@ sal_Bool StgAvlNode::Remove( StgAvlNode** pRoot, StgAvlNode* pDel, sal_Bool bDel sal_Bool StgAvlNode::Move ( StgAvlNode** pRoot1, StgAvlNode** pRoot2, StgAvlNode* pMove ) { + if ( !pRoot1 ) + return sal_False; + // special case - empty tree if( *pRoot1 == NULL ) return sal_False; diff --git a/sot/source/sdstor/stgcache.cxx b/sot/source/sdstor/stgcache.cxx index 3d467dfca4fe..a263e91865ec 100644 --- a/sot/source/sdstor/stgcache.cxx +++ b/sot/source/sdstor/stgcache.cxx @@ -69,6 +69,7 @@ typedef boost::unordered_map StgPage::StgPage( StgCache* p, short n ) { + OSL_ENSURE( n >= 512, "Unexpected page size is provided!" ); pCache = p; nData = n; bDirty = sal_False; @@ -132,11 +133,15 @@ StgCache::~StgCache() void StgCache::SetPhysPageSize( short n ) { - nPageSize = n; - sal_uLong nPos = pStrm->Tell(); - sal_uLong nFileSize = pStrm->Seek( STREAM_SEEK_TO_END ); - nPages = lcl_GetPageCount( nFileSize, nPageSize ); - pStrm->Seek( nPos ); + OSL_ENSURE( n >= 512, "Unexpecte page size is provided!" ); + if ( n >= 512 ) + { + nPageSize = n; + sal_uLong nPos = pStrm->Tell(); + sal_uLong nFileSize = pStrm->Seek( STREAM_SEEK_TO_END ); + nPages = lcl_GetPageCount( nFileSize, nPageSize ); + pStrm->Seek( nPos ); + } } // Create a new cache element @@ -190,19 +195,24 @@ StgPage* StgCache::Create( sal_Int32 nPg ) void StgCache::Erase( StgPage* pElem ) { - //remove from LRU - pElem->pNext1->pLast1 = pElem->pLast1; - pElem->pLast1->pNext1 = pElem->pNext1; - if( pCur == pElem ) - pCur = ( pElem->pNext1 == pElem ) ? NULL : pElem->pNext1; - if( pLRUCache ) - ((UsrStgPagePtr_Impl*)pLRUCache)->erase( pElem->nPage ); - // remove from Sorted - pElem->pNext2->pLast2 = pElem->pLast2; - pElem->pLast2->pNext2 = pElem->pNext2; - if( pElem1 == pElem ) - pElem1 = ( pElem->pNext2 == pElem ) ? NULL : pElem->pNext2; - delete pElem; + OSL_ENSURE( pElem, "The pointer should not be NULL!" ); + if ( pElem ) + { + OSL_ENSURE( pElem->pNext1 && pElem->pLast1, "The pointers may not be NULL!" ); + //remove from LRU + pElem->pNext1->pLast1 = pElem->pLast1; + pElem->pLast1->pNext1 = pElem->pNext1; + if( pCur == pElem ) + pCur = ( pElem->pNext1 == pElem ) ? NULL : pElem->pNext1; + if( pLRUCache ) + ((UsrStgPagePtr_Impl*)pLRUCache)->erase( pElem->nPage ); + // remove from Sorted + pElem->pNext2->pLast2 = pElem->pLast2; + pElem->pLast2->pNext2 = pElem->pNext2; + if( pElem1 == pElem ) + pElem1 = ( pElem->pNext2 == pElem ) ? NULL : pElem->pNext2; + delete pElem; + } } // remove all cache elements without flushing them @@ -234,9 +244,11 @@ StgPage* StgCache::Find( sal_Int32 nPage ) { // page found StgPage* pFound = (*aIt).second; + OSL_ENSURE( pFound, "The pointer may not be NULL!" ); if( pFound != pCur ) { + OSL_ENSURE( pFound->pNext1 && pFound->pLast1, "The pointers may not be NULL!" ); // remove from LRU pFound->pNext1->pLast1 = pFound->pLast1; pFound->pLast1->pNext1 = pFound->pNext1; @@ -283,7 +295,10 @@ StgPage* StgCache::Copy( sal_Int32 nNew, sal_Int32 nOld ) // old page: we must have this data! StgPage* q = Get( nOld, sal_True ); if( q ) + { + OSL_ENSURE( p->nData == q->nData, "Unexpected page size!" ); memcpy( p->pData, q->pData, p->nData ); + } } p->SetDirty(); return p; @@ -455,11 +470,15 @@ sal_Bool StgCache::Read( sal_Int32 nPage, void* pBuf, sal_Int32 nPg ) sal_Bool StgCache::Write( sal_Int32 nPage, void* pBuf, sal_Int32 nPg ) { - if( Good() ) + if( Good() ) { sal_uLong nPos = Page2Pos( nPage ); - sal_uLong nBytes = nPg * nPageSize; + sal_uLong nBytes = 0; + if ( SAL_MAX_INT32 / nPg > nPageSize ) + nBytes = nPg * nPageSize; + // fixed address and size for the header + // nPageSize must be >= 512, otherwise the header can not be written here, we check it on import if( nPage == -1 ) nPos = 0L, nBytes = 512; if( pStrm->Tell() != nPos ) diff --git a/sot/source/sdstor/stgcache.hxx b/sot/source/sdstor/stgcache.hxx index d54563189629..4ea16d3b3d9e 100644 --- a/sot/source/sdstor/stgcache.hxx +++ b/sot/source/sdstor/stgcache.hxx @@ -72,7 +72,7 @@ public: SvStream* GetStrm() { return pStrm; } void SetStrm( SvStream*, sal_Bool ); void SetStrm( UCBStorageStream* ); - sal_Bool IsWritable() { return pStrm->IsWritable(); } + sal_Bool IsWritable() { return ( pStrm && pStrm->IsWritable() ); } sal_Bool Good() { return sal_Bool( nError == SVSTREAM_OK ); } sal_Bool Bad() { return sal_Bool( nError != SVSTREAM_OK ); } sal_uLong GetError() { return nError; } diff --git a/sot/source/sdstor/stgdir.cxx b/sot/source/sdstor/stgdir.cxx index 7a69118569ef..f9546340036a 100644 --- a/sot/source/sdstor/stgdir.cxx +++ b/sot/source/sdstor/stgdir.cxx @@ -53,9 +53,9 @@ // Problem der Implementation: Keine Hierarchischen commits. Daher nur // insgesamt transaktionsorientert oder direkt. -StgDirEntry::StgDirEntry( const void* pFrom, sal_Bool * pbOk ) : StgAvlNode() +StgDirEntry::StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, sal_Bool * pbOk ) : StgAvlNode() { - *pbOk = aEntry.Load( pFrom ); + *pbOk = aEntry.Load( pBuffer, nBufferLen ); InitMembers(); } @@ -102,8 +102,13 @@ StgDirEntry::~StgDirEntry() short StgDirEntry::Compare( const StgAvlNode* p ) const { - const StgDirEntry* pEntry = (const StgDirEntry*) p; - return aEntry.Compare( pEntry->aEntry ); + short nResult = -1; + if ( p ) + { + const StgDirEntry* pEntry = (const StgDirEntry*) p; + nResult = aEntry.Compare( pEntry->aEntry ); + } + return nResult; } // Enumerate the entry numbers. @@ -263,9 +268,9 @@ void StgDirEntry::OpenStream( StgIo& rIo, sal_Bool bForceBig ) sal_Int32 nThreshold = (sal_uInt16) rIo.aHdr.GetThreshold(); delete pStgStrm; if( !bForceBig && aEntry.GetSize() < nThreshold ) - pStgStrm = new StgSmallStrm( rIo, this ); + pStgStrm = new StgSmallStrm( rIo, *this ); else - pStgStrm = new StgDataStrm( rIo, this ); + pStgStrm = new StgDataStrm( rIo, *this ); if( bInvalid && aEntry.GetSize() ) { // This entry has invalid data, so delete that data @@ -323,6 +328,10 @@ sal_Bool StgDirEntry::SetSize( sal_Int32 nNewSize ) } else { + OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" ); + if ( !pStgStrm ) + return sal_False; + sal_Bool bRes = sal_False; StgIo& rIo = pStgStrm->GetIo(); sal_Int32 nThreshold = rIo.aHdr.GetThreshold(); @@ -402,6 +411,10 @@ sal_Int32 StgDirEntry::Seek( sal_Int32 nNew ) } else { + OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" ); + if ( !pStgStrm ) + return nPos; + sal_Int32 nSize = aEntry.GetSize(); if( nNew < 0 ) @@ -421,6 +434,7 @@ sal_Int32 StgDirEntry::Seek( sal_Int32 nNew ) pStgStrm->Pos2Page( nNew ); nNew = pStgStrm->GetPos(); } + return nPos = nNew; } @@ -435,7 +449,14 @@ sal_Int32 StgDirEntry::Read( void* p, sal_Int32 nLen ) else if( pCurStrm ) nLen = pCurStrm->Read( p, nLen ); else + { + OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" ); + if ( !pStgStrm ) + return 0; + nLen = pStgStrm->Read( p, nLen ); + } + nPos += nLen; return nLen; } @@ -453,6 +474,11 @@ sal_Int32 StgDirEntry::Write( const void* p, sal_Int32 nLen ) // Is this stream opened in transacted mode? Do we have to make a copy? if( !bDirect && !pTmpStrm && !Strm2Tmp() ) return 0; + + OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" ); + if ( !pStgStrm ) + return 0; + if( pTmpStrm ) { nLen = pTmpStrm->Write( p, nLen ); @@ -609,6 +635,10 @@ sal_Bool StgDirEntry::Strm2Tmp() { if( n ) { + OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" ); + if ( !pStgStrm ) + return sal_False; + sal_uInt8 aTempBytes[ 4096 ]; void* p = static_cast( aTempBytes ); pStgStrm->Pos2Page( 0L ); @@ -630,9 +660,13 @@ sal_Bool StgDirEntry::Strm2Tmp() else n = 1; } + if( n ) { - pStgStrm->GetIo().SetError( pTmpStrm->GetError() ); + OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" ); + if ( pStgStrm ) + pStgStrm->GetIo().SetError( pTmpStrm->GetError() ); + delete pTmpStrm; pTmpStrm = NULL; return sal_False; @@ -650,6 +684,9 @@ sal_Bool StgDirEntry::Tmp2Strm() pTmpStrm = pCurStrm, pCurStrm = NULL; if( pTmpStrm ) { + OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" ); + if ( !pStgStrm ) + return sal_False; sal_uLong n = pTmpStrm->GetSize(); StgStrm* pNewStrm; StgIo& rIo = pStgStrm->GetIo(); @@ -786,7 +823,7 @@ void StgDirStrm::SetupEntry( sal_Int32 n, StgDirEntry* pUpper ) if( p ) { sal_Bool bOk(sal_False); - StgDirEntry* pCur = new StgDirEntry( p, &bOk ); + StgDirEntry* pCur = new StgDirEntry( p, STGENTRY_SIZE, &bOk ); if( !bOk ) { @@ -863,6 +900,9 @@ void StgDirStrm::SetupEntry( sal_Int32 n, StgDirEntry* pUpper ) sal_Bool StgDirStrm::SetSize( sal_Int32 nBytes ) { // Always allocate full pages + if ( nBytes < 0 ) + nBytes = 0; + nBytes = ( ( nBytes + nPageSize - 1 ) / nPageSize ) * nPageSize; return StgStrm::SetSize( nBytes ); } @@ -871,7 +911,7 @@ sal_Bool StgDirStrm::SetSize( sal_Int32 nBytes ) sal_Bool StgDirStrm::Store() { - if( !pRoot->IsDirty() ) + if( !pRoot || !pRoot->IsDirty() ) return sal_True; if( !pRoot->StoreStreams( rIo ) ) return sal_False; diff --git a/sot/source/sdstor/stgdir.hxx b/sot/source/sdstor/stgdir.hxx index 8a4cf68db903..16c2e113bf9e 100644 --- a/sot/source/sdstor/stgdir.hxx +++ b/sot/source/sdstor/stgdir.hxx @@ -71,7 +71,7 @@ public: sal_Bool bDirect; // sal_True: direct mode sal_Bool bZombie; // sal_True: Removed From StgIo sal_Bool bInvalid; // sal_True: invalid entry - StgDirEntry( const void*, sal_Bool * pbOk ); + StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, sal_Bool * pbOk ); StgDirEntry( const StgEntry& ); ~StgDirEntry(); diff --git a/sot/source/sdstor/stgelem.cxx b/sot/source/sdstor/stgelem.cxx index e8eb0e59db45..d63398cfa67d 100644 --- a/sot/source/sdstor/stgelem.cxx +++ b/sot/source/sdstor/stgelem.cxx @@ -79,21 +79,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++ ) @@ -102,9 +125,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 ) @@ -127,7 +156,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 ) @@ -166,8 +196,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 @@ -222,7 +259,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 ); @@ -315,9 +366,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 @@ -343,7 +397,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 diff --git a/sot/source/sdstor/stgelem.hxx b/sot/source/sdstor/stgelem.hxx index 6ea349e7ef4e..a9025b2b813e 100644 --- a/sot/source/sdstor/stgelem.hxx +++ b/sot/source/sdstor/stgelem.hxx @@ -64,6 +64,7 @@ class StgHeader sal_Int32 nMasterFAT[ 109 ]; // 4C first 109 master FAT pages public: StgHeader(); + void Init(); // initialize the header sal_Bool Load( StgIo& ); sal_Bool Load( SvStream& ); @@ -139,7 +140,7 @@ public: void GetName( String& rName ) const; // fill in the name short Compare( const StgEntry& ) const; // compare two entries - sal_Bool Load( const void* ); + sal_Bool Load( const void* pBuffer, sal_uInt32 nBufSize ); void Store( void* ); StgEntryType GetType() const { return (StgEntryType) cType; } sal_Int32 GetStartPage() const { return nPage1; } diff --git a/sot/source/sdstor/stgio.cxx b/sot/source/sdstor/stgio.cxx index 0c36268c9b26..1d71a34df5b6 100644 --- a/sot/source/sdstor/stgio.cxx +++ b/sot/source/sdstor/stgio.cxx @@ -69,6 +69,8 @@ sal_Bool StgIo::Load() else return sal_False; } + else + return sal_False; } return Good(); } @@ -102,7 +104,7 @@ void StgIo::SetupStreams() if( pRoot ) { pDataFAT = new StgDataStrm( *this, aHdr.GetDataFATStart(), -1 ); - pDataStrm = new StgDataStrm( *this, pRoot ); + pDataStrm = new StgDataStrm( *this, *pRoot ); pDataFAT->SetIncrement( 1 << aHdr.GetPageSize() ); pDataStrm->SetIncrement( GetDataPageSize() ); pDataStrm->SetEntry( *pRoot ); @@ -124,7 +126,7 @@ short StgIo::GetDataPageSize() sal_Bool StgIo::CommitAll() { // Store the data (all streams and the TOC) - if( pTOC->Store() ) + if( pTOC && pTOC->Store() && pDataFAT ) { if( Commit() ) { @@ -161,7 +163,11 @@ public: sal_Int32 GetPageSize() { return nPageSize; } sal_Int32 Count() { return nPages; } - sal_Int32 operator[]( sal_Int32 nOffset ) { return pFat[ nOffset ]; } + sal_Int32 operator[]( sal_Int32 nOffset ) + { + OSL_ENSURE( nOffset >= 0 && nOffset < nPages, "Unexpected offset!" ); + return nOffset >= 0 && nOffset < nPages ? pFat[ nOffset ] : -2; + } sal_uLong Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect ); sal_Bool HasUnrefChains(); @@ -209,6 +215,8 @@ sal_uLong EasyFat::Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect ) sal_Int32 nCurPage = nPage; while( nCount != 0 ) { + if( nCurPage < 0 || nCurPage >= nPages ) + return FAT_OUTOFBOUNDS; pFree[ nCurPage ] = sal_False; nCurPage = pFat[ nCurPage ]; //Stream zu lang @@ -222,9 +230,6 @@ sal_uLong EasyFat::Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect ) nCount = 1; if( nCount != -1 ) nCount--; - // Naechster Block nicht in der FAT - if( nCount && ( nCurPage < 0 || nCurPage >= nPages ) ) - return FAT_OUTOFBOUNDS; } return FAT_OK; } @@ -268,6 +273,9 @@ sal_uLong Validator::ValidateMasterFATs() { sal_Int32 nCount = rIo.aHdr.GetFATSize(); sal_uLong nErr; + if ( !rIo.pFAT ) + return FAT_INMEMORYERROR; + for( sal_Int32 i = 0; i < nCount; i++ ) { if( ( nErr = aFat.Mark(rIo.pFAT->GetPage( short(i), sal_False ), aFat.GetPageSize(), -3 )) != FAT_OK ) @@ -276,11 +284,15 @@ sal_uLong Validator::ValidateMasterFATs() if( rIo.aHdr.GetMasters() ) if( ( nErr = aFat.Mark(rIo.aHdr.GetFATChain( ), aFat.GetPageSize(), -4 )) != FAT_OK ) return nErr; + return FAT_OK; } sal_uLong Validator::MarkAll( StgDirEntry *pEntry ) { + if ( !pEntry ) + return FAT_INMEMORYERROR; + StgIterator aIter( *pEntry ); sal_uLong nErr = FAT_OK; for( StgDirEntry* p = aIter.First(); p ; p = aIter.Next() ) @@ -307,6 +319,9 @@ sal_uLong Validator::MarkAll( StgDirEntry *pEntry ) sal_uLong Validator::ValidateDirectoryEntries() { + if ( !rIo.pTOC ) + return FAT_INMEMORYERROR; + // Normale DirEntries sal_uLong nErr = MarkAll( rIo.pTOC->GetRoot() ); if( nErr != FAT_OK ) @@ -356,7 +371,11 @@ sal_uLong StgIo::ValidateFATs() Validator *pV = new Validator( *this ); sal_Bool bRet1 = !pV->IsError(), bRet2 = sal_True ; delete pV; + SvFileStream *pFileStrm = ( SvFileStream *) GetStrm(); + if ( !pFileStrm ) + return FAT_INMEMORYERROR; + StgIo aIo; if( aIo.Open( pFileStrm->GetFileName(), STREAM_READ | STREAM_SHARE_DENYNONE) && diff --git a/sot/source/sdstor/stgole.cxx b/sot/source/sdstor/stgole.cxx index 68a7a3a00c6f..9366df1f4dfd 100644 --- a/sot/source/sdstor/stgole.cxx +++ b/sot/source/sdstor/stgole.cxx @@ -124,23 +124,28 @@ sal_Bool StgCompObjStream::Load() *this >> aClsId; sal_Int32 nLen1 = 0; *this >> nLen1; - // higher bits are ignored - nLen1 &= 0xFFFF; - sal_Char* p = new sal_Char[ (sal_uInt16) nLen1 ]; - if( Read( p, nLen1 ) == (sal_uLong) nLen1 ) + if ( nLen1 > 0 ) { - //The encoding here is "ANSI", which is pretty useless seeing as - //the actual codepage used doesn't seem to be specified/stored - //anywhere :-(. Might as well pick 1252 and be consistent on - //all platforms and envs - //http://www.openoffice.org/nonav/issues/showattachment.cgi/68668/Orginal%20Document.doc - //for a good edge-case example - aUserName = nLen1 ? String( p, RTL_TEXTENCODING_MS_1252 ) : String(); - nCbFormat = ReadClipboardFormat( *this ); + // higher bits are ignored + sal_uLong nStrLen = ::std::min( nLen1, (sal_Int32)0xFFFE ); + + sal_Char* p = new sal_Char[ nStrLen+1 ]; + p[nStrLen] = 0; + if( Read( p, nStrLen ) == nStrLen ) + { + //The encoding here is "ANSI", which is pretty useless seeing as + //the actual codepage used doesn't seem to be specified/stored + //anywhere :-(. Might as well pick 1252 and be consistent on + //all platforms and envs + //http://www.openoffice.org/nonav/issues/showattachment.cgi/68668/Orginal%20Document.doc + //for a good edge-case example + aUserName = nStrLen ? String( p, RTL_TEXTENCODING_MS_1252 ) : String(); + nCbFormat = ReadClipboardFormat( *this ); + } + else + SetError( SVSTREAM_GENERALERROR ); + delete [] p; } - else - SetError( SVSTREAM_GENERALERROR ); - delete [] p; } return sal_Bool( GetError() == SVSTREAM_OK ); } diff --git a/sot/source/sdstor/stgstrms.cxx b/sot/source/sdstor/stgstrms.cxx index 7bef24381f50..b63eaca72d73 100644 --- a/sot/source/sdstor/stgstrms.cxx +++ b/sot/source/sdstor/stgstrms.cxx @@ -81,7 +81,7 @@ sal_Int32 StgFAT::GetNextPage( sal_Int32 nPg ) { if( nPg >= 0 ) { - StgPage* pPg = GetPhysPage( nPg << 2 ); + StgPage* pPg = GetPhysPage( nPg << 2 ); nPg = pPg ? pPg->GetPage( nOffset >> 2 ) : STG_EOF; } return nPg; @@ -269,19 +269,22 @@ sal_Int32 StgFAT::AllocPages( sal_Int32 nBgn, sal_Int32 nPgs ) sal_Bool StgFAT::InitNew( sal_Int32 nPage1 ) { sal_Int32 n = ( ( rStrm.GetSize() >> 2 ) - nPage1 ) / nEntries; - while( n-- ) + if ( n > 0 ) { - StgPage* pPg = NULL; - // Position within the underlying stream - // use the Pos2Page() method of the stream - rStrm.Pos2Page( nPage1 << 2 ); - // Initialize the page - pPg = rStrm.GetIo().Copy( rStrm.GetPage(), STG_FREE ); - if ( !pPg ) - return sal_False; - for( short i = 0; i < nEntries; i++ ) - pPg->SetPage( i, STG_FREE ); - nPage1++; + while( n-- ) + { + StgPage* pPg = NULL; + // Position within the underlying stream + // use the Pos2Page() method of the stream + rStrm.Pos2Page( nPage1 << 2 ); + // Initialize the page + pPg = rStrm.GetIo().Copy( rStrm.GetPage(), STG_FREE ); + if ( !pPg ) + return sal_False; + for( short i = 0; i < nEntries; i++ ) + pPg->SetPage( i, STG_FREE ); + nPage1++; + } } return sal_True; } @@ -374,6 +377,9 @@ void StgStrm::scanBuildPageChainCache(sal_Int32 *pOptionalCalcSize) // behind the EOF. sal_Bool StgStrm::Pos2Page( sal_Int32 nBytePos ) { + if ( !pFat ) + return sal_False; + // Values < 0 seek to the end if( nBytePos < 0 || nBytePos >= nSize ) nBytePos = nSize; @@ -456,6 +462,9 @@ StgPage* StgStrm::GetPhysPage( sal_Int32 nBytePos, sal_Bool bForce ) sal_Bool StgStrm::Copy( sal_Int32 nFrom, sal_Int32 nBytes ) { + if ( !pFat ) + return sal_False; + m_aPagesCache.clear(); sal_Int32 nTo = nStart; @@ -484,6 +493,9 @@ sal_Bool StgStrm::Copy( sal_Int32 nFrom, sal_Int32 nBytes ) sal_Bool StgStrm::SetSize( sal_Int32 nBytes ) { + if ( nBytes < 0 || !pFat ) + return sal_False; + m_aPagesCache.clear(); // round up to page size @@ -557,6 +569,7 @@ sal_Bool StgFATStrm::Pos2Page( sal_Int32 nBytePos ) StgPage* StgFATStrm::GetPhysPage( sal_Int32 nBytePos, sal_Bool bForce ) { + OSL_ENSURE( nBytePos >= 0, "The value may not be negative!" ); return rIo.Get( nBytePos / ( nPageSize >> 2 ), bForce ); } @@ -564,6 +577,7 @@ StgPage* StgFATStrm::GetPhysPage( sal_Int32 nBytePos, sal_Bool bForce ) sal_Int32 StgFATStrm::GetPage( short nOff, sal_Bool bMake, sal_uInt16 *pnMasterAlloc ) { + OSL_ENSURE( nOff >= 0, "The offset may not be negative!" ); if( pnMasterAlloc ) *pnMasterAlloc = 0; if( nOff < rIo.aHdr.GetFAT1Size() ) return rIo.aHdr.GetFATPage( nOff ); @@ -640,6 +654,7 @@ sal_Int32 StgFATStrm::GetPage( short nOff, sal_Bool bMake, sal_uInt16 *pnMasterA sal_Bool StgFATStrm::SetPage( short nOff, sal_Int32 nNewPage ) { + OSL_ENSURE( nOff >= 0, "The offset may not be negative!" ); m_aPagesCache.clear(); sal_Bool bRes = sal_True; @@ -691,6 +706,9 @@ sal_Bool StgFATStrm::SetPage( short nOff, sal_Int32 nNewPage ) sal_Bool StgFATStrm::SetSize( sal_Int32 nBytes ) { + if ( nBytes < 0 ) + return sal_False; + m_aPagesCache.clear(); // Set the number of entries to a multiple of the page size @@ -719,6 +737,7 @@ sal_Bool StgFATStrm::SetSize( sal_Int32 nBytes ) // find a free page using the FAT allocator sal_Int32 n = 1; + OSL_ENSURE( pFat, "The pointer is always initializer here!" ); sal_Int32 nNewPage = pFat->FindBlock( n ); if( nNewPage == STG_EOF ) { @@ -791,21 +810,25 @@ StgDataStrm::StgDataStrm( StgIo& r, sal_Int32 nBgn, sal_Int32 nLen ) : StgStrm( Init( nBgn, nLen ); } -StgDataStrm::StgDataStrm( StgIo& r, StgDirEntry* p ) : StgStrm( r ) +StgDataStrm::StgDataStrm( StgIo& r, StgDirEntry& p ) : StgStrm( r ) { - pEntry = p; - Init( p->aEntry.GetLeaf( STG_DATA ), - p->aEntry.GetSize() ); + pEntry = &p; + Init( p.aEntry.GetLeaf( STG_DATA ), + p.aEntry.GetSize() ); } void StgDataStrm::Init( sal_Int32 nBgn, sal_Int32 nLen ) { - pFat = new StgFAT( *rIo.pFAT, sal_True ); + if ( rIo.pFAT ) + pFat = new StgFAT( *rIo.pFAT, sal_True ); + + OSL_ENSURE( pFat, "The pointer should not be empty!" ); + nStart = nPage = nBgn; nSize = nLen; nIncr = 1; nOffset = 0; - if( nLen < 0 ) + if( nLen < 0 && pFat ) { // determine the actual size of the stream by scanning // the FAT chain and counting the # of pages allocated @@ -817,6 +840,9 @@ void StgDataStrm::Init( sal_Int32 nBgn, sal_Int32 nLen ) sal_Bool StgDataStrm::SetSize( sal_Int32 nBytes ) { + if ( !pFat ) + return sal_False; + nBytes = ( ( nBytes + nIncr - 1 ) / nIncr ) * nIncr; sal_Int32 nOldSz = nSize; if( ( nOldSz != nBytes ) ) @@ -922,12 +948,15 @@ sal_Int32 StgDataStrm::Read( void* pBuf, sal_Int32 n ) sal_Int32 StgDataStrm::Write( const void* pBuf, sal_Int32 n ) { + if ( n < 0 ) + return 0; + sal_Int32 nDone = 0; if( ( nPos + n ) > nSize ) { sal_Int32 nOld = nPos; if( !SetSize( nPos + n ) ) - return sal_False; + return 0; Pos2Page( nOld ); } while( n ) @@ -992,17 +1021,20 @@ StgSmallStrm::StgSmallStrm( StgIo& r, sal_Int32 nBgn, sal_Int32 nLen ) : StgStrm Init( nBgn, nLen ); } -StgSmallStrm::StgSmallStrm( StgIo& r, StgDirEntry* p ) : StgStrm( r ) +StgSmallStrm::StgSmallStrm( StgIo& r, StgDirEntry& p ) : StgStrm( r ) { - pEntry = p; - Init( p->aEntry.GetLeaf( STG_DATA ), - p->aEntry.GetSize() ); + pEntry = &p; + Init( p.aEntry.GetLeaf( STG_DATA ), + p.aEntry.GetSize() ); } void StgSmallStrm::Init( sal_Int32 nBgn, sal_Int32 nLen ) { - pFat = new StgFAT( *rIo.pDataFAT, sal_False ); + if ( rIo.pDataFAT ) + pFat = new StgFAT( *rIo.pDataFAT, sal_False ); pData = rIo.pDataStrm; + OSL_ENSURE( pFat && pData, "The pointers should not be empty!" ); + nPageSize = rIo.GetDataPageSize(); nStart = nPage = nBgn; @@ -1027,7 +1059,7 @@ sal_Int32 StgSmallStrm::Read( void* pBuf, sal_Int32 n ) nBytes = (short) n; if( nBytes ) { - if( !pData->Pos2Page( nPage * nPageSize + nOffset ) ) + if( !pData || !pData->Pos2Page( nPage * nPageSize + nOffset ) ) break; // all reading thru the stream short nRes = (short) pData->Read( (sal_uInt8*)pBuf + nDone, nBytes ); @@ -1067,9 +1099,10 @@ sal_Int32 StgSmallStrm::Write( const void* pBuf, sal_Int32 n ) { // all writing goes thru the stream sal_Int32 nDataPos = nPage * nPageSize + nOffset; - if( pData->GetSize() < ( nDataPos + nBytes ) ) - if( !pData->SetSize( nDataPos + nBytes ) ) - break; + if ( !pData + || ( pData->GetSize() < ( nDataPos + nBytes ) + && !pData->SetSize( nDataPos + nBytes ) ) ) + break; if( !pData->Pos2Page( nDataPos ) ) break; short nRes = (short) pData->Write( (sal_uInt8*)pBuf + nDone, nBytes ); diff --git a/sot/source/sdstor/stgstrms.hxx b/sot/source/sdstor/stgstrms.hxx index dff07dfa4d98..4eddfdaee571 100644 --- a/sot/source/sdstor/stgstrms.hxx +++ b/sot/source/sdstor/stgstrms.hxx @@ -126,7 +126,7 @@ class StgDataStrm : public StgStrm // a physical data stream void Init( sal_Int32 nBgn, sal_Int32 nLen ); public: StgDataStrm( StgIo&, sal_Int32 nBgn, sal_Int32 nLen=-1 ); - StgDataStrm( StgIo&, StgDirEntry* ); + StgDataStrm( StgIo&, StgDirEntry& ); void* GetPtr( sal_Int32 nPos, sal_Bool bForce, sal_Bool bDirty ); void SetIncrement( short n ) { nIncr = n ; } virtual sal_Bool SetSize( sal_Int32 ); @@ -145,7 +145,7 @@ class StgSmallStrm : public StgStrm // a logical data stream void Init( sal_Int32 nBgn, sal_Int32 nLen ); public: StgSmallStrm( StgIo&, sal_Int32 nBgn, sal_Int32 nLen ); - StgSmallStrm( StgIo&, StgDirEntry* ); + StgSmallStrm( StgIo&, StgDirEntry& ); virtual sal_Int32 Read( void*, sal_Int32 ); virtual sal_Int32 Write( const void*, sal_Int32 ); virtual sal_Bool IsSmallStrm() const { return sal_True; } diff --git a/sot/source/sdstor/storinfo.cxx b/sot/source/sdstor/storinfo.cxx index d3a84809f423..c480e89b6e9a 100644 --- a/sot/source/sdstor/storinfo.cxx +++ b/sot/source/sdstor/storinfo.cxx @@ -44,10 +44,11 @@ sal_uLong ReadClipboardFormat( SvStream & rStm ) if( nLen > 0 ) { // get a string name - sal_Char * p = new sal_Char[ nLen ]; - if( rStm.Read( p, nLen ) == (sal_uLong) nLen ) + sal_Char * p = new( ::std::nothrow ) sal_Char[ nLen ]; + if( p && rStm.Read( p, nLen ) == (sal_uLong) nLen ) { - nFormat = SotExchange::RegisterFormatName( String::CreateFromAscii( p, short(nLen-1) ) ); + // take so much from the buffer, as the string supports + nFormat = SotExchange::RegisterFormatName( String::CreateFromAscii( p, xub_StrLen( ( nLen - 1 ) & STRING_MAXLEN ) ) ); } else rStm.SetError( SVSTREAM_GENERALERROR ); -- cgit v1.2.3