[PATCH 1/2] ddraw: Don't operate on stored invalid clippers.

Stefan Dösinger stefan at codeweavers.com
Fri Mar 22 04:50:04 CDT 2019


Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>

---

This supersedes "ddraw: Don't read clipper methods from the vtable." aka
patch 160690.

I have not modified unsafe_impl_from_IDirectDrawClipper and I'm not
checking the clipper passed to Surface::SetClipper because Windows
crashes when it receives an invalid pointer (although it accepts a
clipper with a modified vtable).
---
 dlls/ddraw/clipper.c       |  2 +-
 dlls/ddraw/ddraw_private.h |  1 +
 dlls/ddraw/surface.c       | 13 ++++++++++---
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/dlls/ddraw/clipper.c b/dlls/ddraw/clipper.c
index e4b7ec2bd50..68a0a7fb7b5 100644
--- a/dlls/ddraw/clipper.c
+++ b/dlls/ddraw/clipper.c
@@ -33,7 +33,7 @@ static inline struct ddraw_clipper *impl_from_IDirectDrawClipper(IDirectDrawClip
     return CONTAINING_RECORD(iface, struct ddraw_clipper, IDirectDrawClipper_iface);
 }
 
-static BOOL ddraw_clipper_is_valid(const struct ddraw_clipper *clipper)
+BOOL ddraw_clipper_is_valid(const struct ddraw_clipper *clipper)
 {
     /* Native is very lenient when you invoke the clipper methods with a clipper pointer that
      * points to something that is either not accessible or not a clipper, or if you break
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 77e28662724..087c7092f98 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -391,6 +391,7 @@ struct ddraw_clipper
 
 HRESULT ddraw_clipper_init(struct ddraw_clipper *clipper) DECLSPEC_HIDDEN;
 struct ddraw_clipper *unsafe_impl_from_IDirectDrawClipper(IDirectDrawClipper *iface) DECLSPEC_HIDDEN;
+BOOL ddraw_clipper_is_valid(const struct ddraw_clipper *clipper) DECLSPEC_HIDDEN;
 
 /*****************************************************************************
  * IDirectDrawPalette implementation structure
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index b8cc2d2195d..4e2faef867d 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -1549,6 +1549,12 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
         return hr;
     }
 
+    if (!ddraw_clipper_is_valid(dst_surface->clipper))
+    {
+        FIXME("Attempting to blit with an invalid clipper.\n");
+        return DDERR_INVALIDPARAMS;
+    }
+
     scale_x = (float)(src_rect.right - src_rect.left) / (float)(dst_rect.right - dst_rect.left);
     scale_y = (float)(src_rect.bottom - src_rect.top) / (float)(dst_rect.bottom - dst_rect.top);
 
@@ -4426,7 +4432,8 @@ static HRESULT WINAPI ddraw_surface7_GetClipper(IDirectDrawSurface7 *iface, IDir
     }
 
     *clipper = &surface->clipper->IDirectDrawClipper_iface;
-    IDirectDrawClipper_AddRef(*clipper);
+    if (ddraw_clipper_is_valid(surface->clipper))
+        IDirectDrawClipper_AddRef(*clipper);
     wined3d_mutex_unlock();
 
     return DD_OK;
@@ -4501,7 +4508,7 @@ static HRESULT WINAPI ddraw_surface7_SetClipper(IDirectDrawSurface7 *iface,
 
     if (clipper != NULL)
         IDirectDrawClipper_AddRef(iclipper);
-    if (old_clipper)
+    if (old_clipper && ddraw_clipper_is_valid(old_clipper))
         IDirectDrawClipper_Release(&old_clipper->IDirectDrawClipper_iface);
 
     if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && This->ddraw->wined3d_swapchain)
@@ -5782,7 +5789,7 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren
     /* Reduce the ddraw surface count. */
     list_remove(&surface->surface_list_entry);
 
-    if (surface->clipper)
+    if (surface->clipper && ddraw_clipper_is_valid(surface->clipper))
         IDirectDrawClipper_Release(&surface->clipper->IDirectDrawClipper_iface);
 
     if (surface == surface->ddraw->primary)
-- 
2.19.2




More information about the wine-devel mailing list