filter/source/msfilter/svdfppt.cxx | 112 ++++++++++++++++++++++-------------- sd/qa/unit/data/ppt/pass/hang-2.ppt |binary sd/source/filter/ppt/propread.cxx | 6 + 3 files changed, 74 insertions(+), 44 deletions(-)
New commits: commit 0b0b2531fc56c7a58835c9242d16c64cce5a3dd2 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Aug 26 14:26:40 2015 +0100 various hangs, check seeks and record lengths Change-Id: Ided7f9376f41ee8cb1f6903e54a2d51e0e07e1a7 (cherry picked from commit a8b2dc80c41022515c3a1df6f7ea245c3390dc39) Reviewed-on: https://gerrit.libreoffice.org/18024 Reviewed-by: David Tardon <dtar...@redhat.com> Tested-by: David Tardon <dtar...@redhat.com> diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx index c9033c9..3f898b6 100644 --- a/filter/source/msfilter/svdfppt.cxx +++ b/filter/source/msfilter/svdfppt.cxx @@ -707,6 +707,21 @@ void SdrEscherImport::RecolorGraphic( SvStream& rSt, sal_uInt32 nRecLen, Graphic } } +namespace +{ + sal_uLong SanitizeEndPos(SvStream &rIn, sal_uLong nEndRecPos) + { + auto nStreamLen = rIn.Tell() + rIn.remainingSize(); + if (nEndRecPos > nStreamLen) + { + SAL_WARN("filter.ms", "Parsing error: " << nStreamLen << + " max end pos, but " << nEndRecPos << " claimed, truncating"); + nEndRecPos = nStreamLen; + } + return nEndRecPos; + } +} + /* ProcessObject is called from ImplSdPPTImport::ProcessObj to handle all application specific things, such as the import of text, animation effects, header footer and placeholder. @@ -732,7 +747,8 @@ SdrObject* SdrEscherImport::ProcessObj( SvStream& rSt, DffObjData& rObjData, voi { sal_Int16 nHeaderFooterInstance = -1; DffRecordHeader aClientDataHd; - while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < maShapeRecords.Current()->GetRecEndFilePos() ) ) + auto nEndRecPos = SanitizeEndPos(rSt, maShapeRecords.Current()->GetRecEndFilePos()); + while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nEndRecPos ) ) { ReadDffRecordHeader( rSt, aClientDataHd ); switch ( aClientDataHd.nRecType ) @@ -1353,9 +1369,8 @@ SdrPowerPointImport::SdrPowerPointImport( PowerPointImportParam& rParam, const O while( nCurrentEditAtomStrmPos ) { sal_uInt32 nPersistIncPos = aCurrentEditAtom.nOffsetPersistDirectory; - if ( nPersistIncPos ) + if (nPersistIncPos && rStCtrl.Seek(nPersistIncPos) == nPersistIncPos) { - rStCtrl.Seek( nPersistIncPos ); DffRecordHeader aPersistHd; ReadDffRecordHeader( rStCtrl, aPersistHd ); if ( aPersistHd.nRecType == PPT_PST_PersistPtrIncrementalBlock ) @@ -1785,8 +1800,10 @@ SdrObject* SdrPowerPointImport::ImportOLE( long nOLEId, if ( const_cast<SdrPowerPointImport*>(this)->maShapeRecords.SeekToContent( rStCtrl, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) { DffRecordHeader aPlaceHd; + + auto nEndRecPos = SanitizeEndPos(rStCtrl, const_cast<SdrPowerPointImport*>(this)->maShapeRecords.Current()->GetRecEndFilePos()); while ( ( rStCtrl.GetError() == 0 ) - && ( rStCtrl.Tell() < const_cast<SdrPowerPointImport*>(this)->maShapeRecords.Current()->GetRecEndFilePos() ) ) + && ( rStCtrl.Tell() < nEndRecPos ) ) { ReadDffRecordHeader( rStCtrl, aPlaceHd ); if ( aPlaceHd.nRecType == PPT_PST_RecolorInfoAtom ) @@ -2643,7 +2660,9 @@ void ImportComment10( SvxMSDffManager& rMan, SvStream& rStCtrl, SdrPage* pPage, sal_Int32 nPosX = 0; sal_Int32 nPosY = 0; - while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < rComment10Hd.GetRecEndFilePos() ) ) + + auto nEndRecPos = SanitizeEndPos(rStCtrl, rComment10Hd.GetRecEndFilePos()); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nEndRecPos ) ) { DffRecordHeader aCommentHd; ReadDffRecordHeader( rStCtrl, aCommentHd ); @@ -2718,7 +2737,8 @@ void SdrPowerPointImport::ImportPage( SdrPage* pRet, const PptSlidePersistEntry* { rSlidePersist.pHeaderFooterEntry = new HeaderFooterEntry( pMasterPersist ); ProcessData aProcessData( rSlidePersist, SdPageCapsule(pRet) ); - while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPageHd.GetRecEndFilePos() ) ) + auto nEndRecPos = SanitizeEndPos(rStCtrl, aPageHd.GetRecEndFilePos()); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nEndRecPos ) ) { DffRecordHeader aHd; ReadDffRecordHeader( rStCtrl, aHd ); @@ -2753,7 +2773,8 @@ void SdrPowerPointImport::ImportPage( SdrPage* pRet, const PptSlidePersistEntry* sal_uInt32 nPPDrawOfs = rStCtrl.Tell(); // importing the background object before importing the page - while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPPDrawHd.GetRecEndFilePos() ) ) + auto nPPEndRecPos = SanitizeEndPos(rStCtrl, aPPDrawHd.GetRecEndFilePos()); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nPPEndRecPos ) ) { DffRecordHeader aEscherObjListHd; ReadDffRecordHeader( rStCtrl, aEscherObjListHd ); @@ -2815,7 +2836,8 @@ void SdrPowerPointImport::ImportPage( SdrPage* pRet, const PptSlidePersistEntry* // now importing page rStCtrl.Seek( nPPDrawOfs ); - while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPPDrawHd.GetRecEndFilePos() ) ) + auto nHdEndRecPos = SanitizeEndPos(rStCtrl, aPPDrawHd.GetRecEndFilePos()); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nHdEndRecPos ) ) { DffRecordHeader aEscherObjListHd; ReadDffRecordHeader( rStCtrl, aEscherObjListHd ); @@ -2827,7 +2849,8 @@ void SdrPowerPointImport::ImportPage( SdrPage* pRet, const PptSlidePersistEntry* if ( SeekToRec( rStCtrl, DFF_msofbtSpContainer, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) ) { aShapeHd.SeekToEndOfRecord( rStCtrl ); - while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aEscherObjListHd.GetRecEndFilePos() ) ) + auto nListEndRecPos = SanitizeEndPos(rStCtrl, aEscherObjListHd.GetRecEndFilePos()); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nListEndRecPos ) ) { ReadDffRecordHeader( rStCtrl, aShapeHd ); if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) @@ -3071,7 +3094,8 @@ sal_uInt32 HeaderFooterEntry::NeedToImportInstance( const sal_uInt32 nInstance, void SdrEscherImport::ImportHeaderFooterContainer( DffRecordHeader& rHd, HeaderFooterEntry& rE ) { rHd.SeekToContent( rStCtrl ); - while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < rHd.GetRecEndFilePos() ) ) + auto nEndRecPos = SanitizeEndPos(rStCtrl, rHd.GetRecEndFilePos()); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nEndRecPos ) ) { DffRecordHeader aHd; ReadDffRecordHeader( rStCtrl, aHd ); @@ -3171,14 +3195,16 @@ PPTExtParaProv::PPTExtParaProv( SdrPowerPointImport& rMan, SvStream& rSt, const pListHd->SeekToContent( rSt ); if ( pListHd && SdrPowerPointImport::SeekToContentOfProgTag( 9, rSt, *pListHd, aContentDataHd ) ) { - while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aContentDataHd.GetRecEndFilePos() ) ) + auto nEndRecPos = SanitizeEndPos(rSt, aContentDataHd.GetRecEndFilePos()); + while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nEndRecPos ) ) { ReadDffRecordHeader( rSt, aHd ); switch ( aHd.nRecType ) { case PPT_PST_ExtendedBuGraContainer : { - while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aHd.GetRecEndFilePos() ) ) + auto nHdEndRecPos = SanitizeEndPos(rSt, aHd.GetRecEndFilePos()); + while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nHdEndRecPos ) ) { sal_uInt16 nType; DffRecordHeader aBuGraAtomHd; @@ -3249,7 +3275,8 @@ PPTExtParaProv::PPTExtParaProv( SdrPowerPointImport& rMan, SvStream& rSt, const if ( pHd && SdrPowerPointImport::SeekToContentOfProgTag( 9, rSt, *pHd, aContentDataHd ) ) { // get the extended paragraph styles on mainmaster ( graphical bullets, num ruling ... ) - while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aContentDataHd.GetRecEndFilePos() ) ) + auto nEndRecPos = SanitizeEndPos(rSt, aContentDataHd.GetRecEndFilePos()); + while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nEndRecPos ) ) { ReadDffRecordHeader( rSt, aHd ); switch ( aHd.nRecType ) @@ -3258,12 +3285,12 @@ PPTExtParaProv::PPTExtParaProv( SdrPowerPointImport& rMan, SvStream& rSt, const { if ( aHd.nRecInstance < PPT_STYLESHEETENTRYS ) { - sal_uInt16 nDepth, i = 0; + sal_uInt16 nDepth = 0, i = 0; rSt.ReadUInt16( nDepth ); if ( i <= 5 ) { - - while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aHd.GetRecEndFilePos() ) && ( i < nDepth ) ) + auto nHdEndRecPos = SanitizeEndPos(rSt, aHd.GetRecEndFilePos()); + while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nHdEndRecPos ) && ( i < nDepth ) ) { bStyles = true; ReadPPTExtParaLevel( rSt, aExtParaSheet[ aHd.nRecInstance ].aExtParaLevel[ i++ ] ); @@ -4024,7 +4051,8 @@ PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, Sd { pEnvHeader->SeekToContent( rIn ); DffRecordHeader aTxMasterStyleHd; - while ( rIn.Tell() < pEnvHeader->GetRecEndFilePos() ) + auto nEndRecPos = SanitizeEndPos(rIn, pEnvHeader->GetRecEndFilePos()); + while (rIn.Tell() < nEndRecPos) { ReadDffRecordHeader( rIn, aTxMasterStyleHd ); if ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom ) @@ -4035,7 +4063,8 @@ PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, Sd sal_uInt16 nLev = 0; bool bFirst = true; bFoundTxMasterStyleAtom04 = true; - while (rIn.GetError() == 0 && rIn.Tell() < aTxMasterStyleHd.GetRecEndFilePos() && nLev < nLevelAnz && nLev < nMaxPPTLevels) + auto nTxEndRecPos = SanitizeEndPos(rIn, aTxMasterStyleHd.GetRecEndFilePos()); + while (rIn.GetError() == 0 && rIn.Tell() < nTxEndRecPos && nLev < nLevelAnz && nLev < nMaxPPTLevels) { if ( nLev ) { @@ -4072,16 +4101,8 @@ PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, Sd rSlideHd.SeekToContent( rIn ); - auto nEndRecPos = rSlideHd.GetRecEndFilePos(); - auto nStreamLen = rIn.Tell() + rIn.remainingSize(); - if (nEndRecPos > nStreamLen) - { - SAL_WARN("filter.ms", "Parsing error: " << nStreamLen << - " max end pos, but " << nEndRecPos << " claimed, truncating"); - nEndRecPos = nStreamLen; - } - DffRecordHeader aTxMasterStyleHd; + auto nEndRecPos = SanitizeEndPos(rIn, rSlideHd.GetRecEndFilePos()); while (rIn.Tell() < nEndRecPos) { ReadDffRecordHeader( rIn, aTxMasterStyleHd ); @@ -4130,17 +4151,18 @@ PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, Sd break; } } - sal_uInt16 nLevelAnz; - rIn.ReadUInt16( nLevelAnz ); - if ( nLevelAnz > 5 ) + sal_uInt16 nLevelAnz(0); + rIn.ReadUInt16(nLevelAnz); + if (nLevelAnz > nMaxPPTLevels) { OSL_FAIL( "PPTStyleSheet::Ppt-TextStylesheet hat mehr als 5 Ebenen! (SJ)" ); - nLevelAnz = 5; + nLevelAnz = nMaxPPTLevels; } sal_uInt16 nLev = 0; bool bFirst = true; - while ( rIn.GetError() == 0 && rIn.Tell() < aTxMasterStyleHd.GetRecEndFilePos() && nLev < nLevelAnz ) + auto nTxEndRecPos = SanitizeEndPos(rIn, aTxMasterStyleHd.GetRecEndFilePos()); + while ( rIn.GetError() == 0 && rIn.Tell() < nTxEndRecPos && nLev < nLevelAnz ) { if ( nLev && ( nInstance < 5 ) ) { @@ -4219,7 +4241,8 @@ PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, Sd { pEnvHeader2->SeekToContent( rIn ); DffRecordHeader aTxMasterStyleHd2; - while ( rIn.Tell() < pEnvHeader2->GetRecEndFilePos() ) + auto nEnvEndRecPos = SanitizeEndPos(rIn, pEnvHeader2->GetRecEndFilePos()); + while (rIn.Tell() < nEnvEndRecPos) { ReadDffRecordHeader( rIn, aTxMasterStyleHd2 ); if ( aTxMasterStyleHd2.nRecType == PPT_PST_TxMasterStyleAtom ) @@ -4229,7 +4252,8 @@ PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, Sd sal_uInt16 nLev = 0; bool bFirst = true; - while ( rIn.GetError() == 0 && rIn.Tell() < aTxMasterStyleHd2.GetRecEndFilePos() && nLev < nLevelAnz ) + auto nTxEndRecPos = SanitizeEndPos(rIn, aTxMasterStyleHd2.GetRecEndFilePos()); + while ( rIn.GetError() == 0 && rIn.Tell() < nTxEndRecPos && nLev < nLevelAnz ) { if ( nLev ) { @@ -4746,17 +4770,18 @@ bool PPTTextSpecInfoAtomInterpreter::Read( SvStream& rIn, const DffRecordHeader& sal_uInt32 nCharIdx = 0; rRecHd.SeekToContent( rIn ); - while ( rIn.Tell() < rRecHd.GetRecEndFilePos() ) + auto nEndRecPos = SanitizeEndPos(rIn, rRecHd.GetRecEndFilePos()); + while (rIn.Tell() < nEndRecPos && rIn.good()) { - sal_uInt32 nCharCount, - nFlags, i; - if ( nRecordType == PPT_PST_TextSpecInfoAtom ) { + sal_uInt32 nCharCount(0); rIn.ReadUInt32( nCharCount ); nCharIdx += nCharCount; } - rIn.ReadUInt32( nFlags ); + + sal_uInt32 nFlags(0); + rIn.ReadUInt32(nFlags); PPTTextSpecInfo* pEntry = new PPTTextSpecInfo( nCharIdx ); if ( pTextSpecDefault ) @@ -4766,7 +4791,7 @@ bool PPTTextSpecInfoAtomInterpreter::Read( SvStream& rIn, const DffRecordHeader& pEntry->nLanguage[ 1 ] = pTextSpecDefault->nLanguage[ 1 ]; pEntry->nLanguage[ 2 ] = pTextSpecDefault->nLanguage[ 2 ]; } - for ( i = 1; nFlags && i ; i <<= 1 ) + for (sal_uInt32 i = 1; nFlags && i ; i <<= 1) { sal_uInt16 nLang = 0; switch( nFlags & i ) @@ -5092,7 +5117,9 @@ void PPTStyleTextPropReader::Init( SvStream& rIn, const DffRecordHeader& rTextHe if ( rExtParaHd.nRecType == PPT_PST_ExtendedParagraphAtom ) { rIn.Seek( rExtParaHd.nFilePos + 8 ); - while( ( rIn.GetError() == 0 ) && ( rIn.Tell() < rExtParaHd.GetRecEndFilePos() ) ) + + auto nEndRecPos = SanitizeEndPos(rIn, rExtParaHd.GetRecEndFilePos()); + while( ( rIn.GetError() == 0 ) && ( rIn.Tell() < nEndRecPos ) ) { aStyleTextProp9.resize( aStyleTextProp9.size() + 1 ); aStyleTextProp9.back().Read( rIn ); @@ -6616,7 +6643,8 @@ PPTTextObj::PPTTextObj( SvStream& rIn, SdrPowerPointImport& rSdrPowerPointImport // or ParaTabStops and append them on this textobj rIn.Seek( nFilePos ); ::std::vector< PPTFieldEntry* > FieldList; - while ( rIn.Tell() < aClientTextBoxHd.GetRecEndFilePos() ) + auto nEndRecPos = SanitizeEndPos(rIn, aClientTextBoxHd.GetRecEndFilePos()); + while (rIn.Tell() < nEndRecPos) { ReadDffRecordHeader( rIn, aTextHd ); sal_uInt16 nVal = 0; diff --git a/sd/qa/unit/data/ppt/pass/hang-2.ppt b/sd/qa/unit/data/ppt/pass/hang-2.ppt new file mode 100644 index 0000000..c6880b7 Binary files /dev/null and b/sd/qa/unit/data/ppt/pass/hang-2.ppt differ diff --git a/sd/source/filter/ppt/propread.cxx b/sd/source/filter/ppt/propread.cxx index e286422..374ecbb 100644 --- a/sd/source/filter/ppt/propread.cxx +++ b/sd/source/filter/ppt/propread.cxx @@ -306,7 +306,7 @@ bool Section::GetDictionary( Dictionary& rDict ) void Section::Read( SotStorageStream *pStrm ) { - sal_uInt32 i, nSecOfs, nSecSize, nPropCount, nPropId, nPropOfs, nPropType, nPropSize, nCurrent, nVectorCount, nTemp, nStrmSize; + sal_uInt32 i, nSecOfs, nPropType, nPropSize, nCurrent, nVectorCount, nTemp, nStrmSize; nSecOfs = pStrm->Tell(); pStrm->Seek( STREAM_SEEK_TO_END ); @@ -314,9 +314,11 @@ void Section::Read( SotStorageStream *pStrm ) pStrm->Seek( nSecOfs ); mnTextEnc = RTL_TEXTENCODING_MS_1252; + sal_uInt32 nSecSize(0), nPropCount(0); pStrm->ReadUInt32( nSecSize ).ReadUInt32( nPropCount ); - while( nPropCount-- && ( pStrm->GetError() == ERRCODE_NONE ) ) + while (nPropCount-- && pStrm->good()) { + sal_uInt32 nPropId(0), nPropOfs(0); pStrm->ReadUInt32( nPropId ).ReadUInt32( nPropOfs ); nCurrent = pStrm->Tell(); pStrm->Seek( nPropOfs + nSecOfs );
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits