Commit in reactos/subsys/win32k/objects on MAIN
bitmaps.c+62-71.82 -> 1.83
testing reveals that source rect must be constrained to the boundaries of the source image. Adjust dest rect so that output still lands where user expected it. This fixes kmode crash from comctl32 handing bad data off to StretchBlt().

reactos/subsys/win32k/objects
bitmaps.c 1.82 -> 1.83
diff -u -r1.82 -r1.83
--- bitmaps.c	12 Dec 2004 01:40:38 -0000	1.82
+++ bitmaps.c	12 Dec 2004 20:58:09 -0000	1.83
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bitmaps.c,v 1.82 2004/12/12 01:40:38 weiden Exp $ */
+/* $Id: bitmaps.c,v 1.83 2004/12/12 20:58:09 royce Exp $ */
 #include <w32k.h>
 
 #define IN_RECT(r,x,y) \
@@ -1085,7 +1085,7 @@
 	BitmapDest = BITMAPOBJ_LockBitmap(DCDest->w.hBitmap);
 	if (UsesSource)
 	{
-	        if (DCSrc->w.hBitmap == DCDest->w.hBitmap)
+		if (DCSrc->w.hBitmap == DCDest->w.hBitmap)
 			BitmapSrc = BitmapDest;
 		else
 			BitmapSrc = BITMAPOBJ_LockBitmap(DCSrc->w.hBitmap);
@@ -1095,6 +1095,60 @@
 		BitmapSrc = NULL;
 	}
 
+	if ( UsesSource )
+	{
+		int sw = BitmapSrc->SurfObj.sizlBitmap.cx;
+		int sh = BitmapSrc->SurfObj.sizlBitmap.cy;
+		if ( SourceRect.left < 0 )
+		{
+			DestRect.left = DestRect.right - (DestRect.right-DestRect.left) * (SourceRect.right)/abs(SourceRect.right-SourceRect.left);
+			SourceRect.left = 0;
+		}
+		if ( SourceRect.top < 0 )
+		{
+			DestRect.top = DestRect.bottom - (DestRect.bottom-DestRect.top) * (SourceRect.bottom)/abs(SourceRect.bottom-SourceRect.top);
+			SourceRect.top = 0;
+		}
+		if ( SourceRect.right < -1 )
+		{
+			DestRect.right = DestRect.left + (DestRect.right-DestRect.left) * (-1-SourceRect.left)/abs(SourceRect.right-SourceRect.left);
+			SourceRect.right = -1;
+		}
+		if ( SourceRect.bottom < -1 )
+		{
+			DestRect.bottom = DestRect.top + (DestRect.bottom-DestRect.top) * (-1-SourceRect.top)/abs(SourceRect.bottom-SourceRect.top);
+			SourceRect.bottom = -1;
+		}
+		if ( SourceRect.right > sw )
+		{
+			DestRect.right = DestRect.left + (DestRect.right-DestRect.left) * abs(sw-SourceRect.left) / abs(SourceRect.right-SourceRect.left);
+			SourceRect.right = sw;
+		}
+		if ( SourceRect.bottom > sh )
+		{
+			DestRect.bottom = DestRect.top + (DestRect.bottom-DestRect.top) * abs(sh-SourceRect.top) / abs(SourceRect.bottom-SourceRect.top);
+			SourceRect.bottom = sh;
+		}
+		sw--;
+		sh--;
+		if ( SourceRect.left > sw )
+		{
+			DestRect.left = DestRect.right - (DestRect.right-DestRect.left) * (SourceRect.right-sw) / abs(SourceRect.right-SourceRect.left);
+			SourceRect.left = 0;
+		}
+		if ( SourceRect.top > sh )
+		{
+			DestRect.top = DestRect.bottom - (DestRect.bottom-DestRect.top) * (SourceRect.bottom-sh) / abs(SourceRect.bottom-SourceRect.top);
+			SourceRect.top = 0;
+		}
+		if (0 == (DestRect.right-DestRect.left) || 0 == (DestRect.bottom-DestRect.top) || 0 == (SourceRect.right-SourceRect.left) || 0 == (SourceRect.bottom-SourceRect.top))
+		{
+			SetLastWin32Error(ERROR_INVALID_PARAMETER);
+			Status = FALSE;
+			goto failed;
+		}
+	}
+
 	if (UsesPattern)
 	{
 		BrushObj = BRUSHOBJ_LockBrush(DCDest->w.hBrush);
@@ -1143,15 +1197,16 @@
 
 	if (UsesSource)
 		EngDeleteXlate(XlateObj);
-	BITMAPOBJ_UnlockBitmap(DCDest->w.hBitmap);
-	if (UsesSource && DCSrc->w.hBitmap != DCDest->w.hBitmap)
-	{
-		BITMAPOBJ_UnlockBitmap(DCSrc->w.hBitmap);
-	}
 	if (UsesPattern)
 	{
 		BRUSHOBJ_UnlockBrush(DCDest->w.hBrush);
 	}
+failed:
+	if (UsesSource && DCSrc->w.hBitmap != DCDest->w.hBitmap)
+	{
+		BITMAPOBJ_UnlockBitmap(DCSrc->w.hBitmap);
+	}
+	BITMAPOBJ_UnlockBitmap(DCDest->w.hBitmap);
 	if (UsesSource && hDCSrc != hDCDest)
 	{
 		DC_UnlockDc(hDCSrc);
CVSspam 0.2.8