summaryrefslogtreecommitdiff
path: root/filter/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-12-22 10:27:38 +0000
committerCaolán McNamara <caolanm@redhat.com>2020-12-22 13:57:43 +0100
commite7c76d604a4694e6568bf10c2a06a786f1096319 (patch)
treee775fc8f819f9e00139c5279976b5199c6bc6c9d /filter/source
parent901e5e7c9170184e286ea3e46fce406136aa9572 (diff)
oss-fuzz: epsfuzzer doesn't pass sanity check
Step #5: #6 0x640b42f in __cxa_throw (/tmp/not-out/epsfuzzer+0x640b42f) Step #5: #7 0x5413d9 in SvStream::ReadUInt32(unsigned int&) (/tmp/not-out/epsfuzzer+0x5413d9) Step #5: #8 0x1dd29b1 in ipsGraphicImport (/tmp/not-out/epsfuzzer+0x1dd29b1) Change-Id: Ieab45edabd5f13d07359be558618ff65badfde2e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108156 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'filter/source')
-rw-r--r--filter/source/graphicfilter/ieps/ieps.cxx355
1 files changed, 183 insertions, 172 deletions
diff --git a/filter/source/graphicfilter/ieps/ieps.cxx b/filter/source/graphicfilter/ieps/ieps.cxx
index 4bb06962ed0d..e5753510bbd9 100644
--- a/filter/source/graphicfilter/ieps/ieps.cxx
+++ b/filter/source/graphicfilter/ieps/ieps.cxx
@@ -592,227 +592,238 @@ ipsGraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
sal_uInt32 nPosWMF = 0;
sal_uInt32 nSizeTIFF = 0;
sal_uInt32 nPosTIFF = 0;
- sal_uInt32 nOrigPos = nPSStreamPos = rStream.Tell();
+
+ auto nOrigPos = nPSStreamPos = rStream.Tell();
SvStreamEndian nOldFormat = rStream.GetEndian();
- rStream.SetEndian( SvStreamEndian::LITTLE );
- rStream.ReadUInt32( nSignature );
- if ( nSignature == 0xc6d3d0c5 )
+
+ try
{
- rStream.ReadUInt32( nPSStreamPos ).ReadUInt32( nPSSize ).ReadUInt32( nPosWMF ).ReadUInt32( nSizeWMF );
+ rStream.SetEndian( SvStreamEndian::LITTLE );
+ rStream.ReadUInt32( nSignature );
+ if ( nSignature == 0xc6d3d0c5 )
+ {
+ rStream.ReadUInt32( nPSStreamPos ).ReadUInt32( nPSSize ).ReadUInt32( nPosWMF ).ReadUInt32( nSizeWMF );
- // first we try to get the metafile grafix
+ // first we try to get the metafile grafix
- if ( nSizeWMF )
- {
- if (nPosWMF && checkSeek(rStream, nOrigPos + nPosWMF))
+ if ( nSizeWMF )
{
- if (GraphicConverter::Import(rStream, aGraphic, ConvertDataFormat::WMF) == ERRCODE_NONE)
- bHasPreview = bRetValue = true;
+ if (nPosWMF && checkSeek(rStream, nOrigPos + nPosWMF))
+ {
+ if (GraphicConverter::Import(rStream, aGraphic, ConvertDataFormat::WMF) == ERRCODE_NONE)
+ bHasPreview = bRetValue = true;
+ }
}
- }
- else
- {
- rStream.ReadUInt32( nPosTIFF ).ReadUInt32( nSizeTIFF );
+ else
+ {
+ rStream.ReadUInt32( nPosTIFF ).ReadUInt32( nSizeTIFF );
- // else we have to get the tiff grafix
+ // else we have to get the tiff grafix
- if (nPosTIFF && nSizeTIFF && checkSeek(rStream, nOrigPos + nPosTIFF))
- {
- if ( GraphicConverter::Import( rStream, aGraphic, ConvertDataFormat::TIF ) == ERRCODE_NONE )
+ if (nPosTIFF && nSizeTIFF && checkSeek(rStream, nOrigPos + nPosTIFF))
{
- MakeAsMeta(aGraphic);
- rStream.Seek( nOrigPos + nPosTIFF );
- bHasPreview = bRetValue = true;
+ if ( GraphicConverter::Import( rStream, aGraphic, ConvertDataFormat::TIF ) == ERRCODE_NONE )
+ {
+ MakeAsMeta(aGraphic);
+ rStream.Seek( nOrigPos + nPosTIFF );
+ bHasPreview = bRetValue = true;
+ }
}
}
}
- }
- else
- {
- nPSStreamPos = nOrigPos; // no preview available _>so we must get the size manually
- nPSSize = rStream.Seek( STREAM_SEEK_TO_END ) - nOrigPos;
- }
-
- std::unique_ptr<sal_uInt8[]> pHeader( new sal_uInt8[ 22 ] );
- rStream.Seek( nPSStreamPos );
- rStream.ReadBytes(pHeader.get(), 22); // check PostScript header
- bool bOk = ImplSearchEntry(pHeader.get(), reinterpret_cast<sal_uInt8 const *>("%!PS-Adobe"), 10, 10) &&
- ImplSearchEntry(&pHeader[ 15 ], reinterpret_cast<sal_uInt8 const *>("EPS"), 3, 3);
- if (bOk)
- {
- rStream.Seek(nPSStreamPos);
- bOk = rStream.remainingSize() >= nPSSize;
- SAL_WARN_IF(!bOk, "filter.eps", "eps claims to be: " << nPSSize << " in size, but only " << rStream.remainingSize() << " remains");
- }
- if (bOk)
- {
- std::unique_ptr<sal_uInt8[]> pBuf( new sal_uInt8[ nPSSize ] );
+ else
+ {
+ nPSStreamPos = nOrigPos; // no preview available _>so we must get the size manually
+ nPSSize = rStream.Seek( STREAM_SEEK_TO_END ) - nOrigPos;
+ }
- sal_uInt32 nBufStartPos = rStream.Tell();
- sal_uInt32 nBytesRead = rStream.ReadBytes(pBuf.get(), nPSSize);
- if ( nBytesRead == nPSSize )
+ std::unique_ptr<sal_uInt8[]> pHeader( new sal_uInt8[ 22 ] );
+ rStream.Seek( nPSStreamPos );
+ rStream.ReadBytes(pHeader.get(), 22); // check PostScript header
+ bool bOk = ImplSearchEntry(pHeader.get(), reinterpret_cast<sal_uInt8 const *>("%!PS-Adobe"), 10, 10) &&
+ ImplSearchEntry(&pHeader[ 15 ], reinterpret_cast<sal_uInt8 const *>("EPS"), 3, 3);
+ if (bOk)
{
- sal_uInt32 nSecurityCount = 32;
- // if there is no tiff/wmf preview, we will parse for a preview in
- // the eps prolog
- if (!bHasPreview && nBytesRead >= nSecurityCount)
+ rStream.Seek(nPSStreamPos);
+ bOk = rStream.remainingSize() >= nPSSize;
+ SAL_WARN_IF(!bOk, "filter.eps", "eps claims to be: " << nPSSize << " in size, but only " << rStream.remainingSize() << " remains");
+ }
+ if (bOk)
+ {
+ std::unique_ptr<sal_uInt8[]> pBuf( new sal_uInt8[ nPSSize ] );
+
+ sal_uInt32 nBufStartPos = rStream.Tell();
+ sal_uInt32 nBytesRead = rStream.ReadBytes(pBuf.get(), nPSSize);
+ if ( nBytesRead == nPSSize )
{
- sal_uInt8* pDest = ImplSearchEntry( pBuf.get(), reinterpret_cast<sal_uInt8 const *>("%%BeginPreview:"), nBytesRead - nSecurityCount, 15 );
- sal_uInt32 nRemainingBytes = pDest ? (nBytesRead - (pDest - pBuf.get())) : 0;
- if (nRemainingBytes >= 15)
+ sal_uInt32 nSecurityCount = 32;
+ // if there is no tiff/wmf preview, we will parse for a preview in
+ // the eps prolog
+ if (!bHasPreview && nBytesRead >= nSecurityCount)
{
- pDest += 15;
- nSecurityCount = nRemainingBytes - 15;
- tools::Long nWidth = ImplGetNumber(pDest, nSecurityCount);
- tools::Long nHeight = ImplGetNumber(pDest, nSecurityCount);
- tools::Long nBitDepth = ImplGetNumber(pDest, nSecurityCount);
- tools::Long nScanLines = ImplGetNumber(pDest, nSecurityCount);
- pDest = ImplSearchEntry(pDest, reinterpret_cast<sal_uInt8 const *>("%"), nSecurityCount, 1); // go to the first Scanline
- bOk = pDest && nWidth > 0 && nHeight > 0 && ( ( nBitDepth == 1 ) || ( nBitDepth == 8 ) ) && nScanLines;
- if (bOk)
+ sal_uInt8* pDest = ImplSearchEntry( pBuf.get(), reinterpret_cast<sal_uInt8 const *>("%%BeginPreview:"), nBytesRead - nSecurityCount, 15 );
+ sal_uInt32 nRemainingBytes = pDest ? (nBytesRead - (pDest - pBuf.get())) : 0;
+ if (nRemainingBytes >= 15)
{
- tools::Long nResult;
- bOk = !o3tl::checked_multiply(nWidth, nHeight, nResult) && nResult <= SAL_MAX_INT32/2/3;
- }
- if (bOk)
- {
- rStream.Seek( nBufStartPos + ( pDest - pBuf.get() ) );
-
- vcl::bitmap::RawBitmap aBitmap( Size( nWidth, nHeight ), 24 );
+ pDest += 15;
+ nSecurityCount = nRemainingBytes - 15;
+ tools::Long nWidth = ImplGetNumber(pDest, nSecurityCount);
+ tools::Long nHeight = ImplGetNumber(pDest, nSecurityCount);
+ tools::Long nBitDepth = ImplGetNumber(pDest, nSecurityCount);
+ tools::Long nScanLines = ImplGetNumber(pDest, nSecurityCount);
+ pDest = ImplSearchEntry(pDest, reinterpret_cast<sal_uInt8 const *>("%"), nSecurityCount, 1); // go to the first Scanline
+ bOk = pDest && nWidth > 0 && nHeight > 0 && ( ( nBitDepth == 1 ) || ( nBitDepth == 8 ) ) && nScanLines;
+ if (bOk)
{
- bool bIsValid = true;
- sal_uInt8 nDat = 0;
- char nByte;
- for (tools::Long y = 0; bIsValid && y < nHeight; ++y)
+ tools::Long nResult;
+ bOk = !o3tl::checked_multiply(nWidth, nHeight, nResult) && nResult <= SAL_MAX_INT32/2/3;
+ }
+ if (bOk)
+ {
+ rStream.Seek( nBufStartPos + ( pDest - pBuf.get() ) );
+
+ vcl::bitmap::RawBitmap aBitmap( Size( nWidth, nHeight ), 24 );
{
- int nBitsLeft = 0;
- for (tools::Long x = 0; x < nWidth; ++x)
+ bool bIsValid = true;
+ sal_uInt8 nDat = 0;
+ char nByte;
+ for (tools::Long y = 0; bIsValid && y < nHeight; ++y)
{
- if ( --nBitsLeft < 0 )
+ int nBitsLeft = 0;
+ for (tools::Long x = 0; x < nWidth; ++x)
{
- while ( bIsValid && ( nBitsLeft != 7 ) )
+ if ( --nBitsLeft < 0 )
{
- rStream.ReadChar(nByte);
- bIsValid = rStream.good();
- if (!bIsValid)
- break;
- switch (nByte)
+ while ( bIsValid && ( nBitsLeft != 7 ) )
{
- case 0x0a :
- if ( --nScanLines < 0 )
- bIsValid = false;
+ rStream.ReadChar(nByte);
+ bIsValid = rStream.good();
+ if (!bIsValid)
break;
- case 0x09 :
- case 0x0d :
- case 0x20 :
- case 0x25 :
- break;
- default:
+ switch (nByte)
{
- if ( nByte >= '0' )
+ case 0x0a :
+ if ( --nScanLines < 0 )
+ bIsValid = false;
+ break;
+ case 0x09 :
+ case 0x0d :
+ case 0x20 :
+ case 0x25 :
+ break;
+ default:
{
- if ( nByte > '9' )
+ if ( nByte >= '0' )
{
- nByte &=~0x20; // case none sensitive for hexadecimal values
- nByte -= ( 'A' - 10 );
- if ( nByte > 15 )
- bIsValid = false;
+ if ( nByte > '9' )
+ {
+ nByte &=~0x20; // case none sensitive for hexadecimal values
+ nByte -= ( 'A' - 10 );
+ if ( nByte > 15 )
+ bIsValid = false;
+ }
+ else
+ nByte -= '0';
+ nBitsLeft += 4;
+ nDat <<= 4;
+ nDat |= ( nByte ^ 0xf ); // in epsi a zero bit represents white color
}
else
- nByte -= '0';
- nBitsLeft += 4;
- nDat <<= 4;
- nDat |= ( nByte ^ 0xf ); // in epsi a zero bit represents white color
+ bIsValid = false;
}
- else
- bIsValid = false;
+ break;
}
- break;
}
}
- }
- if (!bIsValid)
- break;
- if ( nBitDepth == 1 )
- aBitmap.SetPixel( y, x, Color(static_cast<sal_uInt8>(nDat >> nBitsLeft) & 1) );
- else
- {
- aBitmap.SetPixel( y, x, nDat ? COL_WHITE : COL_BLACK ); // nBitDepth == 8
- nBitsLeft = 0;
+ if (!bIsValid)
+ break;
+ if ( nBitDepth == 1 )
+ aBitmap.SetPixel( y, x, Color(static_cast<sal_uInt8>(nDat >> nBitsLeft) & 1) );
+ else
+ {
+ aBitmap.SetPixel( y, x, nDat ? COL_WHITE : COL_BLACK ); // nBitDepth == 8
+ nBitsLeft = 0;
+ }
}
}
- }
- if (bIsValid)
- {
- ScopedVclPtrInstance<VirtualDevice> pVDev;
- GDIMetaFile aMtf;
- Size aSize( nWidth, nHeight );
- pVDev->EnableOutput( false );
- aMtf.Record( pVDev );
- aSize = OutputDevice::LogicToLogic(aSize, MapMode(), MapMode(MapUnit::Map100thMM));
- pVDev->DrawBitmapEx( Point(), aSize, vcl::bitmap::CreateFromData(std::move(aBitmap)) );
- aMtf.Stop();
- aMtf.WindStart();
- aMtf.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
- aMtf.SetPrefSize( aSize );
- aGraphic = aMtf;
- bHasPreview = bRetValue = true;
+ if (bIsValid)
+ {
+ ScopedVclPtrInstance<VirtualDevice> pVDev;
+ GDIMetaFile aMtf;
+ Size aSize( nWidth, nHeight );
+ pVDev->EnableOutput( false );
+ aMtf.Record( pVDev );
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(), MapMode(MapUnit::Map100thMM));
+ pVDev->DrawBitmapEx( Point(), aSize, vcl::bitmap::CreateFromData(std::move(aBitmap)) );
+ aMtf.Stop();
+ aMtf.WindStart();
+ aMtf.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
+ aMtf.SetPrefSize( aSize );
+ aGraphic = aMtf;
+ bHasPreview = bRetValue = true;
+ }
}
}
}
}
- }
- sal_uInt8* pDest = ImplSearchEntry( pBuf.get(), reinterpret_cast<sal_uInt8 const *>("%%BoundingBox:"), nBytesRead, 14 );
- sal_uInt32 nRemainingBytes = pDest ? (nBytesRead - (pDest - pBuf.get())) : 0;
- if (nRemainingBytes >= 14)
- {
- pDest += 14;
- nSecurityCount = std::min<sal_uInt32>(nRemainingBytes - 14, 100);
- tools::Long nNumb[4];
- nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
- for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
- {
- nNumb[ i ] = ImplGetNumber(pDest, nSecurityCount);
- }
- bool bFail = nSecurityCount == 0;
- tools::Long nWidth(0), nHeight(0);
- if (!bFail)
- bFail = o3tl::checked_sub(nNumb[2], nNumb[0], nWidth) || o3tl::checked_add(nWidth, tools::Long(1), nWidth);
- if (!bFail)
- bFail = o3tl::checked_sub(nNumb[3], nNumb[1], nHeight) || o3tl::checked_add(nHeight, tools::Long(1), nHeight);
- if (!bFail && nWidth > 0 && nHeight > 0)
+ sal_uInt8* pDest = ImplSearchEntry( pBuf.get(), reinterpret_cast<sal_uInt8 const *>("%%BoundingBox:"), nBytesRead, 14 );
+ sal_uInt32 nRemainingBytes = pDest ? (nBytesRead - (pDest - pBuf.get())) : 0;
+ if (nRemainingBytes >= 14)
{
- GDIMetaFile aMtf;
-
- // if there is no preview -> try with gs to make one
- if (!bHasPreview && !utl::ConfigManager::IsFuzzing())
+ pDest += 14;
+ nSecurityCount = std::min<sal_uInt32>(nRemainingBytes - 14, 100);
+ tools::Long nNumb[4];
+ nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
+ for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
{
- bHasPreview = RenderAsEMF(pBuf.get(), nBytesRead, aGraphic);
- if (!bHasPreview)
- bHasPreview = RenderAsBMP(pBuf.get(), nBytesRead, aGraphic);
+ nNumb[ i ] = ImplGetNumber(pDest, nSecurityCount);
}
-
- // if there is no preview -> make a red box
- if( !bHasPreview )
+ bool bFail = nSecurityCount == 0;
+ tools::Long nWidth(0), nHeight(0);
+ if (!bFail)
+ bFail = o3tl::checked_sub(nNumb[2], nNumb[0], nWidth) || o3tl::checked_add(nWidth, tools::Long(1), nWidth);
+ if (!bFail)
+ bFail = o3tl::checked_sub(nNumb[3], nNumb[1], nHeight) || o3tl::checked_add(nHeight, tools::Long(1), nHeight);
+ if (!bFail && nWidth > 0 && nHeight > 0)
{
- MakePreview(pBuf.get(), nBytesRead, nWidth, nHeight,
- aGraphic);
- }
+ GDIMetaFile aMtf;
+
+ // if there is no preview -> try with gs to make one
+ if (!bHasPreview && !utl::ConfigManager::IsFuzzing())
+ {
+ bHasPreview = RenderAsEMF(pBuf.get(), nBytesRead, aGraphic);
+ if (!bHasPreview)
+ bHasPreview = RenderAsBMP(pBuf.get(), nBytesRead, aGraphic);
+ }
- GfxLink aGfxLink( std::move(pBuf), nPSSize, GfxLinkType::EpsBuffer ) ;
- aMtf.AddAction( static_cast<MetaAction*>( new MetaEPSAction( Point(), Size( nWidth, nHeight ),
- aGfxLink, aGraphic.GetGDIMetaFile() ) ) );
- CreateMtfReplacementAction( aMtf, rStream, nOrigPos, nPSSize, nPosWMF, nSizeWMF, nPosTIFF, nSizeTIFF );
- aMtf.WindStart();
- aMtf.SetPrefMapMode(MapMode(MapUnit::MapPoint));
- aMtf.SetPrefSize( Size( nWidth, nHeight ) );
- rGraphic = aMtf;
- bRetValue = true;
+ // if there is no preview -> make a red box
+ if( !bHasPreview )
+ {
+ MakePreview(pBuf.get(), nBytesRead, nWidth, nHeight,
+ aGraphic);
+ }
+
+ GfxLink aGfxLink( std::move(pBuf), nPSSize, GfxLinkType::EpsBuffer ) ;
+ aMtf.AddAction( static_cast<MetaAction*>( new MetaEPSAction( Point(), Size( nWidth, nHeight ),
+ aGfxLink, aGraphic.GetGDIMetaFile() ) ) );
+ CreateMtfReplacementAction( aMtf, rStream, nOrigPos, nPSSize, nPosWMF, nSizeWMF, nPosTIFF, nSizeTIFF );
+ aMtf.WindStart();
+ aMtf.SetPrefMapMode(MapMode(MapUnit::MapPoint));
+ aMtf.SetPrefSize( Size( nWidth, nHeight ) );
+ rGraphic = aMtf;
+ bRetValue = true;
+ }
}
}
}
}
+ catch (const SvStreamEOFException&)
+ {
+ SAL_WARN("filter.eps", "EOF");
+ bRetValue = false;
+ }
+
rStream.SetEndian(nOldFormat);
rStream.Seek( nOrigPos );
return bRetValue;