[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-4.4' - cppcanvas/source vcl/source
Mike Kaganski
mike.kaganski at collabora.com
Mon Aug 31 12:37:24 PDT 2015
cppcanvas/source/mtfrenderer/emfplus.cxx | 37 ++++++++++++++++++++-----------
vcl/source/filter/wmf/enhwmf.cxx | 10 ++++----
2 files changed, 30 insertions(+), 17 deletions(-)
New commits:
commit a427022a74163ad8711c66ddd848211e87b05197
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date: Sat Aug 29 00:57:20 2015 +1000
bnc#930818: allow for EMF+ record padding up to 11 bytes
When an array of EMF+ has extra bytes in the end, that are less than 12,
they should not be treated as another EMF+ record, but simply ignored.
Conflicts:
cppcanvas/source/mtfrenderer/emfplus.cxx
Change-Id: I34701c00916812c8a6a4b69730f602da81719b35
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index c99d819..6a103c6 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -1112,31 +1112,35 @@ namespace cppcanvas
void Read (SvMemoryStream &s, sal_uInt32 dataSize, bool bUseWholeStream)
{
- sal_uInt32 header, unknown;
+ sal_uInt32 header, bitmapType;
s.ReadUInt32( header ).ReadUInt32( type );
SAL_INFO("cppcanvas.emf", "EMF+\timage\nEMF+\theader: 0x" << std::hex << header << " type: " << type << std::dec );
if (type == 1) { // bitmap
- s.ReadInt32( width ).ReadInt32( height ).ReadInt32( stride ).ReadInt32( pixelFormat ).ReadUInt32( unknown );
+ s.ReadInt32( width ).ReadInt32( height ).ReadInt32( stride ).ReadInt32( pixelFormat ).ReadUInt32( bitmapType );
SAL_INFO("cppcanvas.emf", "EMF+\tbitmap width: " << width << " height: " << height << " stride: " << stride << " pixelFormat: 0x" << std::hex << pixelFormat << std::dec);
- if (width == 0) { // non native formats
+ if ((bitmapType != 0) || (width == 0)) { // non native formats
GraphicFilter filter;
filter.ImportGraphic (graphic, OUString(), s);
SAL_INFO("cppcanvas.emf", "EMF+\tbitmap width: " << graphic.GetBitmap().GetSizePixel().Width() << " height: " << graphic.GetBitmap().GetSizePixel().Height());
}
- } else if (type == 2) {
+ } else if (type == 2) { // metafile
sal_Int32 mfType, mfSize;
s.ReadInt32( mfType ).ReadInt32( mfSize );
- SAL_INFO("cppcanvas.emf", "EMF+\tmetafile type: " << mfType << " dataSize: " << mfSize << " real size calculated from record dataSize: " << dataSize - 16);
+ if (bUseWholeStream)
+ dataSize = s.remainingSize();
+ else
+ dataSize -= 16;
+ SAL_INFO("cppcanvas.emf", "EMF+\tmetafile type: " << mfType << " dataSize: " << mfSize << " real size calculated from record dataSize: " << dataSize);
GraphicFilter filter;
// workaround buggy metafiles, which have wrong mfSize set (n#705956 for example)
- SvMemoryStream mfStream (((char *)s.GetData()) + s.Tell(), bUseWholeStream ? s.remainingSize() : dataSize - 16, STREAM_READ);
+ SvMemoryStream mfStream (const_cast<char *>(static_cast<char const *>(s.GetData()) + s.Tell()), dataSize, STREAM_READ);
filter.ImportGraphic (graphic, OUString(), mfStream);
@@ -1809,11 +1813,14 @@ namespace cppcanvas
OutDevState& rState, const CanvasSharedPtr& rCanvas )
{
sal_uInt32 length = pAct->GetDataSize ();
- SvMemoryStream rMF ((void*) pAct->GetData (), length, STREAM_READ);
+ SvMemoryStream rMF (const_cast<sal_uInt8 *>(pAct->GetData ()), length, STREAM_READ);
- length -= 4;
+ if (length < 12) {
+ SAL_INFO("cppcanvas.emf", "length is less than required header size");
+ }
- while (length > 0) {
+ // 12 is minimal valid EMF+ record size; remaining bytes are padding
+ while (length >= 12) {
sal_uInt16 type, flags;
sal_uInt32 size, dataSize;
sal_Size next;
@@ -1824,6 +1831,11 @@ namespace cppcanvas
if (size < 12) {
SAL_INFO("cppcanvas.emf", "Size field is less than 12 bytes");
+ } else if (size > length) {
+ SAL_INFO("cppcanvas.emf", "Size field is greater than bytes left");
+ }
+ if (dataSize > (size-12)) {
+ SAL_INFO("cppcanvas.emf", "DataSize field is greater than Size-12");
}
SAL_INFO("cppcanvas.emf", "EMF+ record size: " << size << " type: " << emfTypeToName(type) << " flags: " << flags << " data size: " << dataSize);
@@ -1835,14 +1847,15 @@ namespace cppcanvas
mMStream.Seek(0);
}
- // 1st 4 bytes are unknown
- mMStream.Write (((const char *)rMF.GetData()) + rMF.Tell() + 4, dataSize - 4);
+ OSL_ENSURE(dataSize >= 4, "No room for TotalObjectSize in EmfPlusContinuedObjectRecord");
+ // 1st 4 bytes are TotalObjectSize
+ mMStream.Write (static_cast<const char *>(rMF.GetData()) + rMF.Tell() + 4, dataSize - 4);
SAL_INFO("cppcanvas.emf", "EMF+ read next object part size: " << size << " type: " << type << " flags: " << flags << " data size: " << dataSize);
} else {
if (mbMultipart) {
SAL_INFO("cppcanvas.emf", "EMF+ multipart record flags: " << mMFlags);
mMStream.Seek (0);
- processObjectRecord (mMStream, mMFlags, dataSize, true);
+ processObjectRecord (mMStream, mMFlags, 0, true);
}
mbMultipart = false;
}
diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx
index 578fc0a..ca005e8 100644
--- a/vcl/source/filter/wmf/enhwmf.cxx
+++ b/vcl/source/filter/wmf/enhwmf.cxx
@@ -433,10 +433,8 @@ void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC)
bHaveDC = false;
- OSL_ASSERT(length >= 4);
- // reduce by 32bit length itself, skip in SeekRel if
- // impossibly unavailable
- sal_uInt32 nRemainder = length >= 4 ? length-4 : length;
+ // skip in SeekRel if impossibly unavailable
+ sal_uInt32 nRemainder = length;
const size_t nRequiredHeaderSize = 12;
while (nRemainder >= nRequiredHeaderSize)
@@ -682,7 +680,9 @@ bool EnhWMFReader::ReadEnhWMF()
// EMF+ comment (FIXME: BE?)
if( id == 0x2B464D45 && nRecSize >= 12 )
- ReadEMFPlusComment( length, bHaveDC );
+ // [MS-EMF] 2.3.3: DataSize includes both CommentIdentifier and CommentRecordParm fields.
+ // We have already read 4-byte CommentIdentifier, so reduce length appropriately
+ ReadEMFPlusComment( length-4, bHaveDC );
// GDIC comment, doesn't do anything useful yet
else if( id == 0x43494447 && nRecSize >= 12 ) {
// TODO: ReadGDIComment()
More information about the Libreoffice-commits
mailing list