Dmitry Timoshkov : gdi32: Perform consistency checks when loading an EMF, add a test case.

Alexandre Julliard julliard at wine.codeweavers.com
Tue May 29 08:05:25 CDT 2007


Module: wine
Branch: master
Commit: 6aa84e0eafe4464c3901fb81a1b55afcad97db99
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6aa84e0eafe4464c3901fb81a1b55afcad97db99

Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date:   Mon May 28 16:21:58 2007 +0900

gdi32: Perform consistency checks when loading an EMF, add a test case.

---

 dlls/gdi32/enhmetafile.c    |   40 +++++++++++++++++------------------
 dlls/gdi32/tests/metafile.c |   48 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 65 insertions(+), 23 deletions(-)

diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c
index c822b28..9e7684b 100644
--- a/dlls/gdi32/enhmetafile.c
+++ b/dlls/gdi32/enhmetafile.c
@@ -250,9 +250,20 @@ static inline BOOL is_dib_monochrome( const BITMAPINFO* info )
 HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk )
 {
     HENHMETAFILE hmf = 0;
-    ENHMETAFILEOBJ *metaObj = GDI_AllocObject( sizeof(ENHMETAFILEOBJ),
-                                               ENHMETAFILE_MAGIC,
-					       (HGDIOBJ *)&hmf, NULL );
+    ENHMETAFILEOBJ *metaObj;
+
+    if (emh->iType != EMR_HEADER || emh->dSignature != ENHMETA_SIGNATURE ||
+        (emh->nBytes & 3)) /* refuse to load unaligned EMF as Windows does */
+    {
+        WARN("Invalid emf header type 0x%08x sig 0x%08x.\n",
+             emh->iType, emh->dSignature);
+        SetLastError(ERROR_INVALID_DATA);
+        return 0;
+    }
+
+    metaObj = GDI_AllocObject( sizeof(ENHMETAFILEOBJ),
+                               ENHMETAFILE_MAGIC,
+                               (HGDIOBJ *)&hmf, NULL );
     if (metaObj)
     {
         metaObj->emh = emh;
@@ -304,6 +315,7 @@ static HENHMETAFILE EMF_GetEnhMetaFile( HANDLE hFile )
 {
     ENHMETAHEADER *emh;
     HANDLE hMapping;
+    HENHMETAFILE hemf;
 
     hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
     emh = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
@@ -311,24 +323,10 @@ static HENHMETAFILE EMF_GetEnhMetaFile( HANDLE hFile )
 
     if (!emh) return 0;
 
-    if (emh->iType != EMR_HEADER || emh->dSignature != ENHMETA_SIGNATURE) {
-        WARN("Invalid emf header type 0x%08x sig 0x%08x.\n",
-	     emh->iType, emh->dSignature);
-        goto err;
-    }
-
-    /* refuse to load unaligned EMF as Windows does */
-    if (emh->nBytes & 3)
-    {
-        WARN("Refusing to load unaligned EMF\n");
-        goto err;
-    }
-
-    return EMF_Create_HENHMETAFILE( emh, TRUE );
-
-err:
-    UnmapViewOfFile( emh );
-    return 0;
+    hemf = EMF_Create_HENHMETAFILE( emh, TRUE );
+    if (!hemf)
+        UnmapViewOfFile( emh );
+    return hemf;
 }
 
 
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index a1481c3..3cc27d6 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -1541,7 +1541,7 @@ static void test_gdiis(void)
     ok(!pGdiIsMetaPrintDC(hmfDC), "ismetaprint on metafile\n");
     ok(pGdiIsMetaFileDC(hmfDC), "ismetafile on metafile\n");
     ok(!pGdiIsPlayMetafileDC(hmfDC), "isplaymetafile on metafile\n");
-    DeleteObject(CloseMetaFile(hmfDC));
+    DeleteMetaFile(CloseMetaFile(hmfDC));
 
     /* try with an enhanced metafile */
     hdc = GetDC(NULL);
@@ -1554,10 +1554,53 @@ static void test_gdiis(void)
 
     hemf = CloseEnhMetaFile(hemfDC);
     ok(hemf != NULL, "failed to close EMF\n");
-    DeleteObject(hemf);
+    DeleteEnhMetaFile(hemf);
     ReleaseDC(NULL,hdc);
 }
 
+static void test_SetEnhMetaFileBits(void)
+{
+    BYTE data[256];
+    HENHMETAFILE hemf;
+    ENHMETAHEADER *emh;
+
+    memset(data, 0xAA, sizeof(data));
+    SetLastError(0xdeadbeef);
+    hemf = SetEnhMetaFileBits(sizeof(data), data);
+    ok(!hemf, "SetEnhMetaFileBits should fail\n");
+    ok(GetLastError() == ERROR_INVALID_DATA, "expected ERROR_INVALID_DATA, got %u\n", GetLastError());
+
+    emh = (ENHMETAHEADER *)data;
+    memset(emh, 0, sizeof(*emh));
+
+    emh->iType = EMR_HEADER;
+    emh->nSize = sizeof(*emh);
+    emh->dSignature = ENHMETA_SIGNATURE;
+    /* emh->nVersion  = 0x10000; XP doesn't care about version */
+    emh->nBytes = sizeof(*emh);
+    /* emh->nRecords = 1; XP doesn't care about records */
+    emh->nHandles = 1; /* XP refuses to load a EMF if nHandles == 0 */
+
+    SetLastError(0xdeadbeef);
+    hemf = SetEnhMetaFileBits(emh->nBytes, data);
+    ok(hemf != 0, "SetEnhMetaFileBits error %u\n", GetLastError());
+    DeleteEnhMetaFile(hemf);
+
+    /* XP refuses to load unaligned EMF */
+    emh->nBytes++;
+    SetLastError(0xdeadbeef);
+    hemf = SetEnhMetaFileBits(emh->nBytes, data);
+    ok(!hemf, "SetEnhMetaFileBits should fail\n");
+    /* XP doesn't set error in this case */
+
+    emh->dSignature = 0;
+    emh->nBytes--;
+    SetLastError(0xdeadbeef);
+    hemf = SetEnhMetaFileBits(emh->nBytes, data);
+    ok(!hemf, "SetEnhMetaFileBits should fail\n");
+    /* XP doesn't set error in this case */
+}
+
 START_TEST(metafile)
 {
     init_function_pointers();
@@ -1580,4 +1623,5 @@ START_TEST(metafile)
     test_SetWinMetaFileBits();
 
     test_gdiis();
+    test_SetEnhMetaFileBits();
 }




More information about the wine-cvs mailing list