Henri Verbeet : ddraw: Avoid an integer overflow in IDirectDrawSurfaceImpl_BltFast().
Alexandre Julliard
julliard at winehq.org
Thu Jun 24 11:15:24 CDT 2010
Module: wine
Branch: master
Commit: cf39adbaa2ad80980f8d8f03a9d8802ef7cbd4fd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=cf39adbaa2ad80980f8d8f03a9d8802ef7cbd4fd
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Thu Jun 24 12:10:03 2010 +0200
ddraw: Avoid an integer overflow in IDirectDrawSurfaceImpl_BltFast().
Bug spotted by Iain Arnell, test by Iain Arnell.
---
dlls/ddraw/surface.c | 28 ++++++++++++++++------------
dlls/ddraw/tests/dsurface.c | 8 ++++++++
2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index bfe83a4..ef7b381 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -2077,9 +2077,13 @@ IDirectDrawSurfaceImpl_BltFast(IDirectDrawSurface7 *iface,
{
IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)Source;
+ DWORD src_w, src_h, dst_w, dst_h;
HRESULT hr;
TRACE("(%p)->(%d,%d,%p,%p,%d): Relay\n", This, dstx, dsty, Source, rsrc, trans);
+ dst_w = This->surface_desc.dwWidth;
+ dst_h = This->surface_desc.dwHeight;
+
/* Source must be != NULL, This is not checked by windows. Windows happily throws a 0xc0000005
* in that case
*/
@@ -2092,21 +2096,21 @@ IDirectDrawSurfaceImpl_BltFast(IDirectDrawSurface7 *iface,
WARN("Source rectangle is invalid, returning DDERR_INVALIDRECT\n");
return DDERR_INVALIDRECT;
}
- if(dstx + rsrc->right - rsrc->left > This->surface_desc.dwWidth ||
- dsty + rsrc->bottom - rsrc->top > This->surface_desc.dwHeight)
- {
- WARN("Destination area out of bounds, returning DDERR_INVALIDRECT\n");
- return DDERR_INVALIDRECT;
- }
+
+ src_w = rsrc->right - rsrc->left;
+ src_h = rsrc->bottom - rsrc->top;
}
else
{
- if(dstx + src->surface_desc.dwWidth > This->surface_desc.dwWidth ||
- dsty + src->surface_desc.dwHeight > This->surface_desc.dwHeight)
- {
- WARN("Destination area out of bounds, returning DDERR_INVALIDRECT\n");
- return DDERR_INVALIDRECT;
- }
+ src_w = src->surface_desc.dwWidth;
+ src_h = src->surface_desc.dwHeight;
+ }
+
+ if (src_w > dst_w || dstx > dst_w - src_w
+ || src_h > dst_h || dsty > dst_h - src_h)
+ {
+ WARN("Destination area out of bounds, returning DDERR_INVALIDRECT.\n");
+ return DDERR_INVALIDRECT;
}
EnterCriticalSection(&ddraw_cs);
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index bfd5eae..20e8634 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -2537,6 +2537,14 @@ static void BltParamTest(void)
ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
+
+ hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
+ ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
+ hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
+ ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
+ hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
+ ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
+
hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
More information about the wine-cvs
mailing list