From 182bd71df302f768928357febab70bc6233761e6 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Fri, 18 Sep 2015 12:46:29 +0100 Subject: check stream status and string lengths (cherry picked from commit 7af19f45b35c428d3e06972806e5a05489f45955) if nSize was 1 with unicode encoding nSize would wrap around in lcl_getMaxSafeStrLen (cherry picked from commit f6368c29bdc3a9017bcae3f064d2cd8c7e37ed10) rework this so we don't read the string, backup and re-read the string again (cherry picked from commit 8523e57e427ef5b0b7f7067dcdd07f01176d2160) Change-Id: I99f3d4a2ec760228f485d01fce856deb9c068431 Reviewed-on: https://gerrit.libreoffice.org/18691 Reviewed-by: David Tardon Tested-by: David Tardon --- sd/source/filter/ppt/pptin.cxx | 3 +- sd/source/filter/ppt/propread.cxx | 78 +++++++++++++++++++-------------------- sd/source/filter/ppt/propread.hxx | 4 +- 3 files changed, 43 insertions(+), 42 deletions(-) (limited to 'sd/source/filter') diff --git a/sd/source/filter/ppt/pptin.cxx b/sd/source/filter/ppt/pptin.cxx index 27f483d3fa66..e50358922a5d 100644 --- a/sd/source/filter/ppt/pptin.cxx +++ b/sd/source/filter/ppt/pptin.cxx @@ -366,7 +366,8 @@ bool ImplSdPPTImport::Import() if ( pSection ) { Dictionary aDict; - if ( pSection->GetDictionary( aDict ) ) + pSection->GetDictionary(aDict); + if (!aDict.empty()) { Dictionary::const_iterator iter = aDict.find( OUString("_PID_HLINKS") ); diff --git a/sd/source/filter/ppt/propread.cxx b/sd/source/filter/ppt/propread.cxx index f73d26fbaa3f..11552d603e8b 100644 --- a/sd/source/filter/ppt/propread.cxx +++ b/sd/source/filter/ppt/propread.cxx @@ -269,10 +269,8 @@ void Section::AddProperty( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBu maEntries.push_back( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ) ); } -bool Section::GetDictionary( Dictionary& rDict ) +void Section::GetDictionary(Dictionary& rDict) { - bool bRetValue = false; - boost::ptr_vector::iterator iter; for (iter = maEntries.begin(); iter != maEntries.end(); ++iter) { @@ -280,48 +278,50 @@ bool Section::GetDictionary( Dictionary& rDict ) break; } - if ( iter != maEntries.end() ) + if (iter == maEntries.end()) + return; + + SvMemoryStream aStream( iter->mpBuf, iter->mnSize, STREAM_READ ); + aStream.Seek( STREAM_SEEK_TO_BEGIN ); + sal_uInt32 nDictCount(0); + aStream.ReadUInt32( nDictCount ); + for (sal_uInt32 i = 0; i < nDictCount; ++i) { - sal_uInt32 nDictCount, nId, nSize, nPos; - SvMemoryStream aStream( (sal_Int8*)iter->mpBuf, iter->mnSize, STREAM_READ ); - aStream.Seek( STREAM_SEEK_TO_BEGIN ); - aStream.ReadUInt32( nDictCount ); - for ( sal_uInt32 i = 0; i < nDictCount; i++ ) + sal_uInt32 nId(0), nSize(0); + aStream.ReadUInt32(nId).ReadUInt32(nSize); + if (!aStream.good() || nSize > aStream.remainingSize()) + break; + if (mnTextEnc == RTL_TEXTENCODING_UCS2) + nSize >>= 1; + if (!nSize) + continue; + OUString aString; + try { - aStream.ReadUInt32( nId ).ReadUInt32( nSize ); - if ( nSize ) + if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) { - OUString aString; - nPos = aStream.Tell(); - try - { - sal_Char* pString = new sal_Char[ nSize ]; - aStream.Read( pString, nSize ); - if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) - { - nSize >>= 1; - aStream.Seek( nPos ); - sal_Unicode* pWString = reinterpret_cast(pString); - for (sal_uInt32 j = 0; j < nSize; ++j) - aStream.ReadUInt16(pWString[j]); - aString = OUString(pWString, lcl_getMaxSafeStrLen(nSize)); - } - else - aString = OUString(pString, lcl_getMaxSafeStrLen(nSize), mnTextEnc); - delete[] pString; - } - catch( const std::bad_alloc& ) - { - OSL_FAIL( "sd Section::GetDictionary bad alloc" ); - } - if ( aString.isEmpty() ) - break; - rDict.insert( std::make_pair(aString,nId) ); + sal_Unicode* pWString = new sal_Unicode[nSize]; + for (sal_uInt32 j = 0; j < nSize; ++j) + aStream.ReadUInt16(pWString[j]); + aString = OUString(pWString, lcl_getMaxSafeStrLen(nSize)); + delete[] pWString; + } + else + { + sal_Char* pString = new sal_Char[nSize]; + aStream.Read(pString, nSize); + aString = OUString(pString, lcl_getMaxSafeStrLen(nSize), mnTextEnc); + delete[] pString; } - bRetValue = true; } + catch( const std::bad_alloc& ) + { + OSL_FAIL( "sd Section::GetDictionary bad alloc" ); + } + if (aString.isEmpty()) + break; + rDict.insert( std::make_pair(aString,nId) ); } - return bRetValue; } void Section::Read( SvStorageStream *pStrm ) diff --git a/sd/source/filter/ppt/propread.hxx b/sd/source/filter/ppt/propread.hxx index 7d2ea78f2581..92219d0e021d 100644 --- a/sd/source/filter/ppt/propread.hxx +++ b/sd/source/filter/ppt/propread.hxx @@ -145,8 +145,8 @@ class Section Section( const Section& rSection ); Section& operator=( const Section& rSection ); - bool GetProperty( sal_uInt32 nId, PropItem& rPropItem ); - bool GetDictionary( Dictionary& rDict ); + bool GetProperty( sal_uInt32 nId, PropItem& rPropItem ); + void GetDictionary( Dictionary& rDict ); const sal_uInt8* GetFMTID() const { return aFMTID; }; void Read( SvStorageStream* pStrm ); }; -- cgit v1.2.3