From 11bd10a7df907289382bd6f06753e274376d7629 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 2 Oct 2014 19:20:52 -0700 Subject: [PATCH] Fix x-focus-frame bug with "Not an in-range integer". * xselect.c (X_SHRT_MAX, X_SHRT_MIN, X_LONG_MAX, X_LONG_MIN) (X_ULONG_MAX): Move these macros to xterm.h. (x_fill_property_data): Be more generous about allowing either signed or unsigned data of the appropriate width. * xterm.h (x_display_set_last_user_time): New function. All setters of last_user_time changd to use this function. If ENABLE_CHECKING, check that the times are in range. Fixes: debbugs:18586 --- src/ChangeLog | 11 +++++++++++ src/xselect.c | 35 +++++++++++++---------------------- src/xterm.c | 20 ++++++++++---------- src/xterm.h | 18 +++++++++++++++++- 4 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 4e10e606c87..f5f1d8e0458 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2014-10-03 Paul Eggert + + Fix x-focus-frame bug with "Not an in-range integer" (Bug#18586). + * xselect.c (X_SHRT_MAX, X_SHRT_MIN, X_LONG_MAX, X_LONG_MIN) + (X_ULONG_MAX): Move these macros to xterm.h. + (x_fill_property_data): Be more generous about allowing either + signed or unsigned data of the appropriate width. + * xterm.h (x_display_set_last_user_time): New function. + All setters of last_user_time changd to use this function. + If ENABLE_CHECKING, check that the times are in range. + 2014-10-02 Eli Zaretskii * dispnew.c (adjust_decode_mode_spec_buffer): Use 'int' instead of diff --git a/src/xselect.c b/src/xselect.c index a06243f5924..9b57a95b26b 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -96,13 +96,6 @@ static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions; is not necessarily sizeof (long). */ #define X_LONG_SIZE 4 -/* Extreme 'short' and 'long' values suitable for libX11. */ -#define X_SHRT_MAX 0x7fff -#define X_SHRT_MIN (-1 - X_SHRT_MAX) -#define X_LONG_MAX 0x7fffffff -#define X_LONG_MIN (-1 - X_LONG_MAX) -#define X_ULONG_MAX 0xffffffffUL - /* If this is a smaller number than the max-request-size of the display, emacs will use INCR selection transfer when the selection is larger than this. The max-request-size is usually around 64k, so if you want @@ -2284,10 +2277,10 @@ x_check_property_data (Lisp_Object data) void x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) { - long val; - long *d32 = (long *) ret; - short *d16 = (short *) ret; - char *d08 = (char *) ret; + unsigned long val; + unsigned long *d32 = (unsigned long *) ret; + unsigned short *d16 = (unsigned short *) ret; + unsigned char *d08 = (unsigned char *) ret; Lisp_Object iter; for (iter = data; CONSP (iter); iter = XCDR (iter)) @@ -2300,16 +2293,16 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) && RANGED_INTEGERP (X_LONG_MIN >> 16, XCAR (o), X_LONG_MAX >> 16) && RANGED_INTEGERP (- (1 << 15), XCDR (o), -1)) { - long v1 = XINT (XCAR (o)); - long v2 = XINT (XCDR (o)); - /* cons_to_signed does not handle negative values for v2. + /* cons_to_x_long does not handle negative values for v2. For XDnd, v2 might be y of a window, and can be negative. The XDnd spec. is not explicit about negative values, but let's assume negative v2 is sent modulo 2**16. */ - val = (v1 << 16) | (v2 & 0xffff); + unsigned long v1 = XINT (XCAR (o)) & 0xffff; + unsigned long v2 = XINT (XCDR (o)) & 0xffff; + val = (v1 << 16) | v2; } else - val = cons_to_signed (o, X_LONG_MIN, X_LONG_MAX); + val = cons_to_x_long (o); } else if (STRINGP (o)) { @@ -2322,17 +2315,15 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) if (format == 8) { - if (CHAR_MIN <= val && val <= CHAR_MAX) - *d08++ = val; - else + if ((1 << 8) < val && val <= X_ULONG_MAX - (1 << 7)) error ("Out of 'char' range"); + *d08++ = val; } else if (format == 16) { - if (X_SHRT_MIN <= val && val <= X_SHRT_MAX) - *d16++ = val; - else + if ((1 << 16) < val && val <= X_ULONG_MAX - (1 << 15)) error ("Out of 'short' range"); + *d16++ = val; } else *d32++ = val; diff --git a/src/xterm.c b/src/xterm.c index 8546dc426d8..aff57f6a17e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -6802,7 +6802,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, break; case SelectionNotify: - dpyinfo->last_user_time = event->xselection.time; + x_display_set_last_user_time (dpyinfo, event->xselection.time); #ifdef USE_X_TOOLKIT if (! x_window_to_frame (dpyinfo, event->xselection.requestor)) goto OTHER; @@ -6811,7 +6811,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, break; case SelectionClear: /* Someone has grabbed ownership. */ - dpyinfo->last_user_time = event->xselectionclear.time; + x_display_set_last_user_time (dpyinfo, event->xselectionclear.time); #ifdef USE_X_TOOLKIT if (! x_window_to_frame (dpyinfo, event->xselectionclear.window)) goto OTHER; @@ -6827,7 +6827,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, break; case SelectionRequest: /* Someone wants our selection. */ - dpyinfo->last_user_time = event->xselectionrequest.time; + x_display_set_last_user_time (dpyinfo, event->xselectionrequest.time); #ifdef USE_X_TOOLKIT if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner)) goto OTHER; @@ -6846,7 +6846,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, break; case PropertyNotify: - dpyinfo->last_user_time = event->xproperty.time; + x_display_set_last_user_time (dpyinfo, event->xproperty.time); f = x_top_window_to_frame (dpyinfo, event->xproperty.window); if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state) { @@ -7044,7 +7044,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, case KeyPress: - dpyinfo->last_user_time = event->xkey.time; + x_display_set_last_user_time (dpyinfo, event->xkey.time); ignore_next_mouse_click_timeout = 0; #if defined (USE_X_TOOLKIT) || defined (USE_GTK) @@ -7378,7 +7378,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif case KeyRelease: - dpyinfo->last_user_time = event->xkey.time; + x_display_set_last_user_time (dpyinfo, event->xkey.time); #ifdef HAVE_X_I18N /* Don't dispatch this event since XtDispatchEvent calls XFilterEvent, and two calls in a row may freeze the @@ -7389,7 +7389,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif case EnterNotify: - dpyinfo->last_user_time = event->xcrossing.time; + x_display_set_last_user_time (dpyinfo, event->xcrossing.time); x_detect_focus_change (dpyinfo, any, event, &inev.ie); f = any; @@ -7414,7 +7414,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case LeaveNotify: - dpyinfo->last_user_time = event->xcrossing.time; + x_display_set_last_user_time (dpyinfo, event->xcrossing.time); x_detect_focus_change (dpyinfo, any, event, &inev.ie); f = x_top_window_to_frame (dpyinfo, event->xcrossing.window); @@ -7448,7 +7448,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, case MotionNotify: { - dpyinfo->last_user_time = event->xmotion.time; + x_display_set_last_user_time (dpyinfo, event->xmotion.time); previous_help_echo_string = help_echo_string; help_echo_string = Qnil; @@ -7588,7 +7588,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, memset (&compose_status, 0, sizeof (compose_status)); dpyinfo->last_mouse_glyph_frame = NULL; - dpyinfo->last_user_time = event->xbutton.time; + x_display_set_last_user_time (dpyinfo, event->xbutton.time); f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame : x_window_to_frame (dpyinfo, event->xbutton.window)); diff --git a/src/xterm.h b/src/xterm.h index c8673123611..ed611f1d19f 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -434,7 +434,7 @@ extern void select_visual (struct x_display_info *); struct x_output { -#if defined (USE_X_TOOLKIT) || defined (USE_GTK) +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) /* Height of menu bar widget, in pixels. This value is not meaningful if the menubar is turned off. */ int menubar_height; @@ -654,6 +654,13 @@ struct x_output int move_offset_left; }; +/* Extreme 'short' and 'long' values suitable for libX11. */ +#define X_SHRT_MAX 0x7fff +#define X_SHRT_MIN (-1 - X_SHRT_MAX) +#define X_LONG_MAX 0x7fffffff +#define X_LONG_MIN (-1 - X_LONG_MAX) +#define X_ULONG_MAX 0xffffffffUL + #define No_Cursor (None) enum @@ -1022,6 +1029,15 @@ x_display_pixel_width (struct x_display_info *dpyinfo) return WidthOfScreen (dpyinfo->screen); } +INLINE void +x_display_set_last_user_time (struct x_display_info *dpyinfo, Time t) +{ +#ifdef ENABLE_CHECKING + eassert (t <= X_ULONG_MAX); +#endif + dpyinfo->last_user_time = t; +} + extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); extern void x_wait_for_event (struct frame *, int); extern void x_clear_under_internal_border (struct frame *f); -- 2.11.4.GIT