summaryrefslogtreecommitdiff
path: root/sot
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-07-22 09:24:53 +0100
committerCaolán McNamara <caolanm@redhat.com>2015-07-22 16:12:15 +0000
commit786573068dce1f71c53057f98b5822c401c9f3ff (patch)
tree0288ead6e1c55d572e1666962401901798ed89ca /sot
parent26e6d4b05ab444e6a7529ffcac7fbe592fc94833 (diff)
limit storage entry max size to size of underlying stream
Change-Id: Ie3772338009c07fea40b637621b1170863830e14 Reviewed-on: https://gerrit.libreoffice.org/17296 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sot')
-rw-r--r--sot/qa/cppunit/data/fail/fdo41642-2.compound (renamed from sot/qa/cppunit/data/pass/fdo41642-2.compound)bin35335 -> 35335 bytes
-rw-r--r--sot/source/sdstor/stgdir.cxx11
-rw-r--r--sot/source/sdstor/stgdir.hxx3
-rw-r--r--sot/source/sdstor/stgelem.cxx25
-rw-r--r--sot/source/sdstor/stgelem.hxx2
5 files changed, 31 insertions, 10 deletions
diff --git a/sot/qa/cppunit/data/pass/fdo41642-2.compound b/sot/qa/cppunit/data/fail/fdo41642-2.compound
index b1ae6dd63046..b1ae6dd63046 100644
--- a/sot/qa/cppunit/data/pass/fdo41642-2.compound
+++ b/sot/qa/cppunit/data/fail/fdo41642-2.compound
Binary files differ
diff --git a/sot/source/sdstor/stgdir.cxx b/sot/source/sdstor/stgdir.cxx
index 6ee4a618e493..e2c8bf7b621e 100644
--- a/sot/source/sdstor/stgdir.cxx
+++ b/sot/source/sdstor/stgdir.cxx
@@ -48,9 +48,9 @@
// Problem der Implementation: Keine Hierarchischen commits. Daher nur
// insgesamt transaktionsorientert oder direkt.
-StgDirEntry::StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, bool * pbOk ) : StgAvlNode()
+StgDirEntry::StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, sal_uInt64 nUnderlyingStreamSize, bool * pbOk ) : StgAvlNode()
{
- *pbOk = aEntry.Load( pBuffer, nBufferLen );
+ *pbOk = aEntry.Load( pBuffer, nBufferLen, nUnderlyingStreamSize );
InitMembers();
}
@@ -819,8 +819,13 @@ void StgDirStrm::SetupEntry( sal_Int32 n, StgDirEntry* pUpper )
void* p = ( n == STG_FREE ) ? NULL : GetEntry( n );
if( p )
{
+ SvStream *pUnderlyingStream = rIo.GetStrm();
+ sal_uInt64 nCur = pUnderlyingStream->Tell();
+ sal_uInt64 nUnderlyingStreamSize = pUnderlyingStream->Seek(STREAM_SEEK_TO_END);
+ pUnderlyingStream->Seek(nCur);
+
bool bOk(false);
- StgDirEntry* pCur = new StgDirEntry( p, STGENTRY_SIZE, &bOk );
+ StgDirEntry* pCur = new StgDirEntry( p, STGENTRY_SIZE, nUnderlyingStreamSize, &bOk );
if( !bOk )
{
diff --git a/sot/source/sdstor/stgdir.hxx b/sot/source/sdstor/stgdir.hxx
index c0924f1bf3af..55be53d8d359 100644
--- a/sot/source/sdstor/stgdir.hxx
+++ b/sot/source/sdstor/stgdir.hxx
@@ -62,7 +62,8 @@ public:
bool bDirect; // true: direct mode
bool bZombie; // true: Removed From StgIo
bool bInvalid; // true: invalid entry
- StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, bool * pbOk );
+ StgDirEntry(const void* pBuffer, sal_uInt32 nBufferLen,
+ sal_uInt64 nUnderlyingStreamSize, bool * pbOk);
StgDirEntry( const StgEntry& );
virtual ~StgDirEntry();
diff --git a/sot/source/sdstor/stgelem.cxx b/sot/source/sdstor/stgelem.cxx
index 8e2f9bd86e98..bb85e9f7171a 100644
--- a/sot/source/sdstor/stgelem.cxx
+++ b/sot/source/sdstor/stgelem.cxx
@@ -361,7 +361,7 @@ sal_Int32 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.
-bool StgEntry::Load( const void* pFrom, sal_uInt32 nBufSize )
+bool StgEntry::Load(const void* pFrom, sal_uInt32 nBufSize, sal_uInt64 nUnderlyingStreamSize)
{
if ( nBufSize < 128 )
return false;
@@ -392,11 +392,26 @@ bool StgEntry::Load( const void* pFrom, sal_uInt32 nBufSize )
if (n > nMaxLegalStr)
return false;
- if ((cType != STG_STORAGE) && ((nSize < 0) || (nPage1 < 0 && !isKnownSpecial(nPage1))))
+ if (cType != STG_STORAGE)
{
- // 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
- return false;
+ if (nPage1 < 0 && !isKnownSpecial(nPage1))
+ {
+ //bad pageid
+ return false;
+ }
+ if (nSize < 0)
+ {
+ // 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
+ return false;
+ }
+ if (static_cast<sal_uInt64>(nSize) > nUnderlyingStreamSize)
+ {
+ // surely an entry cannot be larger than the underlying file
+ return false;
+ }
+
}
aName = OUString(nName , n);
diff --git a/sot/source/sdstor/stgelem.hxx b/sot/source/sdstor/stgelem.hxx
index afeb9503da4f..678b5810d2db 100644
--- a/sot/source/sdstor/stgelem.hxx
+++ b/sot/source/sdstor/stgelem.hxx
@@ -129,7 +129,7 @@ public:
void GetName( OUString& rName ) const;
// fill in the name
sal_Int32 Compare( const StgEntry& ) const; // compare two entries
- bool Load( const void* pBuffer, sal_uInt32 nBufSize );
+ bool Load( const void* pBuffer, sal_uInt32 nBufSize, sal_uInt64 nUnderlyingStreamSize );
void Store( void* );
StgEntryType GetType() const { return (StgEntryType) cType; }
sal_Int32 GetStartPage() const { return nPage1; }