From 410a8e86f5cfbae84ea8f011d769d4e63fa67b78 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 14 Jun 2011 20:28:09 +0200 Subject: [PATCH] wined3d: Check for a valid source rectangle and destination in wined3d_device_update_surface(). --- dlls/wined3d/device.c | 44 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 19a9a45a55f..d907d9a6641 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4738,7 +4738,9 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, struct wined3d_context *context; struct wined3d_bo_address data; struct wined3d_format format; + UINT update_w, update_h; CONVERT_TYPES convert; + UINT dst_w, dst_h; DWORD sampler; POINT p; RECT r; @@ -4769,6 +4771,39 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, p.y = 0; dst_point = &p; } + else if (dst_point->x < 0 || dst_point->y < 0) + { + WARN("Invalid destination point.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (!src_rect) + { + r.left = 0; + r.top = 0; + r.right = src_surface->resource.width; + r.bottom = src_surface->resource.height; + src_rect = &r; + } + else if (src_rect->left < 0 || src_rect->left >= r.right + || src_rect->top < 0 || src_rect->top >= r.bottom) + { + WARN("Invalid source rectangle.\n"); + return WINED3DERR_INVALIDCALL; + } + + dst_w = dst_surface->resource.width; + dst_h = dst_surface->resource.height; + + update_w = src_rect->right - src_rect->left; + update_h = src_rect->bottom - src_rect->top; + + if (update_w > dst_w || dst_point->x > dst_w - update_w + || update_h > dst_h || dst_point->y > dst_h - update_h) + { + WARN("Destination out of bounds.\n"); + return WINED3DERR_INVALIDCALL; + } /* This call loads the OpenGL surface directly, instead of copying the * surface to the destination's sysmem copy. If surface conversion is @@ -4790,15 +4825,6 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, surface_internal_preload(dst_surface, SRGB_RGB); surface_bind(dst_surface, gl_info, FALSE); - if (!src_rect) - { - r.left = 0; - r.top = 0; - r.right = src_surface->resource.width; - r.bottom = src_surface->resource.height; - src_rect = &r; - } - data.buffer_object = 0; data.addr = src_surface->resource.allocatedMemory;