[PATCH] gdi32: Do not crash when calling ModifyWorldTransform() with a NULL xform parameter.

Zhiyi Zhang zzhang at codeweavers.com
Mon Mar 29 22:30:36 CDT 2021


EMFDRV_ModifyWorldTransform() does direct struct copy through pointer dereference. And, when the
mode parameter is MWT_IDENTITY, the xform parameter can be NULL because it should be ignored and
use the identity matrix.

Fix Tally crashing when exporting a JPEG image.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/gdi32/mapping.c        |  9 +++------
 dlls/gdi32/tests/metafile.c | 15 +++++++++++++++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/dlls/gdi32/mapping.c b/dlls/gdi32/mapping.c
index 83582846486..a0feee0abb1 100644
--- a/dlls/gdi32/mapping.c
+++ b/dlls/gdi32/mapping.c
@@ -276,12 +276,7 @@ BOOL CDECL nulldrv_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD
     switch (mode)
     {
     case MWT_IDENTITY:
-        dc->xformWorld2Wnd.eM11 = 1.0f;
-        dc->xformWorld2Wnd.eM12 = 0.0f;
-        dc->xformWorld2Wnd.eM21 = 0.0f;
-        dc->xformWorld2Wnd.eM22 = 1.0f;
-        dc->xformWorld2Wnd.eDx  = 0.0f;
-        dc->xformWorld2Wnd.eDy  = 0.0f;
+        dc->xformWorld2Wnd = *xform;
         break;
     case MWT_LEFTMULTIPLY:
         CombineTransform( &dc->xformWorld2Wnd, xform, &dc->xformWorld2Wnd );
@@ -554,10 +549,12 @@ BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
  */
 BOOL WINAPI ModifyWorldTransform( HDC hdc, const XFORM *xform, DWORD mode )
 {
+    static const XFORM identity_xform = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };
     BOOL ret = FALSE;
     DC *dc;
 
     if (!xform && mode != MWT_IDENTITY) return FALSE;
+    if (mode == MWT_IDENTITY) xform = &identity_xform;
     if ((dc = get_dc_ptr( hdc )))
     {
         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pModifyWorldTransform );
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index e81cff1ae57..648e9369803 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -4158,6 +4158,18 @@ static INT CALLBACK enum_emf_WorldTransform(HDC hdc, HANDLETABLE *ht,
 
                     CombineTransform(&test_data->expected, &test_data->stored, &test_data->scale);
                 }
+                else if(lpXfrm->iMode == MWT_IDENTITY)
+                {
+                    /* reset to identity matrix also does discard */
+                    test_data->stored.eM11 = 1.0f;
+                    test_data->stored.eM12 = 0.0f;
+                    test_data->stored.eM21 = 0.0f;
+                    test_data->stored.eM22 = 1.0f;
+                    test_data->stored.eDx = 0.0f;
+                    test_data->stored.eDy = 0.0f;
+
+                    CombineTransform(&test_data->expected, &test_data->stored, &test_data->scale);
+                }
 
                 /* verify it is updated immediately */
                 ret = GetWorldTransform(hdc, &xform);
@@ -4265,6 +4277,9 @@ static void test_emf_WorldTransform(void)
         ret = SetWorldTransform(hdcMetafile, &xform); /* EMR_SETWORLDTRANSFORM */
         ok(ret == TRUE, "SetWorldTransform failed\n");
 
+        ret = ModifyWorldTransform(hdcMetafile, NULL, MWT_IDENTITY); /* EMR_MODIFYWORLDTRANSFORM */
+        ok(ret == TRUE, "ModifyWorldTransform failed\n");
+
         set_rotation_xform(&xform, M_PI / 2.f, -2, -3);
         ret = ModifyWorldTransform(hdcMetafile, &xform, MWT_LEFTMULTIPLY); /* EMR_MODIFYWORLDTRANSFORM */
         ok(ret == TRUE, "ModifyWorldTransform failed\n");
-- 
2.27.0



More information about the wine-devel mailing list