diff options
| author | Paul Eggert | 2014-09-24 13:30:28 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-09-24 13:30:28 -0700 |
| commit | 203a9eb0ec0e1f28958df5fa1a49c5a7e3f4cae8 (patch) | |
| tree | 52781d0a379ff1927d2461265bd0b94f68254454 /src | |
| parent | 0e176389a723f7eec072af62cde12314de7f70e2 (diff) | |
| download | emacs-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/ChangeLog | 11 | ||||
| -rw-r--r-- | src/keyboard.c | 32 | ||||
| -rw-r--r-- | src/systime.h | 3 | ||||
| -rw-r--r-- | src/termhooks.h | 3 |
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 @@ | |||
| 1 | 2014-09-24 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2014-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 | |||
| 3740 | static Time | ||
| 3741 | position_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 | |||
| 3750 | static ptrdiff_t | ||
| 3751 | Time_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 | ||
| 25 | INLINE_HEADER_BEGIN | 24 | INLINE_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 |
| 31 | typedef size_t Time; | 30 | typedef 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. */ | ||
| 292 | verify (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. |