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
