Thanks to GreatLord for spotting that we shouldn't access pixels outside the

source surface in EngBitBlt.

svn path=/trunk/; revision=16059
This commit is contained in:
Gé van Geldorp 2005-06-18 20:29:31 +00:00
parent 91a2889e07
commit 39da2fef47

View file

@ -290,12 +290,64 @@ EngBitBlt(SURFOBJ *DestObj,
return TRUE; return TRUE;
} }
if (UsesSource && NULL != SourcePoint) OutputRect = *DestRect;
if (OutputRect.right < OutputRect.left)
{ {
InputRect.left = SourcePoint->x; OutputRect.left = DestRect->right;
InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left); OutputRect.right = DestRect->left;
InputRect.top = SourcePoint->y; }
InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top); if (OutputRect.bottom < OutputRect.top)
{
OutputRect.left = DestRect->right;
OutputRect.right = DestRect->left;
}
if (UsesSource)
{
if (NULL == SourcePoint)
{
return FALSE;
}
/* 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 else
{ {
@ -305,23 +357,6 @@ EngBitBlt(SURFOBJ *DestObj,
InputRect.bottom = DestRect->bottom - DestRect->top; InputRect.bottom = DestRect->bottom - DestRect->top;
} }
if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
{
return FALSE;
}
if (NULL != SourcePoint)
{
InputPoint.x = SourcePoint->x + Translate.x;
InputPoint.y = SourcePoint->y + Translate.y;
}
else
{
InputPoint.x = 0;
InputPoint.y = 0;
}
OutputRect = *DestRect;
if (NULL != ClipRegion) if (NULL != ClipRegion)
{ {
if (OutputRect.left < ClipRegion->rclBounds.left) if (OutputRect.left < ClipRegion->rclBounds.left)
@ -348,17 +383,25 @@ EngBitBlt(SURFOBJ *DestObj,
} }
} }
/* Check for degenerate case: if height or width of OutputRect is 0 pixels there's /* Check for degenerate case: if height or width of OutputRect is 0 pixels
nothing to do */ there's nothing to do */
if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top) if (OutputRect.right <= OutputRect.left ||
OutputRect.bottom <= OutputRect.top)
{ {
IntEngLeave(&EnterLeaveSource); if (UsesSource)
{
IntEngLeave(&EnterLeaveSource);
}
return TRUE; 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; return FALSE;
} }
@ -368,20 +411,24 @@ EngBitBlt(SURFOBJ *DestObj,
OutputRect.bottom += Translate.y; OutputRect.bottom += Translate.y;
if(BrushOrigin) if(BrushOrigin)
{ {
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x; AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y; AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
} }
else else
{
AdjustedBrushOrigin = Translate; AdjustedBrushOrigin = Translate;
}
// Determine clipping type /* Determine clipping type */
if (ClipRegion == (CLIPOBJ *) NULL) if (ClipRegion == (CLIPOBJ *) NULL)
{ {
clippingType = DC_TRIVIAL; clippingType = DC_TRIVIAL;
} else { }
else
{
clippingType = ClipRegion->iDComplexity; clippingType = ClipRegion->iDComplexity;
} }
if (R4_MASK == Rop4) if (R4_MASK == Rop4)
{ {
@ -404,10 +451,11 @@ EngBitBlt(SURFOBJ *DestObj,
{ {
case DC_TRIVIAL: case DC_TRIVIAL:
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation, Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4); &OutputRect, &InputPoint, MaskOrigin, Brush,
&AdjustedBrushOrigin, Rop4);
break; break;
case DC_RECT: 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.left = ClipRegion->rclBounds.left + Translate.x;
ClipRect.right = ClipRegion->rclBounds.right + Translate.x; ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
ClipRect.top = ClipRegion->rclBounds.top + Translate.y; ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
@ -417,7 +465,8 @@ EngBitBlt(SURFOBJ *DestObj,
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left; Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top; Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation, Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
&CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4); &CombinedRect, &Pt, MaskOrigin, Brush,
&AdjustedBrushOrigin, Rop4);
} }
break; break;
case DC_COMPLEX: case DC_COMPLEX:
@ -426,11 +475,13 @@ EngBitBlt(SURFOBJ *DestObj,
{ {
if (OutputRect.top < InputPoint.y) if (OutputRect.top < InputPoint.y)
{ {
Direction = OutputRect.left < InputPoint.x ? CD_RIGHTDOWN : CD_LEFTDOWN; Direction = OutputRect.left < InputPoint.x ?
CD_RIGHTDOWN : CD_LEFTDOWN;
} }
else else
{ {
Direction = OutputRect.left < InputPoint.x ? CD_RIGHTUP : CD_LEFTUP; Direction = OutputRect.left < InputPoint.x ?
CD_RIGHTUP : CD_LEFTUP;
} }
} }
else else
@ -440,7 +491,8 @@ EngBitBlt(SURFOBJ *DestObj,
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0); CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
do 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++) for (i = 0; i < RectEnum.c; i++)
{ {
@ -465,7 +517,10 @@ EngBitBlt(SURFOBJ *DestObj,
IntEngLeave(&EnterLeaveDest); IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource); if (UsesSource)
{
IntEngLeave(&EnterLeaveSource);
}
return Ret; return Ret;
} }
@ -516,7 +571,8 @@ IntEngBitBlt(BITMAPOBJ *DestObj,
} }
InputPoint = *SourcePoint; 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) if (InputPoint.x < 0)
{ {
InputClippedRect.left -= InputPoint.x; InputClippedRect.left -= InputPoint.x;
@ -527,13 +583,19 @@ IntEngBitBlt(BITMAPOBJ *DestObj,
InputClippedRect.top -= InputPoint.y; InputClippedRect.top -= InputPoint.y;
InputPoint.y = 0; 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 || if (InputClippedRect.right < InputClippedRect.left ||
@ -548,7 +610,8 @@ IntEngBitBlt(BITMAPOBJ *DestObj,
* outside the surface */ * outside the surface */
if (NULL != ClipRegion) if (NULL != ClipRegion)
{ {
if (! EngIntersectRect(&OutputRect, &InputClippedRect, &ClipRegion->rclBounds)) if (! EngIntersectRect(&OutputRect, &InputClippedRect,
&ClipRegion->rclBounds))
{ {
return TRUE; return TRUE;
} }