summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-01-24 09:37:23 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2010-01-24 09:37:23 +0000
commitdc6522dd491831f3843606e3ed57cc01fe2c804c (patch)
treea8551e21071ff4479cc20ee882b3aa6e01230452
parent31bbd7f919f4f1f545dd49861c15e60561c075cb (diff)
uxa: Protect against a potential NULL src->Drawable reference
One of the convoluted if branches dereferenced Drawable when it is potentially NULL. Avoid this by explicitly handling the NULL Drawable cases earlier, and enabling solid fills for solid sources. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--uxa/uxa-render.c119
1 files changed, 78 insertions, 41 deletions
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index 9ccc7558..bffe64f7 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -271,16 +271,19 @@ uxa_try_driver_solid_fill(PicturePtr pSrc,
BoxPtr pbox;
int nbox;
int dst_off_x, dst_off_y;
- PixmapPtr pSrcPix, pDstPix;
+ PixmapPtr pSrcPix = NULL, pDstPix;
CARD32 pixel;
pDstPix = uxa_get_drawable_pixmap(pDst->pDrawable);
- pSrcPix = uxa_get_drawable_pixmap(pSrc->pDrawable);
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
+
+ if (pSrc->pDrawable) {
+ pSrcPix = uxa_get_drawable_pixmap(pSrc->pDrawable);
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+ }
if (!miComputeCompositeRegion(&region, pSrc, NULL, pDst,
xSrc, ySrc, 0, 0, xDst, yDst,
@@ -297,9 +300,21 @@ uxa_try_driver_solid_fill(PicturePtr pSrc,
return 0;
}
- if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) {
- REGION_UNINIT(pDst->pDrawable->pScreen, &region);
- return -1;
+ if (pSrcPix) {
+ if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return -1;
+ }
+ } else {
+ SourcePict *source = pSrc->pSourcePict;
+ PictSolidFill *solid = &source->solidFill;
+
+ if (source == NULL || source->type != SourcePictTypeSolidFill) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return -1;
+ }
+
+ pixel = solid->color;
}
if (!(*uxa_screen->info->prepare_solid)
@@ -949,6 +964,32 @@ uxa_try_magic_two_pass_composite_helper(CARD8 op,
return 1;
}
+static int
+compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src)
+{
+ if (op == PictOpSrc) {
+ if (src->format == dst->format)
+ return 1;
+
+ if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
+ return 1;
+
+ if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
+ return 1;
+ } else if (op == PictOpOver) {
+ if (src->alphaMap || dst->alphaMap)
+ return 0;
+
+ if (src->format == dst->format)
+ return 1;
+
+ if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
+ return 1;
+ }
+
+ return 0;
+}
+
void
uxa_composite(CARD8 op,
PicturePtr pSrc,
@@ -976,27 +1017,29 @@ uxa_composite(CARD8 op,
pSrc->repeat = 0;
if (!pMask) {
- if ((op == PictOpSrc &&
- ((pSrc->format == pDst->format) ||
- (pSrc->format == PICT_a8r8g8b8
- && pDst->format == PICT_x8r8g8b8)
- || (pSrc->format == PICT_a8b8g8r8
- && pDst->format == PICT_x8b8g8r8)))
- || (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap
- && pSrc->format == pDst->format
- && (pSrc->format == PICT_x8r8g8b8
- || pSrc->format == PICT_x8b8g8r8))) {
+ if (pSrc->pDrawable == NULL) {
+ if (pSrc->pSourcePict) {
+ SourcePict *source = pSrc->pSourcePict;
+ if (source->type == SourcePictTypeSolidFill) {
+ ret = uxa_try_driver_solid_fill(pSrc, pDst,
+ xSrc, ySrc,
+ xDst, yDst,
+ width, height);
+ if (ret == 1)
+ goto done;
+ }
+ }
+ } else if (compatible_formats (op, pDst, pSrc)) {
if (pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1 &&
pSrc->repeat) {
- ret =
- uxa_try_driver_solid_fill(pSrc, pDst, xSrc,
- ySrc, xDst, yDst,
- width, height);
+ ret = uxa_try_driver_solid_fill(pSrc, pDst,
+ xSrc, ySrc,
+ xDst, yDst,
+ width, height);
if (ret == 1)
goto done;
- } else if (pSrc->pDrawable != NULL &&
- !pSrc->repeat && !pSrc->transform) {
+ } else if (!pSrc->repeat && !pSrc->transform) {
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
@@ -1016,8 +1059,7 @@ uxa_composite(CARD8 op,
REGION_UNINIT(pDst->pDrawable->pScreen,
&region);
goto done;
- } else if (pSrc->pDrawable != NULL &&
- pSrc->pDrawable->type == DRAWABLE_PIXMAP &&
+ } else if (pSrc->pDrawable->type == DRAWABLE_PIXMAP &&
!pSrc->transform &&
pSrc->repeatType == RepeatNormal) {
DDXPointRec patOrg;
@@ -1027,16 +1069,12 @@ uxa_composite(CARD8 op,
*/
if (uxa_screen->info->prepare_composite
&& !pSrc->alphaMap && !pDst->alphaMap) {
- ret =
- uxa_try_driver_composite(op, pSrc,
- pMask,
- pDst, xSrc,
- ySrc,
- xMask,
- yMask,
- xDst, yDst,
- width,
- height);
+ ret = uxa_try_driver_composite(op, pSrc,
+ pMask, pDst,
+ xSrc, ySrc,
+ xMask, yMask,
+ xDst, yDst,
+ width, height);
if (ret == 1)
goto done;
}
@@ -1060,12 +1098,11 @@ uxa_composite(CARD8 op,
patOrg.x = xDst - xSrc;
patOrg.y = yDst - ySrc;
- ret =
- uxa_fill_region_tiled(pDst->pDrawable,
- &region,
- (PixmapPtr) pSrc->
- pDrawable, &patOrg,
- FB_ALLONES, GXcopy);
+ ret = uxa_fill_region_tiled(pDst->pDrawable,
+ &region,
+ (PixmapPtr) pSrc->
+ pDrawable, &patOrg,
+ FB_ALLONES, GXcopy);
REGION_UNINIT(pDst->pDrawable->pScreen,
&region);