From 700394f5ff748bd949c12120ee6c15150dc8cbb9 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Fri, 20 Apr 2018 00:55:40 +0200 Subject: [PATCH] ddraw: Forbid setting viewport extents larger than the render target in SetViewport(). Signed-off-by: Matteo Bruni Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/ddraw/viewport.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 0bc746e974f..fad079f1edb 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -299,7 +299,10 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE { struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); struct d3d_device *device = viewport->active_device; + struct wined3d_sub_resource_desc rt_desc; + struct wined3d_rendertarget_view *rtv; IDirect3DViewport3 *current_viewport; + struct ddraw_surface *surface; TRACE("iface %p, vp %p.\n", iface, vp); @@ -312,8 +315,33 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE _dump_D3DVIEWPORT(vp); } + if (!device) + { + WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n"); + return D3DERR_VIEWPORTHASNODEVICE; + } + wined3d_mutex_lock(); + if (device->version > 1) + { + if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + { + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); + + if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX + || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY) + { + WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n"); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + } + viewport->use_vp2 = 0; memset(&viewport->viewports.vp1, 0, sizeof(viewport->viewports.vp1)); memcpy(&viewport->viewports.vp1, vp, vp->dwSize); @@ -323,14 +351,11 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE viewport->viewports.vp1.dvMinZ = 0.0; viewport->viewports.vp1.dvMaxZ = 1.0; - if (device) + if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) { - if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) - { - if (current_viewport == iface) - viewport_activate(viewport, FALSE); - IDirect3DViewport3_Release(current_viewport); - } + if (current_viewport == iface) + viewport_activate(viewport, FALSE); + IDirect3DViewport3_Release(current_viewport); } wined3d_mutex_unlock();