diff options
author | Noel Power <noel.power@novell.com> | 2011-08-19 12:31:03 +0100 |
---|---|---|
committer | Noel Power <noel.power@novell.com> | 2011-08-19 12:34:20 +0100 |
commit | 0531021de4a63879baa3de262d871a08712c4bed (patch) | |
tree | d56838e108f9da2f37f4cc7e19e8f1900734cd8d | |
parent | e138dc6704623e1acffa32dc8bb5afd93e8fb238 (diff) |
tweak vba decompression as per frob's amazing bit detective work
ported a version of the patch at https://bugzilla.gnome.org/show_bug.cgi?id=656531 adjusted for libreoffice
-rw-r--r-- | oox/source/ole/vbainputstream.cxx | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/oox/source/ole/vbainputstream.cxx b/oox/source/ole/vbainputstream.cxx index 9926081f60b4..8b054ea707dc 100644 --- a/oox/source/ole/vbainputstream.cxx +++ b/oox/source/ole/vbainputstream.cxx @@ -128,21 +128,32 @@ void VbaInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) bool VbaInputStream::updateChunk() { if( mbEof || (mnChunkPos < maChunk.size()) ) return !mbEof; - // try to read next chunk header, this may trigger EOF sal_uInt16 nHeader = mpInStrm->readuInt16(); + mbEof = mpInStrm->isEof(); if( mbEof ) return false; // check header signature - OSL_ENSURE( (nHeader & VBACHUNK_SIGMASK) == VBACHUNK_SIG, "VbaInputStream::updateChunk - invalid chunk signature" ); - mbEof = (nHeader & VBACHUNK_SIGMASK) != VBACHUNK_SIG; - if( mbEof ) return false; + bool bIgnoreBrokenSig = !( (nHeader & VBACHUNK_SIGMASK) == VBACHUNK_SIG ); // decode length of chunk data and compression flag bool bCompressed = getFlag( nHeader, VBACHUNK_COMPRESSED ); sal_uInt16 nChunkLen = (nHeader & VBACHUNK_LENMASK) + 1; OSL_ENSURE( bCompressed || (nChunkLen == 4096), "VbaInputStream::updateChunk - invalid uncompressed chunk size" ); + + // From the amazing bit detective work of Valek Filippov<frob@gnome.org> + // this tweak and the one at the bottom of the method to seek to the + // start of the next chunk we can read those strange broken + // ( I guess from a MSO bug ) commpessed streams > 4k + + if ( bIgnoreBrokenSig || ( ! ( mpInStrm->getRemaining() < 4096 ) ) ) + { + bCompressed = true; + nChunkLen = 4094; + } + + sal_Int64 target = mpInStrm->tell() + nChunkLen; if( bCompressed ) { maChunk.clear(); @@ -183,6 +194,7 @@ bool VbaInputStream::updateChunk() } } } + // we suspect this will never be called else { maChunk.resize( maChunk.size() + 1 ); @@ -197,7 +209,10 @@ bool VbaInputStream::updateChunk() maChunk.resize( nChunkLen ); mpInStrm->readMemory( &maChunk.front(), nChunkLen ); } - + // decompression sometimes leaves the stream pos offset 1 place ( at + // least ) past or before the expected stream pos. + // here we make sure we are on the chunk boundry + mpInStrm->seek( target ); mnChunkPos = 0; return !mbEof; } |