mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-27 10:54:40 +00:00
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.
This commit is contained in:
parent
0e176389a7
commit
203a9eb0ec
@ -1,5 +1,16 @@
|
||||
2014-09-24 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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.
|
||||
|
||||
* keyboard.c (make_lispy_event): Avoid unnecessary tests
|
||||
of bit 28 and of whether an unsigned value is negative.
|
||||
This simplifies the code a bit, and pacifies clang 3.4.
|
||||
|
@ -3729,6 +3729,34 @@ kbd_buffer_unget_event (register struct input_event *event)
|
||||
}
|
||||
}
|
||||
|
||||
/* Limit help event positions to this range, to avoid overflow problems. */
|
||||
#define INPUT_EVENT_POS_MAX \
|
||||
((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \
|
||||
MOST_POSITIVE_FIXNUM)))
|
||||
#define INPUT_EVENT_POS_MIN (-1 - INPUT_EVENT_POS_MAX)
|
||||
|
||||
/* Return a Time that encodes position POS. POS must be in range. */
|
||||
|
||||
static Time
|
||||
position_to_Time (ptrdiff_t pos)
|
||||
{
|
||||
eassert (INPUT_EVENT_POS_MIN <= pos && pos <= INPUT_EVENT_POS_MAX);
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* Return the position that ENCODED_POS encodes.
|
||||
Avoid signed integer overflow. */
|
||||
|
||||
static ptrdiff_t
|
||||
Time_to_position (Time encoded_pos)
|
||||
{
|
||||
if (encoded_pos <= INPUT_EVENT_POS_MAX)
|
||||
return encoded_pos;
|
||||
Time encoded_pos_min = INPUT_EVENT_POS_MIN;
|
||||
eassert (encoded_pos_min <= encoded_pos);
|
||||
ptrdiff_t notpos = -1 - encoded_pos;
|
||||
return -1 - notpos;
|
||||
}
|
||||
|
||||
/* Generate a HELP_EVENT input_event and store it in the keyboard
|
||||
buffer.
|
||||
@ -3752,7 +3780,7 @@ gen_help_event (Lisp_Object help, Lisp_Object frame, Lisp_Object window,
|
||||
event.arg = object;
|
||||
event.x = WINDOWP (window) ? window : frame;
|
||||
event.y = help;
|
||||
event.timestamp = pos;
|
||||
event.timestamp = position_to_Time (pos);
|
||||
kbd_buffer_store_event (&event);
|
||||
}
|
||||
|
||||
@ -4084,7 +4112,7 @@ kbd_buffer_get_event (KBOARD **kbp,
|
||||
|
||||
frame = event->frame_or_window;
|
||||
object = event->arg;
|
||||
position = make_number (event->timestamp);
|
||||
position = make_number (Time_to_position (event->timestamp));
|
||||
window = event->x;
|
||||
help = event->y;
|
||||
clear_event (event);
|
||||
|
@ -19,7 +19,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#ifndef EMACS_SYSTIME_H
|
||||
#define EMACS_SYSTIME_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <timespec.h>
|
||||
|
||||
INLINE_HEADER_BEGIN
|
||||
@ -28,7 +27,7 @@ INLINE_HEADER_BEGIN
|
||||
# ifdef HAVE_X_WINDOWS
|
||||
# include <X11/X.h>
|
||||
# else
|
||||
typedef size_t Time;
|
||||
typedef unsigned long Time;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -288,9 +288,6 @@ struct input_event
|
||||
Lisp_Object arg;
|
||||
};
|
||||
|
||||
/* To make sure we don't break HELP_EVENT. */
|
||||
verify (sizeof (Time) == sizeof (ptrdiff_t));
|
||||
|
||||
#define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event))
|
||||
|
||||
/* Bits in the modifiers member of the input_event structure.
|
||||
|
Loading…
Reference in New Issue
Block a user