[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