From 341b2f43e511e39dd6a938e8fbdef8a0d5e66c9a Mon Sep 17 00:00:00 2001 From: Mathias Gumz <akira at fluxbox dot org> Date: Mon, 21 Feb 2011 19:21:38 +0100 Subject: Fix bug: 'src_image' might be NULL if width||height are 0 (#3188223) With ROT90-SystemTray fluxbox crashed. It is a bit unclear of where to catch pixmaps / windows with either width or height equal to 0; IMHO this needs more investigation. --- src/FbTk/FbPixmap.cc | 89 +++++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc index a347e23..160d478 100644 --- a/src/FbTk/FbPixmap.cc +++ b/src/FbTk/FbPixmap.cc @@ -218,61 +218,70 @@ void FbPixmap::rotate(FbTk::Orientation orient) { unsigned int neww = oldw, newh = oldh; translateSize(orient, neww, newh); + // reverse height/width for new pixmap + FbPixmap new_pm(drawable(), neww, newh, depth()); + + // width|height could be 0. this happens (for example) if + // the systemtray-tool is ROT90. in that case 'src_image' + // becomes NULL and caused a SIGSEV upon XDestroyImage() + // TODO: catch dimensions with '0' earlier? + // // make an image copy XImage *src_image = XGetImage(display(), drawable(), 0, 0, // pos oldw, oldh, // size ~0, // plane mask ZPixmap); // format - // reverse height/width for new pixmap - FbPixmap new_pm(drawable(), neww, newh, depth()); + if (src_image) { - GContext gc(drawable()); + GContext gc(drawable()); - if (orient == ROT180) { - unsigned int srcx, srcy, destx, desty; - for (srcy = 0, desty = oldh; srcy < oldh; ++srcy, --desty) { - for (srcx = 0, destx = oldw; srcx < oldw; ++srcx, --destx) { - gc.setForeground(XGetPixel(src_image, srcx, srcy)); - XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); + if (orient == ROT180) { + unsigned int srcx, srcy, destx, desty; + for (srcy = 0, desty = oldh; srcy < oldh; ++srcy, --desty) { + for (srcx = 0, destx = oldw; srcx < oldw; ++srcx, --destx) { + gc.setForeground(XGetPixel(src_image, srcx, srcy)); + XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); + } + } + } else { + // need to flip x and y + + // set start, end and direction based on rotation + // NOTE that startx etc are in the direction of the OLD pixmap + unsigned int startx = 0, starty = 0; + int dirx = 0, diry = 0; + switch (orient) { + case ROT90: + startx = neww-1; + starty = 0; + dirx = -1; + diry = 1; + break; + case ROT270: + startx = 0; + starty = newh-1; + dirx = 1; + diry = -1; + break; + default: // kill warning + break; } - } - } else { - // need to flip x and y - - // set start, end and direction based on rotation - // NOTE that startx etc are in the direction of the OLD pixmap - unsigned int startx = 0, starty = 0; - int dirx = 0, diry = 0; - switch (orient) { - case ROT90: - startx = neww-1; - starty = 0; - dirx = -1; - diry = 1; - break; - case ROT270: - startx = 0; - starty = newh-1; - dirx = 1; - diry = -1; - break; - default: // kill warning - break; - } - // copy new area - unsigned int srcx, srcy, destx, desty; - for (srcy = 0, destx = startx; srcy < oldh; ++srcy, destx+=dirx) { - for (srcx = 0, desty = starty; srcx < oldw; ++srcx, desty+=diry) { - gc.setForeground(XGetPixel(src_image, srcx, srcy)); - XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); + // copy new area + unsigned int srcx, srcy, destx, desty; + for (srcy = 0, destx = startx; srcy < oldh; ++srcy, destx+=dirx) { + for (srcx = 0, desty = starty; srcx < oldw; ++srcx, desty+=diry) { + gc.setForeground(XGetPixel(src_image, srcx, srcy)); + XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); + } } } + + XDestroyImage(src_image); } - XDestroyImage(src_image); // free old pixmap and set new from new_pm free(); -- cgit v0.11.2