[PATCH] render: Avoid infinite loops in alpha map handling (#23581)

Adam Jackson ajax at redhat.com
Tue May 11 08:30:06 PDT 2010


If setting alpha map to a picture that already has one, use that
instead. (Transitively, although that should never happen.)  If setting
alpha map picture to the picture itself, act as though None were given.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 render/picture.c |   74 +++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 48 insertions(+), 26 deletions(-)

diff --git a/render/picture.c b/render/picture.c
index 48693b8..1c81c46 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1055,6 +1055,39 @@ CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
     return pPicture;
 }
 
+static int
+lookupAlphaMask(PicturePtr *pAlpha, XID pid, ClientPtr client)
+{
+    int error = Success;
+
+    *pAlpha = 0;
+
+    while (pid) {
+	error = dixLookupResourceByType((pointer *)pAlpha, pid, PictureType,
+					client, DixReadAccess);
+
+	if (error != Success) {
+	    client->errorValue = pid;
+	    error = (error == BadValue) ? RenderErrBase + BadPicture : error;
+	    break;
+	}
+
+	if ((*pAlpha)->pDrawable == NULL ||
+	    (*pAlpha)->pDrawable->type != DRAWABLE_PIXMAP) {
+	    client->errorValue = pid;
+	    error = BadMatch;
+	    break;
+	}
+
+	if ((*pAlpha)->alphaMap)
+	    pid = (*pAlpha)->alphaMap->id;
+	else
+	    pid = None;
+    }
+
+    return error;
+}
+
 #define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
 
 #define NEXT_PTR(_type) ((_type) ulist++->ptr)
@@ -1100,35 +1133,24 @@ ChangePicture (PicturePtr	pPicture,
 	case CPAlphaMap:
 	    {
 		PicturePtr  pAlpha;
+		Picture	    pid;
+
+		if (!vlist)
+		    pid = NEXT_PTR(PicturePtr)->id;
+		else
+		    pid = NEXT_VAL(Picture);
 		
-		if (vlist)
+		error = lookupAlphaMask(&pAlpha, pid, client);
+		if (error != Success)
 		{
-		    Picture	pid = NEXT_VAL(Picture);
-
-		    if (pid == None)
-			pAlpha = 0;
-		    else
-		    {
-			error = dixLookupResourceByType((pointer *)&pAlpha, pid,
-						  PictureType, client,
-						  DixReadAccess);
-			if (error != Success)
-			{
-			    client->errorValue = pid;
-			    error = (error == BadValue) ? RenderErrBase + BadPicture : error;
-			    break;
-			}
-			if (pAlpha->pDrawable == NULL ||
-			    pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
-			{
-			    client->errorValue = pid;
-			    error = BadMatch;
-			    break;
-			}
-		    }
+		    client->errorValue = pid;
+		    break;
 		}
-		else
-		    pAlpha = NEXT_PTR(PicturePtr);
+
+		/* break loops */
+		if (pAlpha == pPicture)
+		    pAlpha = NULL;
+
 		if (!error)
 		{
 		    if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
-- 
1.7.0.1



More information about the xorg-devel mailing list