ddraw: Relax "dwSize" validation in ddraw_surface*_Lock().
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d7b3ef0783
commit
2bef0eafd0
|
@ -626,10 +626,10 @@ struct member_info
|
||||||
/* Structure copy */
|
/* Structure copy */
|
||||||
#define ME(x,f,e) { x, #x, (void (*)(const void *))(f), offsetof(STRUCT, e) }
|
#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 { \
|
do { \
|
||||||
DWORD __size = (to)->dwSize; \
|
DWORD __size = (to)->dwSize; \
|
||||||
DWORD __resetsize = min(__size, sizeof(*to)); \
|
DWORD __resetsize = min(to_size, sizeof(*to)); \
|
||||||
DWORD __copysize = min(__resetsize, from_size); \
|
DWORD __copysize = min(__resetsize, from_size); \
|
||||||
assert(to != from); \
|
assert(to != from); \
|
||||||
memcpy(to, from, __copysize); \
|
memcpy(to, from, __copysize); \
|
||||||
|
@ -637,7 +637,7 @@ struct member_info
|
||||||
(to)->dwSize = __size; /* restore size */ \
|
(to)->dwSize = __size; /* restore size */ \
|
||||||
} while (0)
|
} 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;
|
HRESULT hr_ddraw_from_wined3d(HRESULT hr) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -954,14 +954,15 @@ static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *ifac
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static HRESULT surface_lock(struct ddraw_surface *surface,
|
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_map_desc map_desc;
|
||||||
|
struct wined3d_box box;
|
||||||
HRESULT hr = DD_OK;
|
HRESULT hr = DD_OK;
|
||||||
|
|
||||||
TRACE("surface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
TRACE("surface %p, rect %s, surface_desc %p, surface_desc_size %u, flags %#x, h %p.\n",
|
||||||
surface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
surface, wine_dbgstr_rect(rect), surface_desc, surface_desc_size, flags, h);
|
||||||
|
|
||||||
/* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */
|
/* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
|
@ -1025,7 +1026,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Windows does not set DDSD_LPSURFACE on locked surfaces. */
|
/* 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;
|
surface_desc->lpSurface = map_desc.data;
|
||||||
|
|
||||||
TRACE("locked surface returning description :\n");
|
TRACE("locked surface returning description :\n");
|
||||||
|
@ -1037,63 +1038,80 @@ static HRESULT surface_lock(struct ddraw_surface *surface,
|
||||||
return DD_OK;
|
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,
|
static HRESULT WINAPI ddraw_surface7_Lock(IDirectDrawSurface7 *iface,
|
||||||
RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
|
RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
|
||||||
{
|
{
|
||||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
|
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",
|
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||||
|
|
||||||
if (!surface_desc) return DDERR_INVALIDPARAMS;
|
if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
|
||||||
if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
|
||||||
surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
|
||||||
{
|
|
||||||
WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
|
||||||
return DDERR_INVALIDPARAMS;
|
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,
|
static HRESULT WINAPI ddraw_surface4_Lock(IDirectDrawSurface4 *iface, RECT *rect,
|
||||||
DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
|
DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
|
||||||
{
|
{
|
||||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
|
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",
|
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||||
|
|
||||||
if (!surface_desc) return DDERR_INVALIDPARAMS;
|
if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
|
||||||
if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
|
||||||
surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
|
||||||
{
|
|
||||||
WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
|
||||||
return DDERR_INVALIDPARAMS;
|
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,
|
static HRESULT WINAPI ddraw_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect,
|
||||||
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
||||||
{
|
{
|
||||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
|
struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
|
||||||
|
unsigned int surface_desc_size;
|
||||||
DDSURFACEDESC2 surface_desc2;
|
DDSURFACEDESC2 surface_desc2;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||||
|
|
||||||
if (!surface_desc) return DDERR_INVALIDPARAMS;
|
if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
|
||||||
if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
|
||||||
surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
|
||||||
{
|
|
||||||
WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
|
||||||
return DDERR_INVALIDPARAMS;
|
return DDERR_INVALIDPARAMS;
|
||||||
}
|
|
||||||
|
|
||||||
surface_desc2.dwSize = surface_desc->dwSize;
|
surface_desc2.dwSize = surface_desc->dwSize;
|
||||||
surface_desc2.dwFlags = 0;
|
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);
|
DDSD2_to_DDSD(&surface_desc2, surface_desc);
|
||||||
surface_desc->dwSize = surface_desc2.dwSize;
|
surface_desc->dwSize = surface_desc2.dwSize;
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -1103,23 +1121,19 @@ static HRESULT WINAPI ddraw_surface2_Lock(IDirectDrawSurface2 *iface, RECT *rect
|
||||||
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
||||||
{
|
{
|
||||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
|
struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
|
||||||
|
unsigned int surface_desc_size;
|
||||||
DDSURFACEDESC2 surface_desc2;
|
DDSURFACEDESC2 surface_desc2;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||||
|
|
||||||
if (!surface_desc) return DDERR_INVALIDPARAMS;
|
if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
|
||||||
if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
|
||||||
surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
|
||||||
{
|
|
||||||
WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
|
||||||
return DDERR_INVALIDPARAMS;
|
return DDERR_INVALIDPARAMS;
|
||||||
}
|
|
||||||
|
|
||||||
surface_desc2.dwSize = surface_desc->dwSize;
|
surface_desc2.dwSize = surface_desc->dwSize;
|
||||||
surface_desc2.dwFlags = 0;
|
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);
|
DDSD2_to_DDSD(&surface_desc2, surface_desc);
|
||||||
surface_desc->dwSize = surface_desc2.dwSize;
|
surface_desc->dwSize = surface_desc2.dwSize;
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -1129,22 +1143,19 @@ static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect,
|
||||||
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h)
|
||||||
{
|
{
|
||||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
|
struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
|
||||||
|
unsigned int surface_desc_size;
|
||||||
DDSURFACEDESC2 surface_desc2;
|
DDSURFACEDESC2 surface_desc2;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
|
||||||
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
iface, wine_dbgstr_rect(rect), surface_desc, flags, h);
|
||||||
|
|
||||||
if (!surface_desc) return DDERR_INVALIDPARAMS;
|
if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
|
||||||
if (surface_desc->dwSize != sizeof(DDSURFACEDESC) &&
|
|
||||||
surface_desc->dwSize != sizeof(DDSURFACEDESC2))
|
|
||||||
{
|
|
||||||
WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize);
|
|
||||||
return DDERR_INVALIDPARAMS;
|
return DDERR_INVALIDPARAMS;
|
||||||
}
|
|
||||||
|
|
||||||
surface_desc2.dwSize = surface_desc->dwSize;
|
surface_desc2.dwSize = surface_desc->dwSize;
|
||||||
surface_desc2.dwFlags = 0;
|
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);
|
DDSD2_to_DDSD(&surface_desc2, surface_desc);
|
||||||
surface_desc->dwSize = surface_desc2.dwSize;
|
surface_desc->dwSize = surface_desc2.dwSize;
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -5891,7 +5891,6 @@ static void test_surface_lock(void)
|
||||||
expected_hr = tests[i].caps & DDSCAPS_TEXTURE && !(tests[i].caps & DDSCAPS_VIDEOMEMORY)
|
expected_hr = tests[i].caps & DDSCAPS_TEXTURE && !(tests[i].caps & DDSCAPS_VIDEOMEMORY)
|
||||||
? DD_OK : DDERR_INVALIDPARAMS;
|
? DD_OK : DDERR_INVALIDPARAMS;
|
||||||
hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd, DDLOCK_WAIT, NULL);
|
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);
|
ok(hr == expected_hr, "Got hr %#x, expected %#x, type %s.\n", hr, expected_hr, tests[i].name);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -12321,7 +12320,6 @@ static void test_surface_desc_size(void)
|
||||||
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
||||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc.desc1, 0, 0);
|
hr = IDirectDrawSurface_Lock(surface, NULL, &desc.desc1, 0, 0);
|
||||||
expected_hr = ignore_size || valid_size ? DD_OK : DDERR_INVALIDPARAMS;
|
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",
|
ok(hr == expected_hr, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
|
||||||
hr, expected_hr, desc_sizes[j], surface_caps[i].name);
|
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",
|
ok(desc.dwSize == desc_sizes[j], "dwSize was changed from %u to %u, type %s.\n",
|
||||||
|
@ -12348,7 +12346,6 @@ static void test_surface_desc_size(void)
|
||||||
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
||||||
hr = IDirectDrawSurface3_Lock(surface3, NULL, &desc.desc1, 0, 0);
|
hr = IDirectDrawSurface3_Lock(surface3, NULL, &desc.desc1, 0, 0);
|
||||||
expected_hr = ignore_size || valid_size ? DD_OK : DDERR_INVALIDPARAMS;
|
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",
|
ok(hr == expected_hr, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
|
||||||
hr, expected_hr, desc_sizes[j], surface_caps[i].name);
|
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",
|
ok(desc.dwSize == desc_sizes[j], "dwSize was changed from %u to %u, type %s.\n",
|
||||||
|
@ -12375,7 +12372,6 @@ static void test_surface_desc_size(void)
|
||||||
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
desc.blob[sizeof(DDSURFACEDESC2)] = 0xef;
|
||||||
hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
|
hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
|
||||||
expected_hr = ignore_size || valid_size ? DD_OK : DDERR_INVALIDPARAMS;
|
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",
|
ok(hr == expected_hr, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
|
||||||
hr, expected_hr, desc_sizes[j], surface_caps[i].name);
|
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",
|
ok(desc.dwSize == desc_sizes[j], "dwSize was changed from %u to %u, type %s.\n",
|
||||||
|
|
Loading…
Reference in New Issue