[PATCH:xserver] Missing memory allocation checks.

Miod Vallat miod at online.fr
Mon Nov 30 12:54:51 PST 2015


This is a potpourri of missing memory allocation checks. Routines will return
BadAlloc whenever possible, or fall back to a different behaviour, whenever
possible. Unfortunately some functions are void and can not propagate failure
to their callers.

Signed-off-by: Miod Vallat <miod at online.fr>
---
 Xext/panoramiX.c          | 15 ++++++++++++++-
 Xext/panoramiXprocs.c     | 16 ++++++++++++++++
 Xext/xres.c               |  2 ++
 Xi/getprop.c              |  3 +++
 Xi/getselev.c             |  2 ++
 dix/enterleave.c          |  2 ++
 dix/window.c              |  2 ++
 exa/exa_accel.c           | 12 ++++++++++++
 glamor/glamor_core.c      | 10 +++++++---
 hw/dmx/config/dmxconfig.c | 18 ++++++++++++++++++
 hw/dmx/dmxcursor.c        |  6 ++++--
 hw/dmx/dmxextension.c     |  3 +++
 hw/dmx/dmxfont.c          |  8 ++++++++
 hw/dmx/dmxgc.c            | 24 +++++++++++++-----------
 hw/dmx/dmxinit.c          | 14 +++++++++-----
 hw/dmx/dmxpict.c          |  8 ++++++++
 hw/dmx/dmxprop.c          | 15 ++++++++++++---
 hw/dmx/dmxwindow.c        | 48 +++++++++++++++++++++++++----------------------
 18 files changed, 161 insertions(+), 47 deletions(-)

diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 209df29..7b94ba7 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -807,7 +807,7 @@ extern void
 PanoramiXConsolidate(void)
 {
     int i;
-    PanoramiXRes *root, *defmap, *saver;
+    PanoramiXRes *root = NULL, *defmap = NULL, *saver = NULL;
     ScreenPtr pScreen = screenInfo.screens[0];
     DepthPtr pDepth = pScreen->allowedDepths;
     VisualPtr pVisual = pScreen->visuals;
@@ -822,10 +822,16 @@ PanoramiXConsolidate(void)
         PanoramiXMaybeAddVisual(pVisual++);
 
     root = malloc(sizeof(PanoramiXRes));
+    if (!root)
+        goto outOfMemory;
     root->type = XRT_WINDOW;
     defmap = malloc(sizeof(PanoramiXRes));
+    if (!defmap)
+        goto outOfMemory;
     defmap->type = XRT_COLORMAP;
     saver = malloc(sizeof(PanoramiXRes));
+    if (!saver)
+        goto outOfMemory;
     saver->type = XRT_WINDOW;
 
     FOR_NSCREENS(i) {
@@ -843,6 +849,13 @@ PanoramiXConsolidate(void)
     AddResource(root->info[0].id, XRT_WINDOW, root);
     AddResource(saver->info[0].id, XRT_WINDOW, saver);
     AddResource(defmap->info[0].id, XRT_COLORMAP, defmap);
+
+    return;
+
+ outOfMemory:
+    free(saver);
+    free(defmap);
+    free(root);
 }
 
 VisualID
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 9eb29bd..644175d 100644
--- a/Xext/panoramiXprocs.c
+++ b/Xext/panoramiXprocs.c
@@ -1342,6 +1342,8 @@ PanoramiXPolyPoint(ClientPtr client)
     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
     if (npoint > 0) {
         origPts = xallocarray(npoint, sizeof(xPoint));
+        if (!origPts)
+            return BadAlloc;
         memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1407,6 +1409,8 @@ PanoramiXPolyLine(ClientPtr client)
     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
     if (npoint > 0) {
         origPts = xallocarray(npoint, sizeof(xPoint));
+        if (!origPts)
+            return BadAlloc;
         memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1476,6 +1480,8 @@ PanoramiXPolySegment(ClientPtr client)
     nsegs >>= 3;
     if (nsegs > 0) {
         origSegs = xallocarray(nsegs, sizeof(xSegment));
+        if (!origSegs)
+            return BadAlloc;
         memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1544,6 +1550,8 @@ PanoramiXPolyRectangle(ClientPtr client)
     nrects >>= 3;
     if (nrects > 0) {
         origRecs = xallocarray(nrects, sizeof(xRectangle));
+        if (!origRecs)
+            return BadAlloc;
         memcpy((char *) origRecs, (char *) &stuff[1],
                nrects * sizeof(xRectangle));
         FOR_NSCREENS_FORWARD(j) {
@@ -1611,6 +1619,8 @@ PanoramiXPolyArc(ClientPtr client)
     narcs /= sizeof(xArc);
     if (narcs > 0) {
         origArcs = xallocarray(narcs, sizeof(xArc));
+        if (!origArcs)
+            return BadAlloc;
         memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1673,6 +1683,8 @@ PanoramiXFillPoly(ClientPtr client)
     count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
     if (count > 0) {
         locPts = xallocarray(count, sizeof(DDXPointRec));
+        if (!locPts)
+            return BadAlloc;
         memcpy((char *) locPts, (char *) &stuff[1],
                count * sizeof(DDXPointRec));
         FOR_NSCREENS_FORWARD(j) {
@@ -1742,6 +1754,8 @@ PanoramiXPolyFillRectangle(ClientPtr client)
     things >>= 3;
     if (things > 0) {
         origRects = xallocarray(things, sizeof(xRectangle));
+        if (!origRects)
+            return BadAlloc;
         memcpy((char *) origRects, (char *) &stuff[1],
                things * sizeof(xRectangle));
         FOR_NSCREENS_FORWARD(j) {
@@ -1809,6 +1823,8 @@ PanoramiXPolyFillArc(ClientPtr client)
     narcs /= sizeof(xArc);
     if (narcs > 0) {
         origArcs = xallocarray(narcs, sizeof(xArc));
+        if (!origArcs)
+            return BadAlloc;
         memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
         FOR_NSCREENS_FORWARD(j) {
 
diff --git a/Xext/xres.c b/Xext/xres.c
index 83cc691..023f6b0 100644
--- a/Xext/xres.c
+++ b/Xext/xres.c
@@ -224,6 +224,8 @@ ProcXResQueryClients(ClientPtr client)
     REQUEST_SIZE_MATCH(xXResQueryClientsReq);
 
     current_clients = xallocarray(currentMaxClients, sizeof(int));
+    if (!current_clients)
+        return BadAlloc;
 
     num_clients = 0;
     for (i = 0; i < currentMaxClients; i++) {
diff --git a/Xi/getprop.c b/Xi/getprop.c
index 19f18af..19339a4 100644
--- a/Xi/getprop.c
+++ b/Xi/getprop.c
@@ -119,6 +119,9 @@ ProcXGetDeviceDontPropagateList(ClientPtr client)
         if (count) {
             rep.count = count;
             buf = xallocarray(rep.count, sizeof(XEventClass));
+            if (!buf)
+                return BadAlloc;
+
             rep.length = bytes_to_int32(rep.count * sizeof(XEventClass));
 
             tbuf = buf;
diff --git a/Xi/getselev.c b/Xi/getselev.c
index 60a46c2..c1aaf9b 100644
--- a/Xi/getselev.c
+++ b/Xi/getselev.c
@@ -133,6 +133,8 @@ ProcXGetSelectedExtensionEvents(ClientPtr client)
             sizeof(XEventClass);
         rep.length = bytes_to_int32(total_length);
         buf = (XEventClass *) malloc(total_length);
+        if (!buf)
+            return BadAlloc;
 
         tclient = buf;
         aclient = buf + rep.this_client_count;
diff --git a/dix/enterleave.c b/dix/enterleave.c
index f0b1572..3be5449 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -715,6 +715,8 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
     }
 
     sev = ev = xallocarray(evcount, sizeof(xEvent));
+    if (!ev)
+        return;
     FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
 
     if (b != NULL) {
diff --git a/dix/window.c b/dix/window.c
index 25d29ec..579e6fa 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -3510,6 +3510,8 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
             return Success;
 
         pNewNode = malloc(sizeof(DevCursNodeRec));
+        if (!pNewNode)
+           return BadAlloc;
         pNewNode->dev = pDev;
         pNewNode->next = pWin->optional->deviceCursors;
         pWin->optional->deviceCursors = pNewNode;
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index b26d5c8..fbc1bda 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -627,6 +627,10 @@ exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
     }
 
     prect = xallocarray(npt, sizeof(xRectangle));
+    if (!prect) {
+        ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
+        return;
+    }
     for (i = 0; i < npt; i++) {
         prect[i].x = ppt[i].x;
         prect[i].y = ppt[i].y;
@@ -668,6 +672,10 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
     }
 
     prect = xallocarray(npt - 1, sizeof(xRectangle));
+    if (!prect) {
+        ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+        return;
+    }
     x1 = ppt[0].x;
     y1 = ppt[0].y;
     /* If we have any non-horizontal/vertical, fall back. */
@@ -739,6 +747,10 @@ exaPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
     }
 
     prect = xallocarray(nseg, sizeof(xRectangle));
+    if (!prect) {
+        ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
+        return;
+    }
     for (i = 0; i < nseg; i++) {
         if (pSeg[i].x1 < pSeg[i].x2) {
             prect[i].x = pSeg[i].x1;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 0104b88..f5f61cb 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -95,9 +95,13 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
 
         glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
         info = malloc(size);
-
-        glGetProgramInfoLog(prog, size, NULL, info);
-        ErrorF("Failed to link: %s\n", info);
+        if (info) {
+            glGetProgramInfoLog(prog, size, NULL, info);
+            ErrorF("Failed to link: %s\n", info);
+            free(info);
+        }
+        else
+            ErrorF("Failed to get shader link info.\n");
         FatalError("GLSL link failure\n");
     }
 
diff --git a/hw/dmx/config/dmxconfig.c b/hw/dmx/config/dmxconfig.c
index 1d10ec0..783ce73 100644
--- a/hw/dmx/config/dmxconfig.c
+++ b/hw/dmx/config/dmxconfig.c
@@ -85,7 +85,13 @@ dmxConfigStoreDisplay(const char *display)
 {
     DMXConfigListPtr entry = malloc(sizeof(*entry));
 
+    if (!entry)
+        return;
     entry->name = strdup(display);
+    if (!entry->name) {
+        free(entry);
+        return;
+    }
     entry->next = NULL;
     if (!dmxConfigCmd.displays)
         dmxConfigCmd.displays = entry;
@@ -107,7 +113,13 @@ dmxConfigStoreInput(const char *input)
 {
     DMXConfigListPtr entry = malloc(sizeof(*entry));
 
+    if (!entry)
+        return;
     entry->name = strdup(input);
+    if (!entry->name) {
+        free(entry);
+        return;
+    }
     entry->next = NULL;
     if (!dmxConfigCmd.inputs)
         dmxConfigCmd.inputs = entry;
@@ -128,7 +140,13 @@ dmxConfigStoreXInput(const char *input)
 {
     DMXConfigListPtr entry = malloc(sizeof(*entry));
 
+    if (!entry)
+        return;
     entry->name = strdup(input);
+    if (!entry->name) {
+        free(entry);
+        return;
+    }
     entry->next = NULL;
     if (!dmxConfigCmd.xinputs)
         dmxConfigCmd.xinputs = entry;
diff --git a/hw/dmx/dmxcursor.c b/hw/dmx/dmxcursor.c
index 0ef800e..10892ff 100644
--- a/hw/dmx/dmxcursor.c
+++ b/hw/dmx/dmxcursor.c
@@ -206,8 +206,10 @@ dmxSLCreate(void)
     int *list = xallocarray(dmxNumScreens, sizeof(*list));
     int i;
 
-    for (i = 0; i < dmxNumScreens; i++)
-        list[i] = 1;
+    if (list) {
+        for (i = 0; i < dmxNumScreens; i++)
+            list[i] = 1;
+    }
     return list;
 }
 
diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c
index 75d7166..da0d854 100644
--- a/hw/dmx/dmxextension.c
+++ b/hw/dmx/dmxextension.c
@@ -1190,6 +1190,8 @@ dmxBERestoreRenderGlyph(void *value, XID id, void *n)
     images = calloc(len_images, sizeof(char));
     gids = xallocarray(glyphSet->hash.tableEntries, sizeof(Glyph));
     glyphs = xallocarray(glyphSet->hash.tableEntries, sizeof(XGlyphInfo));
+    if (!images || !gids || !glyphs)
+        goto outOfMemory;
 
     pos = images;
     ctr = 0;
@@ -1224,6 +1226,7 @@ dmxBERestoreRenderGlyph(void *value, XID id, void *n)
                      gids, glyphs, glyphSet->hash.tableEntries, images,
                      len_images);
 
+ outOfMemory:
     /* Clean up */
     free(images);
     free(gids);
diff --git a/hw/dmx/dmxfont.c b/hw/dmx/dmxfont.c
index 25a04a6..1a8ec29 100644
--- a/hw/dmx/dmxfont.c
+++ b/hw/dmx/dmxfont.c
@@ -71,8 +71,14 @@ dmxGetFontPath(int *npaths)
     GetFontPath(serverClient, npaths, &len, &paths);
 
     newfp = malloc(*npaths + len);
+    if (!newfp)
+        return NULL;
     c = (unsigned char *) newfp;
     fp = xallocarray(*npaths, sizeof(*fp));
+    if (!fp) {
+        free(newfp);
+        return NULL;
+    }
 
     memmove(newfp, paths + 1, *npaths + len - 1);
     l = *paths;
@@ -204,6 +210,8 @@ dmxProcSetFontPath(ClientPtr client)
 
     GetFontPath(serverClient, &nOldPaths, &lenOldPaths, &tmpFontPath);
     oldFontPath = malloc(nOldPaths + lenOldPaths);
+    if (!oldFontPath)
+        return BadAlloc;
     memmove(oldFontPath, tmpFontPath, nOldPaths + lenOldPaths);
 
     result = SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]);
diff --git a/hw/dmx/dmxgc.c b/hw/dmx/dmxgc.c
index c4789a6..d974a4b 100644
--- a/hw/dmx/dmxgc.c
+++ b/hw/dmx/dmxgc.c
@@ -400,18 +400,20 @@ dmxChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
             pRects = xallocarray(nRects, sizeof(*pRects));
             pBox = RegionRects((RegionPtr) pGC->clientClip);
 
-            for (i = 0; i < nRects; i++) {
-                pRects[i].x = pBox[i].x1;
-                pRects[i].y = pBox[i].y1;
-                pRects[i].width = pBox[i].x2 - pBox[i].x1;
-                pRects[i].height = pBox[i].y2 - pBox[i].y1;
+            if (pRects) {
+                for (i = 0; i < nRects; i++) {
+                    pRects[i].x = pBox[i].x1;
+                    pRects[i].y = pBox[i].y1;
+                    pRects[i].width = pBox[i].x2 - pBox[i].x1;
+                    pRects[i].height = pBox[i].y2 - pBox[i].y1;
+                }
+
+                XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
+                                   pGC->clipOrg.x, pGC->clipOrg.y,
+                                   pRects, nRects, Unsorted);
+
+                free(pRects);
             }
-
-            XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
-                               pGC->clipOrg.x, pGC->clipOrg.y,
-                               pRects, nRects, Unsorted);
-
-            free(pRects);
         }
     }
 
diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c
index 3d394c5..fc4d871 100644
--- a/hw/dmx/dmxinit.c
+++ b/hw/dmx/dmxinit.c
@@ -441,11 +441,13 @@ dmxGetColormaps(DMXScreenInfo * dmxScreen)
     dmxScreen->beDefColormaps = xallocarray(dmxScreen->beNumDefColormaps,
                                        sizeof(*dmxScreen->beDefColormaps));
 
-    for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
-        dmxScreen->beDefColormaps[i] =
-            XCreateColormap(dmxScreen->beDisplay,
-                            DefaultRootWindow(dmxScreen->beDisplay),
-                            dmxScreen->beVisuals[i].visual, AllocNone);
+    if (dmxScreen->beDefColormaps) {
+        for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
+            dmxScreen->beDefColormaps[i] =
+                XCreateColormap(dmxScreen->beDisplay,
+                                DefaultRootWindow(dmxScreen->beDisplay),
+                                dmxScreen->beVisuals[i].visual, AllocNone);
+    }
 
     dmxScreen->beBlackPixel = BlackPixel(dmxScreen->beDisplay,
                                          DefaultScreen(dmxScreen->beDisplay));
@@ -805,6 +807,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
 
                     configprivs[j] = (dmxGlxVisualPrivate *)
                         malloc(sizeof(dmxGlxVisualPrivate));
+                    if (!configprivs[j])
+                        continue;
                     configprivs[j]->x_visual_depth = 0;
                     configprivs[j]->x_visual_class = 0;
 
diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c
index 1f1022e..287e9e2 100644
--- a/hw/dmx/dmxpict.c
+++ b/hw/dmx/dmxpict.c
@@ -391,6 +391,8 @@ dmxProcRenderAddGlyphs(ClientPtr client)
                   (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs);
 
         gidsCopy = xallocarray(nglyphs, sizeof(*gidsCopy));
+        if (!gidsCopy)
+            return BadAlloc;
         for (i = 0; i < nglyphs; i++)
             gidsCopy[i] = gids[i];
 
@@ -435,6 +437,8 @@ dmxProcRenderFreeGlyphs(ClientPtr client)
         nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2;
         if (nglyphs) {
             gids = xallocarray(nglyphs, sizeof(*gids));
+            if (!gids)
+                return BadAlloc;
             for (i = 0; i < nglyphs; i++)
                 gids[i] = ((CARD32 *) (stuff + 1))[i];
 
@@ -926,6 +930,10 @@ dmxChangePictureClip(PicturePtr pPicture, int clipType, void *value, int n)
 
             nRects = nBox;
             pRects = pRect = xallocarray(nRects, sizeof(*pRect));
+            if (!pRects) {
+                DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);
+                return BadAlloc;
+            }
 
             while (nBox--) {
                 pRect->x = pBox->x1;
diff --git a/hw/dmx/dmxprop.c b/hw/dmx/dmxprop.c
index 4c85268..dfe5d60 100644
--- a/hw/dmx/dmxprop.c
+++ b/hw/dmx/dmxprop.c
@@ -159,6 +159,7 @@ dmxPropertyCheckOtherServers(DMXScreenInfo * dmxScreen, Atom atom)
             if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
                 if (!strncmp((char *) tp.value, DMX_IDENT, strlen(DMX_IDENT))) {
                     int flag = 0;
+                    char **newlist;
 
                     for (i = 0; i < count; i++)
                         if (!strcmp(list[i], (char *) tp.value)) {
@@ -171,9 +172,17 @@ dmxPropertyCheckOtherServers(DMXScreenInfo * dmxScreen, Atom atom)
                     dmxLogOutputWarning(dmxScreen,
                                         "%s also running on %s\n",
                                         tp.value, dmxScreen->name);
-                    list = reallocarray(list, ++count, sizeof(*list));
-                    list[count - 1] = malloc(tp.nitems + 2);
-                    strncpy(list[count - 1], (char *) tp.value, tp.nitems + 1);
+                    newlist = reallocarray(list, ++count, sizeof(*list));
+                    if (newlist) {
+                        list = newlist;
+                        list[count - 1] = malloc(tp.nitems + 2);
+                        if (list[count - 1])
+                            strncpy(list[count - 1], (char *) tp.value,
+                                    tp.nitems + 1);
+                    } else {
+                        count--;
+                        retcode--;
+                    }
                 }
                 XFree(tp.value);
             }
diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c
index dcdb9ac..1e8f4fd 100644
--- a/hw/dmx/dmxwindow.c
+++ b/hw/dmx/dmxwindow.c
@@ -970,18 +970,20 @@ dmxDoSetShape(WindowPtr pWindow)
         pBox = RegionRects(wBoundingShape(pWindow));
         nRect = nBox = RegionNumRects(wBoundingShape(pWindow));
         pRectFirst = pRect = xallocarray(nRect, sizeof(*pRect));
-        while (nBox--) {
-            pRect->x = pBox->x1;
-            pRect->y = pBox->y1;
-            pRect->width = pBox->x2 - pBox->x1;
-            pRect->height = pBox->y2 - pBox->y1;
-            pBox++;
-            pRect++;
+        if (pRectFirst) {
+            while (nBox--) {
+                pRect->x = pBox->x1;
+                pRect->y = pBox->y1;
+                pRect->width = pBox->x2 - pBox->x1;
+                pRect->height = pBox->y2 - pBox->y1;
+                pBox++;
+                pRect++;
+            }
+            XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
+                                    ShapeBounding, 0, 0,
+                                    pRectFirst, nRect, ShapeSet, YXBanded);
+            free(pRectFirst);
         }
-        XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
-                                ShapeBounding, 0, 0,
-                                pRectFirst, nRect, ShapeSet, YXBanded);
-        free(pRectFirst);
     }
     else {
         XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
@@ -993,18 +995,20 @@ dmxDoSetShape(WindowPtr pWindow)
         pBox = RegionRects(wClipShape(pWindow));
         nRect = nBox = RegionNumRects(wClipShape(pWindow));
         pRectFirst = pRect = xallocarray(nRect, sizeof(*pRect));
-        while (nBox--) {
-            pRect->x = pBox->x1;
-            pRect->y = pBox->y1;
-            pRect->width = pBox->x2 - pBox->x1;
-            pRect->height = pBox->y2 - pBox->y1;
-            pBox++;
-            pRect++;
+        if (pRectFirst) {
+            while (nBox--) {
+                pRect->x = pBox->x1;
+                pRect->y = pBox->y1;
+                pRect->width = pBox->x2 - pBox->x1;
+                pRect->height = pBox->y2 - pBox->y1;
+                pBox++;
+                pRect++;
+            }
+            XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
+                                    ShapeClip, 0, 0,
+                                    pRectFirst, nRect, ShapeSet, YXBanded);
+            free(pRectFirst);
         }
-        XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
-                                ShapeClip, 0, 0,
-                                pRectFirst, nRect, ShapeSet, YXBanded);
-        free(pRectFirst);
     }
     else {
         XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
-- 
2.6.3



More information about the xorg-devel mailing list