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;

Attachment: ShmGetOOBTest.java
Description: Binary data

Reply via email to