summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Power <noel.power@novell.com>2011-08-19 12:31:03 +0100
committerNoel Power <noel.power@novell.com>2011-08-19 12:34:20 +0100
commit0531021de4a63879baa3de262d871a08712c4bed (patch)
treed56838e108f9da2f37f4cc7e19e8f1900734cd8d
parente138dc6704623e1acffa32dc8bb5afd93e8fb238 (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.cxx25
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;
}