diff options
| author | Paul Eggert | 2014-10-02 19:20:52 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-10-02 19:20:52 -0700 |
| commit | 11bd10a7df907289382bd6f06753e274376d7629 (patch) | |
| tree | 328d75ecf3ac1c6e1c391ad503577f4853f2708c /src | |
| parent | 7118822435bafe077c73b026e9e463a10e96f09a (diff) | |
| download | emacs-11bd10a7df907289382bd6f06753e274376d7629.tar.gz emacs-11bd10a7df907289382bd6f06753e274376d7629.zip | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/xselect.c | 35 | ||||
| -rw-r--r-- | src/xterm.c | 20 | ||||
| -rw-r--r-- | 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 @@ | |||
| 1 | 2014-10-03 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix x-focus-frame bug with "Not an in-range integer" (Bug#18586). | ||
| 4 | * xselect.c (X_SHRT_MAX, X_SHRT_MIN, X_LONG_MAX, X_LONG_MIN) | ||
| 5 | (X_ULONG_MAX): Move these macros to xterm.h. | ||
| 6 | (x_fill_property_data): Be more generous about allowing either | ||
| 7 | signed or unsigned data of the appropriate width. | ||
| 8 | * xterm.h (x_display_set_last_user_time): New function. | ||
| 9 | All setters of last_user_time changd to use this function. | ||
| 10 | If ENABLE_CHECKING, check that the times are in range. | ||
| 11 | |||
| 1 | 2014-10-02 Eli Zaretskii <eliz@gnu.org> | 12 | 2014-10-02 Eli Zaretskii <eliz@gnu.org> |
| 2 | 13 | ||
| 3 | * dispnew.c (adjust_decode_mode_spec_buffer): Use 'int' instead of | 14 | * 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; | |||
| 96 | is not necessarily sizeof (long). */ | 96 | is not necessarily sizeof (long). */ |
| 97 | #define X_LONG_SIZE 4 | 97 | #define X_LONG_SIZE 4 |
| 98 | 98 | ||
| 99 | /* Extreme 'short' and 'long' values suitable for libX11. */ | ||
| 100 | #define X_SHRT_MAX 0x7fff | ||
| 101 | #define X_SHRT_MIN (-1 - X_SHRT_MAX) | ||
| 102 | #define X_LONG_MAX 0x7fffffff | ||
| 103 | #define X_LONG_MIN (-1 - X_LONG_MAX) | ||
| 104 | #define X_ULONG_MAX 0xffffffffUL | ||
| 105 | |||
| 106 | /* If this is a smaller number than the max-request-size of the display, | 99 | /* If this is a smaller number than the max-request-size of the display, |
| 107 | emacs will use INCR selection transfer when the selection is larger | 100 | emacs will use INCR selection transfer when the selection is larger |
| 108 | than this. The max-request-size is usually around 64k, so if you want | 101 | 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) | |||
| 2284 | void | 2277 | void |
| 2285 | x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | 2278 | x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) |
| 2286 | { | 2279 | { |
| 2287 | long val; | 2280 | unsigned long val; |
| 2288 | long *d32 = (long *) ret; | 2281 | unsigned long *d32 = (unsigned long *) ret; |
| 2289 | short *d16 = (short *) ret; | 2282 | unsigned short *d16 = (unsigned short *) ret; |
| 2290 | char *d08 = (char *) ret; | 2283 | unsigned char *d08 = (unsigned char *) ret; |
| 2291 | Lisp_Object iter; | 2284 | Lisp_Object iter; |
| 2292 | 2285 | ||
| 2293 | for (iter = data; CONSP (iter); iter = XCDR (iter)) | 2286 | 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) | |||
| 2300 | && RANGED_INTEGERP (X_LONG_MIN >> 16, XCAR (o), X_LONG_MAX >> 16) | 2293 | && RANGED_INTEGERP (X_LONG_MIN >> 16, XCAR (o), X_LONG_MAX >> 16) |
| 2301 | && RANGED_INTEGERP (- (1 << 15), XCDR (o), -1)) | 2294 | && RANGED_INTEGERP (- (1 << 15), XCDR (o), -1)) |
| 2302 | { | 2295 | { |
| 2303 | long v1 = XINT (XCAR (o)); | 2296 | /* cons_to_x_long does not handle negative values for v2. |
| 2304 | long v2 = XINT (XCDR (o)); | ||
| 2305 | /* cons_to_signed does not handle negative values for v2. | ||
| 2306 | For XDnd, v2 might be y of a window, and can be negative. | 2297 | For XDnd, v2 might be y of a window, and can be negative. |
| 2307 | The XDnd spec. is not explicit about negative values, | 2298 | The XDnd spec. is not explicit about negative values, |
| 2308 | but let's assume negative v2 is sent modulo 2**16. */ | 2299 | but let's assume negative v2 is sent modulo 2**16. */ |
| 2309 | val = (v1 << 16) | (v2 & 0xffff); | 2300 | unsigned long v1 = XINT (XCAR (o)) & 0xffff; |
| 2301 | unsigned long v2 = XINT (XCDR (o)) & 0xffff; | ||
| 2302 | val = (v1 << 16) | v2; | ||
| 2310 | } | 2303 | } |
| 2311 | else | 2304 | else |
| 2312 | val = cons_to_signed (o, X_LONG_MIN, X_LONG_MAX); | 2305 | val = cons_to_x_long (o); |
| 2313 | } | 2306 | } |
| 2314 | else if (STRINGP (o)) | 2307 | else if (STRINGP (o)) |
| 2315 | { | 2308 | { |
| @@ -2322,17 +2315,15 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | |||
| 2322 | 2315 | ||
| 2323 | if (format == 8) | 2316 | if (format == 8) |
| 2324 | { | 2317 | { |
| 2325 | if (CHAR_MIN <= val && val <= CHAR_MAX) | 2318 | if ((1 << 8) < val && val <= X_ULONG_MAX - (1 << 7)) |
| 2326 | *d08++ = val; | ||
| 2327 | else | ||
| 2328 | error ("Out of 'char' range"); | 2319 | error ("Out of 'char' range"); |
| 2320 | *d08++ = val; | ||
| 2329 | } | 2321 | } |
| 2330 | else if (format == 16) | 2322 | else if (format == 16) |
| 2331 | { | 2323 | { |
| 2332 | if (X_SHRT_MIN <= val && val <= X_SHRT_MAX) | 2324 | if ((1 << 16) < val && val <= X_ULONG_MAX - (1 << 15)) |
| 2333 | *d16++ = val; | ||
| 2334 | else | ||
| 2335 | error ("Out of 'short' range"); | 2325 | error ("Out of 'short' range"); |
| 2326 | *d16++ = val; | ||
| 2336 | } | 2327 | } |
| 2337 | else | 2328 | else |
| 2338 | *d32++ = val; | 2329 | *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, | |||
| 6802 | break; | 6802 | break; |
| 6803 | 6803 | ||
| 6804 | case SelectionNotify: | 6804 | case SelectionNotify: |
| 6805 | dpyinfo->last_user_time = event->xselection.time; | 6805 | x_display_set_last_user_time (dpyinfo, event->xselection.time); |
| 6806 | #ifdef USE_X_TOOLKIT | 6806 | #ifdef USE_X_TOOLKIT |
| 6807 | if (! x_window_to_frame (dpyinfo, event->xselection.requestor)) | 6807 | if (! x_window_to_frame (dpyinfo, event->xselection.requestor)) |
| 6808 | goto OTHER; | 6808 | goto OTHER; |
| @@ -6811,7 +6811,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 6811 | break; | 6811 | break; |
| 6812 | 6812 | ||
| 6813 | case SelectionClear: /* Someone has grabbed ownership. */ | 6813 | case SelectionClear: /* Someone has grabbed ownership. */ |
| 6814 | dpyinfo->last_user_time = event->xselectionclear.time; | 6814 | x_display_set_last_user_time (dpyinfo, event->xselectionclear.time); |
| 6815 | #ifdef USE_X_TOOLKIT | 6815 | #ifdef USE_X_TOOLKIT |
| 6816 | if (! x_window_to_frame (dpyinfo, event->xselectionclear.window)) | 6816 | if (! x_window_to_frame (dpyinfo, event->xselectionclear.window)) |
| 6817 | goto OTHER; | 6817 | goto OTHER; |
| @@ -6827,7 +6827,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 6827 | break; | 6827 | break; |
| 6828 | 6828 | ||
| 6829 | case SelectionRequest: /* Someone wants our selection. */ | 6829 | case SelectionRequest: /* Someone wants our selection. */ |
| 6830 | dpyinfo->last_user_time = event->xselectionrequest.time; | 6830 | x_display_set_last_user_time (dpyinfo, event->xselectionrequest.time); |
| 6831 | #ifdef USE_X_TOOLKIT | 6831 | #ifdef USE_X_TOOLKIT |
| 6832 | if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner)) | 6832 | if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner)) |
| 6833 | goto OTHER; | 6833 | goto OTHER; |
| @@ -6846,7 +6846,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 6846 | break; | 6846 | break; |
| 6847 | 6847 | ||
| 6848 | case PropertyNotify: | 6848 | case PropertyNotify: |
| 6849 | dpyinfo->last_user_time = event->xproperty.time; | 6849 | x_display_set_last_user_time (dpyinfo, event->xproperty.time); |
| 6850 | f = x_top_window_to_frame (dpyinfo, event->xproperty.window); | 6850 | f = x_top_window_to_frame (dpyinfo, event->xproperty.window); |
| 6851 | if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state) | 6851 | if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state) |
| 6852 | { | 6852 | { |
| @@ -7044,7 +7044,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7044 | 7044 | ||
| 7045 | case KeyPress: | 7045 | case KeyPress: |
| 7046 | 7046 | ||
| 7047 | dpyinfo->last_user_time = event->xkey.time; | 7047 | x_display_set_last_user_time (dpyinfo, event->xkey.time); |
| 7048 | ignore_next_mouse_click_timeout = 0; | 7048 | ignore_next_mouse_click_timeout = 0; |
| 7049 | 7049 | ||
| 7050 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | 7050 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) |
| @@ -7378,7 +7378,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7378 | #endif | 7378 | #endif |
| 7379 | 7379 | ||
| 7380 | case KeyRelease: | 7380 | case KeyRelease: |
| 7381 | dpyinfo->last_user_time = event->xkey.time; | 7381 | x_display_set_last_user_time (dpyinfo, event->xkey.time); |
| 7382 | #ifdef HAVE_X_I18N | 7382 | #ifdef HAVE_X_I18N |
| 7383 | /* Don't dispatch this event since XtDispatchEvent calls | 7383 | /* Don't dispatch this event since XtDispatchEvent calls |
| 7384 | XFilterEvent, and two calls in a row may freeze the | 7384 | XFilterEvent, and two calls in a row may freeze the |
| @@ -7389,7 +7389,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7389 | #endif | 7389 | #endif |
| 7390 | 7390 | ||
| 7391 | case EnterNotify: | 7391 | case EnterNotify: |
| 7392 | dpyinfo->last_user_time = event->xcrossing.time; | 7392 | x_display_set_last_user_time (dpyinfo, event->xcrossing.time); |
| 7393 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); | 7393 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); |
| 7394 | 7394 | ||
| 7395 | f = any; | 7395 | f = any; |
| @@ -7414,7 +7414,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7414 | goto OTHER; | 7414 | goto OTHER; |
| 7415 | 7415 | ||
| 7416 | case LeaveNotify: | 7416 | case LeaveNotify: |
| 7417 | dpyinfo->last_user_time = event->xcrossing.time; | 7417 | x_display_set_last_user_time (dpyinfo, event->xcrossing.time); |
| 7418 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); | 7418 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); |
| 7419 | 7419 | ||
| 7420 | f = x_top_window_to_frame (dpyinfo, event->xcrossing.window); | 7420 | f = x_top_window_to_frame (dpyinfo, event->xcrossing.window); |
| @@ -7448,7 +7448,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7448 | 7448 | ||
| 7449 | case MotionNotify: | 7449 | case MotionNotify: |
| 7450 | { | 7450 | { |
| 7451 | dpyinfo->last_user_time = event->xmotion.time; | 7451 | x_display_set_last_user_time (dpyinfo, event->xmotion.time); |
| 7452 | previous_help_echo_string = help_echo_string; | 7452 | previous_help_echo_string = help_echo_string; |
| 7453 | help_echo_string = Qnil; | 7453 | help_echo_string = Qnil; |
| 7454 | 7454 | ||
| @@ -7588,7 +7588,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 7588 | 7588 | ||
| 7589 | memset (&compose_status, 0, sizeof (compose_status)); | 7589 | memset (&compose_status, 0, sizeof (compose_status)); |
| 7590 | dpyinfo->last_mouse_glyph_frame = NULL; | 7590 | dpyinfo->last_mouse_glyph_frame = NULL; |
| 7591 | dpyinfo->last_user_time = event->xbutton.time; | 7591 | x_display_set_last_user_time (dpyinfo, event->xbutton.time); |
| 7592 | 7592 | ||
| 7593 | f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame | 7593 | f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame |
| 7594 | : x_window_to_frame (dpyinfo, event->xbutton.window)); | 7594 | : 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 *); | |||
| 434 | 434 | ||
| 435 | struct x_output | 435 | struct x_output |
| 436 | { | 436 | { |
| 437 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | 437 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) |
| 438 | /* Height of menu bar widget, in pixels. This value | 438 | /* Height of menu bar widget, in pixels. This value |
| 439 | is not meaningful if the menubar is turned off. */ | 439 | is not meaningful if the menubar is turned off. */ |
| 440 | int menubar_height; | 440 | int menubar_height; |
| @@ -654,6 +654,13 @@ struct x_output | |||
| 654 | int move_offset_left; | 654 | int move_offset_left; |
| 655 | }; | 655 | }; |
| 656 | 656 | ||
| 657 | /* Extreme 'short' and 'long' values suitable for libX11. */ | ||
| 658 | #define X_SHRT_MAX 0x7fff | ||
| 659 | #define X_SHRT_MIN (-1 - X_SHRT_MAX) | ||
| 660 | #define X_LONG_MAX 0x7fffffff | ||
| 661 | #define X_LONG_MIN (-1 - X_LONG_MAX) | ||
| 662 | #define X_ULONG_MAX 0xffffffffUL | ||
| 663 | |||
| 657 | #define No_Cursor (None) | 664 | #define No_Cursor (None) |
| 658 | 665 | ||
| 659 | enum | 666 | enum |
| @@ -1022,6 +1029,15 @@ x_display_pixel_width (struct x_display_info *dpyinfo) | |||
| 1022 | return WidthOfScreen (dpyinfo->screen); | 1029 | return WidthOfScreen (dpyinfo->screen); |
| 1023 | } | 1030 | } |
| 1024 | 1031 | ||
| 1032 | INLINE void | ||
| 1033 | x_display_set_last_user_time (struct x_display_info *dpyinfo, Time t) | ||
| 1034 | { | ||
| 1035 | #ifdef ENABLE_CHECKING | ||
| 1036 | eassert (t <= X_ULONG_MAX); | ||
| 1037 | #endif | ||
| 1038 | dpyinfo->last_user_time = t; | ||
| 1039 | } | ||
| 1040 | |||
| 1025 | extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); | 1041 | extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); |
| 1026 | extern void x_wait_for_event (struct frame *, int); | 1042 | extern void x_wait_for_event (struct frame *, int); |
| 1027 | extern void x_clear_under_internal_border (struct frame *f); | 1043 | extern void x_clear_under_internal_border (struct frame *f); |