filter,sc: try to prevent potential SeekToEndOfRecord infinite loops

SeekToEndOfRecord() now doesn't seek to EOF if the offset is too large;
break out of loops in the obvious cases where this could be problematic.

But don't use SAL_WARN_UNUSED_RESULT because unfortunately GCC doesn't
allow to explicitly suppress that with a (void) cast.

Change-Id: Ie0211075bf0f4ef271bb26bdfead5fb070875a2b
This commit is contained in:
Michael Stahl 2017-09-20 12:36:41 +02:00
parent dc97ede7cf
commit adbf0374e9
4 changed files with 45 additions and 24 deletions

View file

@ -3210,7 +3210,11 @@ bool SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, sal_u
if (!ReadDffRecordHeader(rSt, aEscherObjListHd))
break;
if ( aEscherObjListHd.nRecVer != 0xf )
aEscherObjListHd.SeekToEndOfRecord( rSt );
{
bool bSeekSuccess = aEscherObjListHd.SeekToEndOfRecord(rSt);
if (!bSeekSuccess)
break;
}
else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
{
DffRecordHeader aShapeHd;
@ -3225,7 +3229,9 @@ bool SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, sal_u
break;
}
}
aEscherObjListHd.SeekToEndOfRecord( rSt );
bool bSeekSuccess = aEscherObjListHd.SeekToEndOfRecord(rSt);
if (!bSeekSuccess)
break;
}
}
}
@ -3596,7 +3602,9 @@ void SvxMSDffManager::ReadObjText( SvStream& rStream, SdrObject* pObj )
default:
break;
}
aHd.SeekToEndOfRecord( rStream );
bool bSeekSuccess = aHd.SeekToEndOfRecord(rStream);
if (!bSeekSuccess)
break;
}
}
}
@ -3782,9 +3790,12 @@ SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, cons
Still no luck, lets look at the end of this record for a FBSE pool,
this fallback is a specific case for how word does it sometimes
*/
rObjData.rSpHd.SeekToEndOfRecord( rSt );
bool bOk = rObjData.rSpHd.SeekToEndOfRecord( rSt );
DffRecordHeader aHd;
bool bOk = ReadDffRecordHeader(rSt, aHd);
if (bOk)
{
bOk = ReadDffRecordHeader(rSt, aHd);
}
if (bOk && DFF_msofbtBSE == aHd.nRecType)
{
const sal_uLong nSkipBLIPLen = 20;

View file

@ -559,7 +559,7 @@ bool SdrEscherImport::ReadString( OUString& rStr ) const
bRet = true;
sal_uLong nBytes = aStrHd.nRecLen;
rStr = MSDFFReadZString( rStCtrl, nBytes, bUniCode );
aStrHd.SeekToEndOfRecord( rStCtrl );
bRet = aStrHd.SeekToEndOfRecord( rStCtrl );
}
else
aStrHd.SeekToBegOfRecord( rStCtrl );
@ -2393,7 +2393,10 @@ bool SdrPowerPointImport::SeekToContentOfProgTag( sal_Int32 nVersion, SvStream&
sal_Int32 nV = aSuf.toInt32();
if ( ( nV == nVersion ) && ( aPre == "___PPT" ) )
{
rContentHd.SeekToEndOfRecord( rSt );
if (!rContentHd.SeekToEndOfRecord(rSt))
{
break;
}
ReadDffRecordHeader( rSt, rContentHd );
if ( rContentHd.nRecType == PPT_PST_BinaryTagData )
{
@ -2857,7 +2860,10 @@ void SdrPowerPointImport::ImportPage( SdrPage* pRet, const PptSlidePersistEntry*
DffRecordHeader aShapeHd;
if ( SeekToRec( rStCtrl, DFF_msofbtSpContainer, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
{
aShapeHd.SeekToEndOfRecord( rStCtrl );
if (!aShapeHd.SeekToEndOfRecord(rStCtrl))
{
break;
}
auto nListEndRecPos = SanitizeEndPos(rStCtrl, aEscherObjListHd.GetRecEndFilePos());
while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nListEndRecPos ) )
{
@ -6875,7 +6881,10 @@ PPTTextObj::PPTTextObj( SvStream& rIn, SdrPowerPointImport& rSdrPowerPointImport
{
if ( pHyperlink->nIndex == aInteractiveInfoAtom.nExHyperlinkId )
{
aTextHd.SeekToEndOfRecord( rIn );
if (!aTextHd.SeekToEndOfRecord(rIn))
{
break;
}
ReadDffRecordHeader( rIn, aTextHd );
if ( aTextHd.nRecType != PPT_PST_TxInteractiveInfoAtom )
{

View file

@ -3681,7 +3681,7 @@ OUString XclImpDffConverter::ReadHlinkProperty( SvStream& rDffStrm ) const
return aString;
}
void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader )
bool XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader )
{
std::size_t nEndPos = rDgHeader.GetRecEndFilePos();
bool isBreak(false);
@ -3692,26 +3692,27 @@ void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecord
switch( aHeader.nRecType )
{
case DFF_msofbtSolverContainer:
ProcessSolverContainer( rDffStrm, aHeader );
isBreak = !ProcessSolverContainer( rDffStrm, aHeader );
break;
case DFF_msofbtSpgrContainer:
ProcessShGrContainer( rDffStrm, aHeader );
isBreak = !ProcessShGrContainer( rDffStrm, aHeader );
break;
default:
isBreak = !aHeader.SeekToEndOfRecord( rDffStrm );
}
}
// seek to end of drawing page container
rDgHeader.SeekToEndOfRecord( rDffStrm );
isBreak = !rDgHeader.SeekToEndOfRecord( rDffStrm );
// #i12638# #i37900# connector rules
XclImpSolverContainer& rSolverCont = GetConvData().maSolverCont;
rSolverCont.UpdateConnectorRules();
SolveSolver( rSolverCont );
rSolverCont.RemoveConnectorRules();
return !isBreak;
}
void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader )
bool XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader )
{
std::size_t nEndPos = rShGrHeader.GetRecEndFilePos();
bool isBreak(false);
@ -3723,27 +3724,27 @@ void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffReco
{
case DFF_msofbtSpgrContainer:
case DFF_msofbtSpContainer:
ProcessShContainer( rDffStrm, aHeader );
isBreak = !ProcessShContainer( rDffStrm, aHeader );
break;
default:
isBreak = !aHeader.SeekToEndOfRecord( rDffStrm );
}
}
// seek to end of shape group container
rShGrHeader.SeekToEndOfRecord( rDffStrm );
return rShGrHeader.SeekToEndOfRecord( rDffStrm ) && !isBreak;
}
void XclImpDffConverter::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader )
bool XclImpDffConverter::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader )
{
// solver container wants to read the solver container header again
rSolverHeader.SeekToBegOfRecord( rDffStrm );
// read the entire solver container
ReadSvxMSDffSolverContainer( rDffStrm, GetConvData().maSolverCont );
// seek to end of solver container
rSolverHeader.SeekToEndOfRecord( rDffStrm );
return rSolverHeader.SeekToEndOfRecord( rDffStrm );
}
void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader )
bool XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader )
{
rShHeader.SeekToBegOfRecord( rDffStrm );
tools::Rectangle aDummy;
@ -3757,7 +3758,7 @@ void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecord
SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy ) );
if( pDrawObj && xSdrObj )
InsertSdrObject( GetConvData().mrSdrPage, *pDrawObj, xSdrObj.release() );
rShHeader.SeekToEndOfRecord( rDffStrm );
return rShHeader.SeekToEndOfRecord( rDffStrm );
}
void XclImpDffConverter::InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj )

View file

@ -1023,13 +1023,13 @@ private:
OUString ReadHlinkProperty( SvStream& rDffStrm ) const;
/** Processes a drawing container (all drawing data of a sheet). */
void ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader );
bool ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader );
/** Processes the global shape group container (all shapes of a sheet). */
void ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader );
bool ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader );
/** Processes the solver container (connectors of a sheet). */
void ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader );
bool ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader );
/** Processes a shape or shape group container (one top-level shape). */
void ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader );
bool ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader );
/** Inserts the passed SdrObject into the document. This function takes ownership of pSdrObj! */
void InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj );