mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Added patch to relax dwSize validation ddraw_surface*_Lock.
This commit is contained in:
parent
dbaede0fc8
commit
76177e1da2
@ -0,0 +1,269 @@
|
||||
From 0a0146b997a9c5d60fea6a4c6367e059241b942b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <jkucia@codeweavers.com>
|
||||
Date: Tue, 17 Jan 2017 12:26:37 +0100
|
||||
Subject: ddraw: Relax "dwSize" validation in ddraw_surface*_Lock().
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
|
||||
---
|
||||
dlls/ddraw/ddraw_private.h | 6 +--
|
||||
dlls/ddraw/surface.c | 91 ++++++++++++++++++++++++++--------------------
|
||||
dlls/ddraw/tests/ddraw7.c | 4 --
|
||||
3 files changed, 54 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
|
||||
index 0dc915cfcb2..a8ac865887d 100644
|
||||
--- a/dlls/ddraw/ddraw_private.h
|
||||
+++ b/dlls/ddraw/ddraw_private.h
|
||||
@@ -628,10 +628,10 @@ struct member_info
|
||||
/* Structure copy */
|
||||
#define ME(x,f,e) { x, #x, (void (*)(const void *))(f), offsetof(STRUCT, e) }
|
||||
|
||||
-#define DD_STRUCT_COPY_BYSIZE_(to,from,from_size) \
|
||||
+#define DD_STRUCT_COPY_BYSIZE_(to,from,to_size,from_size) \
|
||||
do { \
|
||||
DWORD __size = (to)->dwSize; \
|
||||
- DWORD __resetsize = min(__size, sizeof(*to)); \
|
||||
+ DWORD __resetsize = min(to_size, sizeof(*to)); \
|
||||
DWORD __copysize = min(__resetsize, from_size); \
|
||||
assert(to != from); \
|
||||
memcpy(to, from, __copysize); \
|
||||
@@ -639,7 +639,7 @@ struct member_info
|
||||
(to)->dwSize = __size; /* restore size */ \
|
||||
} while (0)
|
||||
|
||||
-#define DD_STRUCT_COPY_BYSIZE(to,from) DD_STRUCT_COPY_BYSIZE_(to,from,(from)->dwSize)
|
||||
+#define DD_STRUCT_COPY_BYSIZE(to,from) DD_STRUCT_COPY_BYSIZE_(to,from,(to)->dwSize,(from)->dwSize)
|
||||
|
||||
HRESULT hr_ddraw_from_wined3d(HRESULT hr) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
|
||||
index 7d1fc2edd34..cbe1eb7d98f 100644
|
||||
--- a/dlls/ddraw/surface.c
|
||||
+++ b/dlls/ddraw/surface.c
|
||||
@@ -955,14 +955,15 @@ static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *ifac
|
||||
*
|
||||
*****************************************************************************/
|
||||
static HRESULT surface_lock(struct ddraw_surface *surface,
|
||||
- RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
|
||||
+ RECT *rect, DDSURFACEDESC2 *surface_desc, unsigned int surface_desc_size,
|
||||
+ DWORD flags, HANDLE h)
|
||||
{
|
||||
- struct wined3d_box box;
|
||||
struct wined3d_map_desc map_desc;
|
||||
+ struct wined3d_box box;
|
||||
HRESULT hr = DD_OK;
|
||||
|
||||
- TRACE("surface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||
- surface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||
+ TRACE("surface %p, rect %s, surface_desc %p, surface_desc_size %u, flags %#x, h %p.\n",
|
||||
+ surface, wine_dbgstr_rect(rect), surface_desc, surface_desc_size, flags, h);
|
||||
|
||||
/* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */
|
||||
wined3d_mutex_lock();
|
||||
@@ -1026,7 +1027,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface,
|
||||
}
|
||||
|
||||
/* Windows does not set DDSD_LPSURFACE on locked surfaces. */
|
||||
- DD_STRUCT_COPY_BYSIZE(surface_desc, &surface->surface_desc);
|
||||
+ DD_STRUCT_COPY_BYSIZE_(surface_desc, &surface->surface_desc, surface_desc_size, surface->surface_desc.dwSize);
|
||||
surface_desc->lpSurface = map_desc.data;
|
||||
|
||||
TRACE("locked surface returning description :\n");
|
||||
@@ -1038,63 +1039,80 @@ static HRESULT surface_lock(struct ddraw_surface *surface,
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
+static BOOL surface_validate_lock_desc(struct ddraw_surface *surface,
|
||||
+ const DDSURFACEDESC *desc, unsigned int *size)
|
||||
+{
|
||||
+ if (!desc)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (desc->dwSize == sizeof(DDSURFACEDESC) || desc->dwSize == sizeof(DDSURFACEDESC2))
|
||||
+ {
|
||||
+ *size = desc->dwSize;
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+
|
||||
+ if (surface->version == 7
|
||||
+ && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE
|
||||
+ && !(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
|
||||
+ {
|
||||
+ if (desc->dwSize >= sizeof(DDSURFACEDESC2))
|
||||
+ *size = sizeof(DDSURFACEDESC2);
|
||||
+ else
|
||||
+ *size = sizeof(DDSURFACEDESC);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+
|
||||
+ WARN("Invalid structure size %u.\n", desc->dwSize);
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
static HRESULT WINAPI ddraw_surface7_Lock(IDirectDrawSurface7 *iface,
|
||||
RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
|
||||
{
|
||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
|
||||
+ unsigned int surface_desc_size;
|
||||
|
||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||
|
||||
- if (!surface_desc) return DDERR_INVALIDPARAMS;
|
||||
- if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
||||
- surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
||||
- {
|
||||
- WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
||||
+ if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
|
||||
return DDERR_INVALIDPARAMS;
|
||||
- }
|
||||
- return surface_lock(surface, rect, surface_desc, flags, h);
|
||||
+
|
||||
+ return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ddraw_surface4_Lock(IDirectDrawSurface4 *iface, RECT *rect,
|
||||
DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
|
||||
{
|
||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
|
||||
+ unsigned int surface_desc_size;
|
||||
|
||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||
|
||||
- if (!surface_desc) return DDERR_INVALIDPARAMS;
|
||||
- if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
||||
- surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
||||
- {
|
||||
- WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
||||
+ if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
|
||||
return DDERR_INVALIDPARAMS;
|
||||
- }
|
||||
- return surface_lock(surface, rect, surface_desc, flags, h);
|
||||
+
|
||||
+ return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ddraw_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect,
|
||||
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
||||
{
|
||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
|
||||
+ unsigned int surface_desc_size;
|
||||
DDSURFACEDESC2 surface_desc2;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||
|
||||
- if (!surface_desc) return DDERR_INVALIDPARAMS;
|
||||
- if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
||||
- surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
||||
- {
|
||||
- WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
||||
+ if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
|
||||
return DDERR_INVALIDPARAMS;
|
||||
- }
|
||||
|
||||
surface_desc2.dwSize = surface_desc->dwSize;
|
||||
surface_desc2.dwFlags = 0;
|
||||
- hr = surface_lock(surface, rect, &surface_desc2, flags, h);
|
||||
+ hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
|
||||
DDSD2_to_DDSD(&surface_desc2, surface_desc);
|
||||
surface_desc->dwSize = surface_desc2.dwSize;
|
||||
return hr;
|
||||
@@ -1104,23 +1122,19 @@ static HRESULT WINAPI ddraw_surface2_Lock(IDirectDrawSurface2 *iface, RECT *rect
|
||||
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
||||
{
|
||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
|
||||
+ unsigned int surface_desc_size;
|
||||
DDSURFACEDESC2 surface_desc2;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||
|
||||
- if (!surface_desc) return DDERR_INVALIDPARAMS;
|
||||
- if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
||||
- surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
||||
- {
|
||||
- WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
||||
+ if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
|
||||
return DDERR_INVALIDPARAMS;
|
||||
- }
|
||||
|
||||
surface_desc2.dwSize = surface_desc->dwSize;
|
||||
surface_desc2.dwFlags = 0;
|
||||
- hr = surface_lock(surface, rect, &surface_desc2, flags, h);
|
||||
+ hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
|
||||
DDSD2_to_DDSD(&surface_desc2, surface_desc);
|
||||
surface_desc->dwSize = surface_desc2.dwSize;
|
||||
return hr;
|
||||
@@ -1130,22 +1144,19 @@ static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect,
|
||||
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
||||
{
|
||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
|
||||
+ unsigned int surface_desc_size;
|
||||
DDSURFACEDESC2 surface_desc2;
|
||||
HRESULT hr;
|
||||
+
|
||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||
|
||||
- if (!surface_desc) return DDERR_INVALIDPARAMS;
|
||||
- if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
||||
- surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
||||
- {
|
||||
- WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
||||
+ if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
|
||||
return DDERR_INVALIDPARAMS;
|
||||
- }
|
||||
|
||||
surface_desc2.dwSize = surface_desc->dwSize;
|
||||
surface_desc2.dwFlags = 0;
|
||||
- hr = surface_lock(surface, rect, &surface_desc2, flags, h);
|
||||
+ hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
|
||||
DDSD2_to_DDSD(&surface_desc2, surface_desc);
|
||||
surface_desc->dwSize = surface_desc2.dwSize;
|
||||
return hr;
|
||||
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
|
||||
index 7957f1733d5..bc35ae78199 100644
|
||||
--- a/dlls/ddraw/tests/ddraw7.c
|
||||
+++ b/dlls/ddraw/tests/ddraw7.c
|
||||
@@ -5909,7 +5909,6 @@ static void test_surface_lock(void)
|
||||
expected_hr = tests[i].caps & DDSCAPS_TEXTURE && !(tests[i].caps & DDSCAPS_VIDEOMEMORY)
|
||||
? DD_OK : DDERR_INVALIDPARAMS;
|
||||
hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd, DDLOCK_WAIT, NULL);
|
||||
- todo_wine_if(expected_hr == D3D_OK)
|
||||
ok(hr == expected_hr, "Got hr %#x, expected %#x, type %s.\n", hr, expected_hr, tests[i].name);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
@@ -12340,7 +12339,6 @@ static void test_surface_desc_size(void)
|
||||
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc.desc1, 0, 0);
|
||||
expected_hr = ignore_size || valid_size ? DD_OK : DDERR_INVALIDPARAMS;
|
||||
- todo_wine_if(ignore_size && !valid_size)
|
||||
ok(hr == expected_hr, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
|
||||
hr, expected_hr, desc_sizes[j], surface_caps[i].name);
|
||||
ok(desc.dwSize == desc_sizes[j], "dwSize was changed from %u to %u, type %s.\n",
|
||||
@@ -12367,7 +12365,6 @@ static void test_surface_desc_size(void)
|
||||
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
||||
hr = IDirectDrawSurface3_Lock(surface3, NULL, &desc.desc1, 0, 0);
|
||||
expected_hr = ignore_size || valid_size ? DD_OK : DDERR_INVALIDPARAMS;
|
||||
- todo_wine_if(ignore_size && !valid_size)
|
||||
ok(hr == expected_hr, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
|
||||
hr, expected_hr, desc_sizes[j], surface_caps[i].name);
|
||||
ok(desc.dwSize == desc_sizes[j], "dwSize was changed from %u to %u, type %s.\n",
|
||||
@@ -12394,7 +12391,6 @@ static void test_surface_desc_size(void)
|
||||
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
||||
hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
|
||||
expected_hr = ignore_size || valid_size ? DD_OK : DDERR_INVALIDPARAMS;
|
||||
- todo_wine_if(ignore_size && !valid_size)
|
||||
ok(hr == expected_hr, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
|
||||
hr, expected_hr, desc_sizes[j], surface_caps[i].name);
|
||||
ok(desc.dwSize == desc_sizes[j], "dwSize was changed from %u to %u, type %s.\n",
|
||||
--
|
||||
2.11.0
|
||||
|
1
patches/ddraw-Relax_dwSize_Validation/definition
Normal file
1
patches/ddraw-Relax_dwSize_Validation/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [14897] Relax dwSize validation ddraw_surface*_Lock
|
@ -139,6 +139,7 @@ patch_enable_all ()
|
||||
enable_ddraw_Fix_Typos="$1"
|
||||
enable_ddraw_FlipToGDISurface="$1"
|
||||
enable_ddraw_IDirect3DTexture2_Load="$1"
|
||||
enable_ddraw_Relax_dwSize_Validation="$1"
|
||||
enable_ddraw_Rendering_Targets="$1"
|
||||
enable_ddraw_Write_Vtable="$1"
|
||||
enable_dinput_Initialize="$1"
|
||||
@ -630,6 +631,9 @@ patch_enable ()
|
||||
ddraw-IDirect3DTexture2_Load)
|
||||
enable_ddraw_IDirect3DTexture2_Load="$2"
|
||||
;;
|
||||
ddraw-Relax_dwSize_Validation)
|
||||
enable_ddraw_Relax_dwSize_Validation="$2"
|
||||
;;
|
||||
ddraw-Rendering_Targets)
|
||||
enable_ddraw_Rendering_Targets="$2"
|
||||
;;
|
||||
@ -3832,6 +3836,21 @@ if test "$enable_ddraw_IDirect3DTexture2_Load" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ddraw-Relax_dwSize_Validation
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#14897] Relax dwSize validation ddraw_surface*_Lock
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ddraw/ddraw_private.h, dlls/ddraw/surface.c, dlls/ddraw/tests/ddraw7.c
|
||||
# |
|
||||
if test "$enable_ddraw_Relax_dwSize_Validation" -eq 1; then
|
||||
patch_apply ddraw-Relax_dwSize_Validation/0001-ddraw-Relax-dwSize-validation-in-ddraw_surface-_Lock.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Józef Kucia", "ddraw: Relax \"dwSize\" validation in ddraw_surface*_Lock().", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ddraw-Rendering_Targets
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
x
Reference in New Issue
Block a user