[PATCH] fb: Trim fill to drawable bounds
Oliver McFadden
oliver.mcfadden at nokia.com
Fri Jul 2 06:42:15 PDT 2010
On Fri, 2010-07-02 at 15:13 +0200, ext Chris Wilson wrote:
> Fixes:
>
> Bug 27313 - random X11 crash (SIGSEGV) when rendering firefox in pixman/intel
> https://bugs.freedesktop.org/show_bug.cgi?id=27313
>
> As pixman does not guard against a fill request outside of the buffer,
> we must be be careful and trim oversized fills.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Tested-by: Michael Stapelberg <michael+freedesktop at stapelberg.de>
Reviewed-by: Oliver McFadden <oliver.mcfadden at nokia.com>
> ---
> fb/fbfill.c | 38 ++++++++++++++++++++++++--------------
> include/misc.h | 1 +
> 2 files changed, 25 insertions(+), 14 deletions(-)
>
> diff --git a/fb/fbfill.c b/fb/fbfill.c
> index 801a0d0..e76dcf1 100644
> --- a/fb/fbfill.c
> +++ b/fb/fbfill.c
> @@ -39,20 +39,31 @@ fbFill (DrawablePtr pDrawable,
> int dstBpp;
> int dstXoff, dstYoff;
> FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
> -
> + int x1, x2, y1, y2;
> +
> fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
>
> + /* trim fill to drawable bounds */
> + x1 = clamp(x + dstXoff, 0, pDrawable->width);
> + x2 = clamp(x + dstXoff + width, 0, pDrawable->width);
> +
> + y1 = clamp(y + dstYoff, 0, pDrawable->height);
> + y2 = clamp(y + dstYoff + height, 0, pDrawable->height);
> +
> + width = x2 - x1;
> + height = y2 - y1;
> +
> switch (pGC->fillStyle) {
> case FillSolid:
> #ifndef FB_ACCESS_WRAPPER
> if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
> - x + dstXoff, y + dstYoff,
> + x1, y1,
> width, height,
> pPriv->xor))
> #endif
> - fbSolid (dst + (y + dstYoff) * dstStride,
> - dstStride,
> - (x + dstXoff) * dstBpp,
> + fbSolid (dst + y1 * dstStride,
> + dstStride,
> + x1 * dstBpp,
> dstBpp,
> width * dstBpp, height,
> pPriv->and, pPriv->xor);
> @@ -76,9 +87,9 @@ fbFill (DrawablePtr pDrawable,
> else
> alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
> fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
> - fbTile (dst + (y + dstYoff) * dstStride,
> + fbTile (dst + y1 * dstStride,
> dstStride,
> - x + dstXoff,
> + x1,
> width, height,
> stip,
> stipStride,
> @@ -87,7 +98,6 @@ fbFill (DrawablePtr pDrawable,
> alu,
> pPriv->pm,
> dstBpp,
> -
> (pGC->patOrg.x + pDrawable->x + dstXoff),
> pGC->patOrg.y + pDrawable->y - y);
> fbFinishAccess (&pStip->drawable);
> @@ -114,9 +124,9 @@ fbFill (DrawablePtr pDrawable,
> }
>
> fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
> - fbStipple (dst + (y + dstYoff) * dstStride,
> - dstStride,
> - (x + dstXoff) * dstBpp,
> + fbStipple (dst + y1 * dstStride,
> + dstStride,
> + x1 * dstBpp,
> dstBpp,
> width * dstBpp, height,
> stip,
> @@ -144,9 +154,9 @@ fbFill (DrawablePtr pDrawable,
> fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
> tileWidth = pTile->drawable.width;
> tileHeight = pTile->drawable.height;
> - fbTile (dst + (y + dstYoff) * dstStride,
> - dstStride,
> - (x + dstXoff) * dstBpp,
> + fbTile (dst + y1 * dstStride,
> + dstStride,
> + x1 * dstBpp,
> width * dstBpp, height,
> tile,
> tileStride,
> diff --git a/include/misc.h b/include/misc.h
> index 62d813e..595d4e0 100644
> --- a/include/misc.h
> +++ b/include/misc.h
> @@ -136,6 +136,7 @@ typedef struct _xReq *xReqPtr;
>
> #define min(a, b) (((a) < (b)) ? (a) : (b))
> #define max(a, b) (((a) > (b)) ? (a) : (b))
> +#define clamp(v, a, b) (((v) < (a)) ? (a) : (v) > (b) ? (b) : (v))
> /* abs() is a function, not a macro; include the file declaring
> * it in case we haven't done that yet.
> */
More information about the xorg-devel
mailing list