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>
This commit is contained in:
parent
31bbd7f919
commit
dc6522dd49
119
uxa/uxa-render.c
119
uxa/uxa-render.c
|
|
@ -271,16 +271,19 @@ uxa_try_driver_solid_fill(PicturePtr pSrc,
|
||||||
BoxPtr pbox;
|
BoxPtr pbox;
|
||||||
int nbox;
|
int nbox;
|
||||||
int dst_off_x, dst_off_y;
|
int dst_off_x, dst_off_y;
|
||||||
PixmapPtr pSrcPix, pDstPix;
|
PixmapPtr pSrcPix = NULL, pDstPix;
|
||||||
CARD32 pixel;
|
CARD32 pixel;
|
||||||
|
|
||||||
pDstPix = uxa_get_drawable_pixmap(pDst->pDrawable);
|
pDstPix = uxa_get_drawable_pixmap(pDst->pDrawable);
|
||||||
pSrcPix = uxa_get_drawable_pixmap(pSrc->pDrawable);
|
|
||||||
|
|
||||||
xDst += pDst->pDrawable->x;
|
xDst += pDst->pDrawable->x;
|
||||||
yDst += pDst->pDrawable->y;
|
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(®ion, pSrc, NULL, pDst,
|
if (!miComputeCompositeRegion(®ion, pSrc, NULL, pDst,
|
||||||
xSrc, ySrc, 0, 0, xDst, yDst,
|
xSrc, ySrc, 0, 0, xDst, yDst,
|
||||||
|
|
@ -297,9 +300,21 @@ uxa_try_driver_solid_fill(PicturePtr pSrc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) {
|
if (pSrcPix) {
|
||||||
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) {
|
||||||
return -1;
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SourcePict *source = pSrc->pSourcePict;
|
||||||
|
PictSolidFill *solid = &source->solidFill;
|
||||||
|
|
||||||
|
if (source == NULL || source->type != SourcePictTypeSolidFill) {
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel = solid->color;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*uxa_screen->info->prepare_solid)
|
if (!(*uxa_screen->info->prepare_solid)
|
||||||
|
|
@ -949,6 +964,32 @@ uxa_try_magic_two_pass_composite_helper(CARD8 op,
|
||||||
return 1;
|
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
|
void
|
||||||
uxa_composite(CARD8 op,
|
uxa_composite(CARD8 op,
|
||||||
PicturePtr pSrc,
|
PicturePtr pSrc,
|
||||||
|
|
@ -976,27 +1017,29 @@ uxa_composite(CARD8 op,
|
||||||
pSrc->repeat = 0;
|
pSrc->repeat = 0;
|
||||||
|
|
||||||
if (!pMask) {
|
if (!pMask) {
|
||||||
if ((op == PictOpSrc &&
|
if (pSrc->pDrawable == NULL) {
|
||||||
((pSrc->format == pDst->format) ||
|
if (pSrc->pSourcePict) {
|
||||||
(pSrc->format == PICT_a8r8g8b8
|
SourcePict *source = pSrc->pSourcePict;
|
||||||
&& pDst->format == PICT_x8r8g8b8)
|
if (source->type == SourcePictTypeSolidFill) {
|
||||||
|| (pSrc->format == PICT_a8b8g8r8
|
ret = uxa_try_driver_solid_fill(pSrc, pDst,
|
||||||
&& pDst->format == PICT_x8b8g8r8)))
|
xSrc, ySrc,
|
||||||
|| (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap
|
xDst, yDst,
|
||||||
&& pSrc->format == pDst->format
|
width, height);
|
||||||
&& (pSrc->format == PICT_x8r8g8b8
|
if (ret == 1)
|
||||||
|| pSrc->format == PICT_x8b8g8r8))) {
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (compatible_formats (op, pDst, pSrc)) {
|
||||||
if (pSrc->pDrawable->width == 1 &&
|
if (pSrc->pDrawable->width == 1 &&
|
||||||
pSrc->pDrawable->height == 1 &&
|
pSrc->pDrawable->height == 1 &&
|
||||||
pSrc->repeat) {
|
pSrc->repeat) {
|
||||||
ret =
|
ret = uxa_try_driver_solid_fill(pSrc, pDst,
|
||||||
uxa_try_driver_solid_fill(pSrc, pDst, xSrc,
|
xSrc, ySrc,
|
||||||
ySrc, xDst, yDst,
|
xDst, yDst,
|
||||||
width, height);
|
width, height);
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
goto done;
|
goto done;
|
||||||
} else if (pSrc->pDrawable != NULL &&
|
} else if (!pSrc->repeat && !pSrc->transform) {
|
||||||
!pSrc->repeat && !pSrc->transform) {
|
|
||||||
xDst += pDst->pDrawable->x;
|
xDst += pDst->pDrawable->x;
|
||||||
yDst += pDst->pDrawable->y;
|
yDst += pDst->pDrawable->y;
|
||||||
xSrc += pSrc->pDrawable->x;
|
xSrc += pSrc->pDrawable->x;
|
||||||
|
|
@ -1016,8 +1059,7 @@ uxa_composite(CARD8 op,
|
||||||
REGION_UNINIT(pDst->pDrawable->pScreen,
|
REGION_UNINIT(pDst->pDrawable->pScreen,
|
||||||
®ion);
|
®ion);
|
||||||
goto done;
|
goto done;
|
||||||
} else if (pSrc->pDrawable != NULL &&
|
} else if (pSrc->pDrawable->type == DRAWABLE_PIXMAP &&
|
||||||
pSrc->pDrawable->type == DRAWABLE_PIXMAP &&
|
|
||||||
!pSrc->transform &&
|
!pSrc->transform &&
|
||||||
pSrc->repeatType == RepeatNormal) {
|
pSrc->repeatType == RepeatNormal) {
|
||||||
DDXPointRec patOrg;
|
DDXPointRec patOrg;
|
||||||
|
|
@ -1027,16 +1069,12 @@ uxa_composite(CARD8 op,
|
||||||
*/
|
*/
|
||||||
if (uxa_screen->info->prepare_composite
|
if (uxa_screen->info->prepare_composite
|
||||||
&& !pSrc->alphaMap && !pDst->alphaMap) {
|
&& !pSrc->alphaMap && !pDst->alphaMap) {
|
||||||
ret =
|
ret = uxa_try_driver_composite(op, pSrc,
|
||||||
uxa_try_driver_composite(op, pSrc,
|
pMask, pDst,
|
||||||
pMask,
|
xSrc, ySrc,
|
||||||
pDst, xSrc,
|
xMask, yMask,
|
||||||
ySrc,
|
xDst, yDst,
|
||||||
xMask,
|
width, height);
|
||||||
yMask,
|
|
||||||
xDst, yDst,
|
|
||||||
width,
|
|
||||||
height);
|
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1060,12 +1098,11 @@ uxa_composite(CARD8 op,
|
||||||
patOrg.x = xDst - xSrc;
|
patOrg.x = xDst - xSrc;
|
||||||
patOrg.y = yDst - ySrc;
|
patOrg.y = yDst - ySrc;
|
||||||
|
|
||||||
ret =
|
ret = uxa_fill_region_tiled(pDst->pDrawable,
|
||||||
uxa_fill_region_tiled(pDst->pDrawable,
|
®ion,
|
||||||
®ion,
|
(PixmapPtr) pSrc->
|
||||||
(PixmapPtr) pSrc->
|
pDrawable, &patOrg,
|
||||||
pDrawable, &patOrg,
|
FB_ALLONES, GXcopy);
|
||||||
FB_ALLONES, GXcopy);
|
|
||||||
|
|
||||||
REGION_UNINIT(pDst->pDrawable->pScreen,
|
REGION_UNINIT(pDst->pDrawable->pScreen,
|
||||||
®ion);
|
®ion);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue