aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-09-24 13:30:28 -0700
committerPaul Eggert2014-09-24 13:30:28 -0700
commit203a9eb0ec0e1f28958df5fa1a49c5a7e3f4cae8 (patch)
tree52781d0a379ff1927d2461265bd0b94f68254454 /src
parent0e176389a723f7eec072af62cde12314de7f70e2 (diff)
downloademacs-203a9eb0ec0e1f28958df5fa1a49c5a7e3f4cae8.tar.gz
emacs-203a9eb0ec0e1f28958df5fa1a49c5a7e3f4cae8.zip
Avoid signed integer overflow when converting Time to ptrdiff_t.
* keyboard.c (INPUT_EVENT_POS_MAX, INPUT_EVENT_POS_MIN): New macros. (position_to_Time, Time_to_position): New functions. (gen_help_event, kbd_buffer_get_event): Use them. * systime.h (Time) [emacs && !HAVE_X_WINDOWS]: Go back to plain 'unsigned long', so that 'Time' is the same for both X and non-X builds; this is less likely to cause surprise. * termhooks.h: Remove compile-time check that Time and ptrdiff_t are the same size; this is no longer required.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/keyboard.c32
-rw-r--r--src/systime.h3
-rw-r--r--src/termhooks.h3
4 files changed, 42 insertions, 7 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9ee4a3de1d0..5f95c1594ef 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,16 @@
12014-09-24 Paul Eggert <eggert@cs.ucla.edu> 12014-09-24 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Avoid signed integer overflow when converting Time to ptrdiff_t.
4 * keyboard.c (INPUT_EVENT_POS_MAX, INPUT_EVENT_POS_MIN):
5 New macros.
6 (position_to_Time, Time_to_position): New functions.
7 (gen_help_event, kbd_buffer_get_event): Use them.
8 * systime.h (Time) [emacs && !HAVE_X_WINDOWS]:
9 Go back to plain 'unsigned long', so that 'Time' is the same
10 for both X and non-X builds; this is less likely to cause surprise.
11 * termhooks.h: Remove compile-time check that Time and ptrdiff_t
12 are the same size; this is no longer required.
13
3 * keyboard.c (make_lispy_event): Avoid unnecessary tests 14 * keyboard.c (make_lispy_event): Avoid unnecessary tests
4 of bit 28 and of whether an unsigned value is negative. 15 of bit 28 and of whether an unsigned value is negative.
5 This simplifies the code a bit, and pacifies clang 3.4. 16 This simplifies the code a bit, and pacifies clang 3.4.
diff --git a/src/keyboard.c b/src/keyboard.c
index 718614f080a..704109e1671 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3729,6 +3729,34 @@ kbd_buffer_unget_event (register struct input_event *event)
3729 } 3729 }
3730} 3730}
3731 3731
3732/* Limit help event positions to this range, to avoid overflow problems. */
3733#define INPUT_EVENT_POS_MAX \
3734 ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \
3735 MOST_POSITIVE_FIXNUM)))
3736#define INPUT_EVENT_POS_MIN (-1 - INPUT_EVENT_POS_MAX)
3737
3738/* Return a Time that encodes position POS. POS must be in range. */
3739
3740static Time
3741position_to_Time (ptrdiff_t pos)
3742{
3743 eassert (INPUT_EVENT_POS_MIN <= pos && pos <= INPUT_EVENT_POS_MAX);
3744 return pos;
3745}
3746
3747/* Return the position that ENCODED_POS encodes.
3748 Avoid signed integer overflow. */
3749
3750static ptrdiff_t
3751Time_to_position (Time encoded_pos)
3752{
3753 if (encoded_pos <= INPUT_EVENT_POS_MAX)
3754 return encoded_pos;
3755 Time encoded_pos_min = INPUT_EVENT_POS_MIN;
3756 eassert (encoded_pos_min <= encoded_pos);
3757 ptrdiff_t notpos = -1 - encoded_pos;
3758 return -1 - notpos;
3759}
3732 3760
3733/* Generate a HELP_EVENT input_event and store it in the keyboard 3761/* Generate a HELP_EVENT input_event and store it in the keyboard
3734 buffer. 3762 buffer.
@@ -3752,7 +3780,7 @@ gen_help_event (Lisp_Object help, Lisp_Object frame, Lisp_Object window,
3752 event.arg = object; 3780 event.arg = object;
3753 event.x = WINDOWP (window) ? window : frame; 3781 event.x = WINDOWP (window) ? window : frame;
3754 event.y = help; 3782 event.y = help;
3755 event.timestamp = pos; 3783 event.timestamp = position_to_Time (pos);
3756 kbd_buffer_store_event (&event); 3784 kbd_buffer_store_event (&event);
3757} 3785}
3758 3786
@@ -4084,7 +4112,7 @@ kbd_buffer_get_event (KBOARD **kbp,
4084 4112
4085 frame = event->frame_or_window; 4113 frame = event->frame_or_window;
4086 object = event->arg; 4114 object = event->arg;
4087 position = make_number (event->timestamp); 4115 position = make_number (Time_to_position (event->timestamp));
4088 window = event->x; 4116 window = event->x;
4089 help = event->y; 4117 help = event->y;
4090 clear_event (event); 4118 clear_event (event);
diff --git a/src/systime.h b/src/systime.h
index 30a13d0ebcf..a834bce76dc 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -19,7 +19,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19#ifndef EMACS_SYSTIME_H 19#ifndef EMACS_SYSTIME_H
20#define EMACS_SYSTIME_H 20#define EMACS_SYSTIME_H
21 21
22#include <sys/types.h>
23#include <timespec.h> 22#include <timespec.h>
24 23
25INLINE_HEADER_BEGIN 24INLINE_HEADER_BEGIN
@@ -28,7 +27,7 @@ INLINE_HEADER_BEGIN
28# ifdef HAVE_X_WINDOWS 27# ifdef HAVE_X_WINDOWS
29# include <X11/X.h> 28# include <X11/X.h>
30# else 29# else
31typedef size_t Time; 30typedef unsigned long Time;
32# endif 31# endif
33#endif 32#endif
34 33
diff --git a/src/termhooks.h b/src/termhooks.h
index 6412f0da6ca..8d85fba8af8 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -288,9 +288,6 @@ struct input_event
288 Lisp_Object arg; 288 Lisp_Object arg;
289}; 289};
290 290
291/* To make sure we don't break HELP_EVENT. */
292verify (sizeof (Time) == sizeof (ptrdiff_t));
293
294#define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event)) 291#define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event))
295 292
296/* Bits in the modifiers member of the input_event structure. 293/* Bits in the modifiers member of the input_event structure.