[Libreoffice-commits] .: Branch 'libreoffice-3-5' - sot/source

Petr Mladek pmladek at kemper.freedesktop.org
Tue Jul 31 05:14:35 PDT 2012


 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(-)

New commits:
commit f95762beb3b5849bfaccd39523a11fe15b191d89
Author: Mikhail Voytenko <mav at openoffice.org>
Date:   Tue Jul 31 12:08:39 2012 +0200

    sot: prevent some null pointer crashes

diff --git a/sot/source/sdstor/stg.cxx b/sot/source/sdstor/stg.cxx
index 18e95f6..dbb34a1 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();
@@ -345,14 +360,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;
 }
 
@@ -467,7 +488,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 );
@@ -488,7 +511,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++;
@@ -543,7 +566,7 @@ const String& Storage::GetName() const
 
 void Storage::FillInfoList( SvStorageInfoList* pList ) const
 {
-    if( Validate() )
+	if( Validate() && pList )
     {
         StgIterator aIter( *pEntry );
         StgDirEntry* p = aIter.First();
@@ -739,21 +762,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;
@@ -765,20 +791,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;
@@ -1036,17 +1065,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 b451bf2..c1042f8 100644
--- a/sot/source/sdstor/stgavl.cxx
+++ b/sot/source/sdstor/stgavl.cxx
@@ -27,7 +27,7 @@
  ************************************************************************/
 
 
-
+#include <osl/diagnose.h>
 #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 a9f2f90..79b43d3 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;
@@ -458,11 +473,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 9b47cff..1dea5b1 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 ccc7b17..fd613c7 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<void*>( 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();
@@ -787,7 +824,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 )
         {
@@ -864,6 +901,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 );
 }
@@ -872,7 +912,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 f260d42..9524b5f 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 bb163e6..1af72f9 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
@@ -228,7 +265,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 );
@@ -322,9 +373,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
@@ -350,7 +404,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 7792608..d96051e 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& );
@@ -140,7 +141,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 40b4cea..f2079dc 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( NULL ) )
         {
@@ -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 127cd60..272ca85 100644
--- a/sot/source/sdstor/stgole.cxx
+++ b/sot/source/sdstor/stgole.cxx
@@ -125,23 +125,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 b220973..e7f3843 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 5a9558b..39a83ee 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() { return sal_True; }
diff --git a/sot/source/sdstor/storinfo.cxx b/sot/source/sdstor/storinfo.cxx
index d3a8480..c480e89 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 );


More information about the Libreoffice-commits mailing list