Thanks to GreatLord for spotting that we shouldn't access pixels outside the
source surface in EngBitBlt.
Modified: trunk/reactos/subsys/win32k/eng/bitblt.c

Modified: trunk/reactos/subsys/win32k/eng/bitblt.c
--- trunk/reactos/subsys/win32k/eng/bitblt.c	2005-06-18 20:25:08 UTC (rev 16058)
+++ trunk/reactos/subsys/win32k/eng/bitblt.c	2005-06-18 20:29:31 UTC (rev 16059)
@@ -290,38 +290,73 @@
     return TRUE;
     }
 
-  if (UsesSource && NULL != SourcePoint)
+  OutputRect = *DestRect;
+  if (OutputRect.right < OutputRect.left)
     {
-    InputRect.left = SourcePoint->x;
-    InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
-    InputRect.top = SourcePoint->y;
-    InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top);
+    OutputRect.left = DestRect->right;
+    OutputRect.right = DestRect->left;
     }
-  else
+  if (OutputRect.bottom < OutputRect.top)
     {
-    InputRect.left = 0;
-    InputRect.right = DestRect->right - DestRect->left;
-    InputRect.top = 0;
-    InputRect.bottom = DestRect->bottom - DestRect->top;
+    OutputRect.left = DestRect->right;
+    OutputRect.right = DestRect->left;
     }
 
-  if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
+  if (UsesSource)
     {
-    return FALSE;
-    }
+    if (NULL == SourcePoint)
+      {
+      return FALSE;
+      }
 
-  if (NULL != SourcePoint)
-    {
-    InputPoint.x = SourcePoint->x + Translate.x;
-    InputPoint.y = SourcePoint->y + Translate.y;
+    /* Make sure we don't try to copy anything outside the valid source
+       region */
+    InputPoint = *SourcePoint;
+    if (InputPoint.x < 0)
+      {
+        OutputRect.left -= InputPoint.x;
+        InputPoint.x = 0;
+      }
+    if (InputPoint.y < 0)
+      {
+        OutputRect.top -= InputPoint.y;
+        InputPoint.y = 0;
+      }
+    if (SourceObj->sizlBitmap.cx < InputPoint.x +
+                                   OutputRect.right - OutputRect.left)
+      {
+        OutputRect.right = OutputRect.left +
+                           SourceObj->sizlBitmap.cx - InputPoint.x;
+      }
+    if (SourceObj->sizlBitmap.cy < InputPoint.y +
+                                   OutputRect.bottom - OutputRect.top)
+      {
+        OutputRect.bottom = OutputRect.top +
+                            SourceObj->sizlBitmap.cy - InputPoint.y;
+      }
+
+    InputRect.left = InputPoint.x;
+    InputRect.right = InputPoint.x + (OutputRect.right - OutputRect.left);
+    InputRect.top = InputPoint.y;
+    InputRect.bottom = InputPoint.y + (OutputRect.bottom - OutputRect.top);
+
+    if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE,
+                      &Translate, &InputObj))
+      {
+      return FALSE;
+      }
+
+    InputPoint.x += Translate.x;
+    InputPoint.y += Translate.y;
     }
   else
     {
-    InputPoint.x = 0;
-    InputPoint.y = 0;
+    InputRect.left = 0;
+    InputRect.right = DestRect->right - DestRect->left;
+    InputRect.top = 0;
+    InputRect.bottom = DestRect->bottom - DestRect->top;
     }
 
-  OutputRect = *DestRect;
   if (NULL != ClipRegion)
     {
       if (OutputRect.left < ClipRegion->rclBounds.left)
@@ -348,17 +383,25 @@
 	}
     }
 
-  /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
-     nothing to do */
-  if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
+  /* Check for degenerate case: if height or width of OutputRect is 0 pixels
+     there's nothing to do */
+  if (OutputRect.right <= OutputRect.left ||
+      OutputRect.bottom <= OutputRect.top)
     {
-    IntEngLeave(&EnterLeaveSource);
+    if (UsesSource)
+      {
+      IntEngLeave(&EnterLeaveSource);
+      }
     return TRUE;
     }
 
-  if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
+  if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate,
+                    &OutputObj))
     {
-    IntEngLeave(&EnterLeaveSource);
+    if (UsesSource)
+      {
+      IntEngLeave(&EnterLeaveSource);
+      }
     return FALSE;
     }
 
@@ -368,20 +411,24 @@
   OutputRect.bottom += Translate.y;
 
   if(BrushOrigin)
-  {
+    {
     AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
     AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
-  }
+    }
   else
+    {
     AdjustedBrushOrigin = Translate;
+    }
 
-  // Determine clipping type
+  /* Determine clipping type */
   if (ClipRegion == (CLIPOBJ *) NULL)
-  {
+    {
     clippingType = DC_TRIVIAL;
-  } else {
+    }
+  else
+    {
     clippingType = ClipRegion->iDComplexity;
-  }
+    }
 
   if (R4_MASK == Rop4)
     {
@@ -404,10 +451,11 @@
   {
     case DC_TRIVIAL:
       Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
-                           &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4);
+                           &OutputRect, &InputPoint, MaskOrigin, Brush,
+                           &AdjustedBrushOrigin, Rop4);
       break;
     case DC_RECT:
-      // Clip the blt to the clip rectangle
+      /* Clip the blt to the clip rectangle */
       ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
       ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
       ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
@@ -417,7 +465,8 @@
           Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
           Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
           Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
-                               &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4);
+                               &CombinedRect, &Pt, MaskOrigin, Brush,
+                               &AdjustedBrushOrigin, Rop4);
         }
       break;
     case DC_COMPLEX:
@@ -426,11 +475,13 @@
 	{
 	  if (OutputRect.top < InputPoint.y)
 	    {
-	      Direction = OutputRect.left < InputPoint.x ? CD_RIGHTDOWN : CD_LEFTDOWN;
+	      Direction = OutputRect.left < InputPoint.x ?
+                          CD_RIGHTDOWN : CD_LEFTDOWN;
 	    }
 	  else
 	    {
-	      Direction = OutputRect.left < InputPoint.x ? CD_RIGHTUP : CD_LEFTUP;
+	      Direction = OutputRect.left < InputPoint.x ?
+                          CD_RIGHTUP : CD_LEFTUP;
 	    }
 	}
       else
@@ -440,7 +491,8 @@
       CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
       do
 	{
-	  EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
+	  EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
+                                   (PVOID) &RectEnum);
 
 	  for (i = 0; i < RectEnum.c; i++)
 	    {
@@ -465,7 +517,10 @@
 
 
   IntEngLeave(&EnterLeaveDest);
-  IntEngLeave(&EnterLeaveSource);
+  if (UsesSource)
+    {
+    IntEngLeave(&EnterLeaveSource);
+    }
 
   return Ret;
 }
@@ -516,7 +571,8 @@
         }
       InputPoint = *SourcePoint;
 
-      /* Make sure we don't try to copy anything outside the valid source region */
+      /* Make sure we don't try to copy anything outside the valid source
+         region */
       if (InputPoint.x < 0)
         {
           InputClippedRect.left -= InputPoint.x;
@@ -527,13 +583,19 @@
           InputClippedRect.top -= InputPoint.y;
           InputPoint.y = 0;
         }
-      if (SourceSurf->sizlBitmap.cx < InputPoint.x + InputClippedRect.right - InputClippedRect.left)
+      if (SourceSurf->sizlBitmap.cx < InputPoint.x +
+                                      InputClippedRect.right -
+                                      InputClippedRect.left)
         {
-          InputClippedRect.right = InputClippedRect.left + SourceSurf->sizlBitmap.cx - InputPoint.x;
+          InputClippedRect.right = InputClippedRect.left +
+                                   SourceSurf->sizlBitmap.cx - InputPoint.x;
         }
-      if (SourceSurf->sizlBitmap.cy < InputPoint.y + InputClippedRect.bottom - InputClippedRect.top)
+      if (SourceSurf->sizlBitmap.cy < InputPoint.y +
+                                      InputClippedRect.bottom -
+                                      InputClippedRect.top)
         {
-          InputClippedRect.bottom = InputClippedRect.top + SourceSurf->sizlBitmap.cy - InputPoint.y;
+          InputClippedRect.bottom = InputClippedRect.top +
+                                    SourceSurf->sizlBitmap.cy - InputPoint.y;
         }
 
       if (InputClippedRect.right < InputClippedRect.left ||
@@ -548,7 +610,8 @@
    * outside the surface */
   if (NULL != ClipRegion)
     {
-      if (! EngIntersectRect(&OutputRect, &InputClippedRect, &ClipRegion->rclBounds))
+      if (! EngIntersectRect(&OutputRect, &InputClippedRect,
+                             &ClipRegion->rclBounds))
 	{
 	  return TRUE;
 	}