Hi, I've recently encountered some BadMatch errors triggered by fallbacks. Those are caused by reading outside of surface bounds using the cached ShmPixmap.
Testcase and patch attached. Running with -Dsun.awt.noisyerrorhandler=True the testcase causes a BadMatch: > Xerror BadMatch (invalid parameter attributes), XID 5000017, ser# 215 > Major opcode 139 //SHM > Minor opcode 4 //GetImage If a X11SDOps structure belongs to a pixmap I can directly use pmWidth/Height, but for windows I have to query the attributes width/height. Is there a better way to get window's width/height, maybe through some of AWT's structures? - Clemens
--- old/src/solaris/native/sun/java2d/x11/X11SurfaceData.c 2010-11-13 18:32:30.688184052 +0100 +++ new/src/solaris/native/sun/java2d/x11/X11SurfaceData.c 2010-11-13 18:32:30.354433458 +0100 @@ -595,11 +595,11 @@ } XImage* X11SD_GetSharedImage(X11SDOps *xsdo, jint width, jint height, - jboolean readBits) + jint maxWidth, jint maxHeight, jboolean readBits) { XImage * retImage = NULL; if (cachedXImage != NULL && - X11SD_CachedXImageFits(width, height, xsdo->depth, readBits)) { + X11SD_CachedXImageFits(width, height, maxWidth, maxHeight, xsdo->depth, readBits)) { /* sync so previous data gets flushed */ XSync(awt_display, False); retImage = cachedXImage; @@ -728,8 +728,8 @@ * it must be close enough to avoid excessive reading from the screen; * otherwise it should just be at least the size requested. */ -jboolean X11SD_CachedXImageFits(jint width, jint height, jint depth, - jboolean readBits) +jboolean X11SD_CachedXImageFits(jint width, jint height, jint maxWidth, + jint maxHeight, jint depth, jboolean readBits) { /* we assume here that the cached image exists */ jint imgWidth = cachedXImage->width; @@ -747,10 +747,13 @@ return JNI_TRUE; } - if ((imgWidth < width + 64) && (imgHeight < height + 64)) { + if ((imgWidth < width + 64) && (imgHeight < height + 64) + && imgWidth <= maxWidth && imgHeight <= maxHeight) { /* Cached image's width/height shouldn't be more than 64 pixels * larger than requested, because the region in XShmGetImage * can't be specified and we don't want to read too much. + * Furthermore it has to be smaller than maxWidth/Height + * so drawables are not read out of bounds. */ return JNI_TRUE; } @@ -1295,7 +1298,7 @@ SurfaceDataBounds *bounds, jint lockFlags) { - int x, y, w, h; + int x, y, w, h, maxWidth, maxHeight; int scan; XImage * img = NULL; Drawable drawable; @@ -1311,10 +1314,25 @@ #ifdef MITSHM if (useMitShmExt == CAN_USE_MITSHM) { - if (xsdo->isPixmap && readBits) { + if (xsdo->isPixmap) { + if(readBits) { X11SD_PuntPixmap(xsdo, w, h); - } - img = X11SD_GetSharedImage(xsdo, w, h, readBits); + } + + maxWidth = xsdo->pmWidth; + maxHeight = xsdo->pmHeight; + } else { + XWindowAttributes winAttr; + if(XGetWindowAttributes(awt_display, (Window) xsdo->drawable, &winAttr) != 0) { + maxWidth = winAttr.width; + maxHeight = winAttr.height; + } + } + + maxWidth -= x; + maxHeight -= y; + + img = X11SD_GetSharedImage(xsdo, w, h, maxWidth, maxHeight, readBits); } #endif /* MITSHM */ drawable = xsdo->drawable;
ShmGetOOBTest.java
Description: Binary data