Subject: bug#44930: I can reproduce it

From: Alan Third <[email-masked]>
Date: Sat, 5 Dec 2020 19:44:13 +0000

On Sat, Dec 05, 2020 at 05:08:15PM +0100, Francesco Potortì wrote:
> >>> In this moment I have a *w3m* buffer on a live Emacs.  If I switch to it
> >>> on a text frame, everything is well.  If I switch to it on an X display,
> >>> the frame dies (but Emacs survives).  The error is
> >>> 
> >>> X protocol error: BadMatch (invalid parameter attributes) on protocol request 73
> 
> I managed to find the time to compile emacs with symbols.
> 
> The previous instance of Emacs crashed, so apparently there is a serious
> problem somewhere.
> 
> On the plus side, now apparently every instance of a *w3m* buffer
> exhibits the problem, which is now easy to reproduce for me.
> 
> The error is:
>   redisplay: X protocol error: BadMatch (invalid parameter attributes) on protocol request 73
> which points to an XGetImage call where the pixmap or window to be
> returned does not satisfy certain geometric criteria, according to
>   https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#requests:GetImage  
> 
> Setting debug-on-error to t tells me that this happens inside
> redisplay_internal().
> 
> I evaluated (x-synchronize t) and then switched to the *w3b* buffer.
> 
> Here is the backtrace.  If you help me I can try and continue debugging.
<snip>
> #5  0x00007fc6655e033a in XGetImage () at /usr/lib/x86_64-linux-gnu/libX11.so.6
> #6  0x00005596a19c3788 in image_get_x_image (f=<optimized out>, img=img@entry=0x5596a57dccd0, mask_p=mask_p@entry=false) at ./debian/build-src/src/image.c:2934
> #7  0x00005596a19c938e in image_background (img=0x5596a57dccd0, f=<optimized out>, pimg=pimg@entry=0x0) at ./debian/build-src/src/image.c:1376

Hmm, my suspicion here is that we're calling XGetImage with dimensions
that don't match the pixmap since we no longer store the dimensions of
the original image.

It hadn't occurred to me that we'd ever pull the image BACK from the X
server.

Can you try with the attached patch, please?
-- 
Alan Third
>From b2457ae612bd53c3d08cec7ddba703f400a78a2d Mon Sep 17 00:00:00 2001
From: Alan Third <[email-masked]>
Date: Sat, 5 Dec 2020 19:40:08 +0000
Subject: [PATCH] Fix crash when using XRender and restoring image from X
 (bug#44930)

* src/dispextern.h (struct image): Add original dimension elements.
* src/image.c (image_set_transform): Store the original dimensions.
(image_get_x_image): If we're using transforms use the original
dimensions with XGetImage.
---
 src/dispextern.h | 4 ++++
 src/image.c      | 9 +++++++++
 2 files changed, 13 insertions(+)

diff --git a/src/dispextern.h b/src/dispextern.h
index da51772b37..c76822ff39 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3040,6 +3040,10 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
 # if !defined USE_CAIRO && defined HAVE_XRENDER
   /* Picture versions of pixmap and mask for compositing.  */
   Picture picture, mask_picture;
+
+  /* We need to store the original image dimensions in case we have to
+     call XGetImage.  */
+  int original_width, original_height;
 # endif
 #endif	/* HAVE_X_WINDOWS */
 #ifdef HAVE_NTGUI
diff --git a/src/image.c b/src/image.c
index 5eb4132295..9494f9ddc6 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2131,6 +2131,10 @@ image_set_transform (struct frame *f, struct image *img)
 # if !defined USE_CAIRO && defined HAVE_XRENDER
   if (!img->picture)
     return;
+
+  /* Store the original dimensions as we'll overwrite them later.  */
+  img->original_width = img->width;
+  img->original_height = img->height;
 # endif
 
   /* Determine size.  */
@@ -2990,6 +2994,11 @@ image_get_x_image (struct frame *f, struct image *img, bool mask_p)
 
   if (ximg_in_img)
     return ximg_in_img;
+#ifdef HAVE_XRENDER
+  else if (img->picture)
+    return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
+		      0, 0, img->original_width, img->original_height, ~0, ZPixmap);
+#endif
   else
     return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
 		      0, 0, img->width, img->height, ~0, ZPixmap);
-- 
2.29.2