X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/e9eb6f14fe334d0e37d2037c952e6541eeb242ad..1c262cae409ec55a234c89b3b74a13a77c7f595a:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index 926ebc30b7..51eac369e7 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -44,7 +44,7 @@ along with GNU Emacs. If not, see . */ #include "process.h" #include -#ifdef HAVE_GTK_AND_PTHREAD +#ifdef HAVE_PTHREAD #include #endif #ifdef MSDOS @@ -196,7 +196,7 @@ int immediate_quit; int quit_char; /* Current depth in recursive edits. */ -int command_loop_level; +EMACS_INT command_loop_level; /* If not Qnil, this is a switch-frame event which we decided to put off until the end of a key sequence. This should be read as the @@ -435,16 +435,16 @@ static void (*keyboard_init_hook) (void); static int read_avail_input (int); static void get_input_pending (int *, int); static int readable_events (int); -static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *, +static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *, Lisp_Object, int *); -static Lisp_Object read_char_minibuf_menu_prompt (int, int, +static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t, Lisp_Object *); static Lisp_Object make_lispy_event (struct input_event *); #if defined (HAVE_MOUSE) || defined (HAVE_GPM) static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object, enum scroll_bar_part, Lisp_Object, Lisp_Object, - unsigned long); + Time); #endif static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object, Lisp_Object, const char *const *, @@ -998,7 +998,8 @@ static Lisp_Object cmd_error (Lisp_Object data) { Lisp_Object old_level, old_length; - char macroerror[50]; + char macroerror[sizeof "After..kbd macro iterations: " + + INT_STRLEN_BOUND (EMACS_INT)]; #ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) @@ -1010,7 +1011,7 @@ cmd_error (Lisp_Object data) if (executing_kbd_macro_iterations == 1) sprintf (macroerror, "After 1 kbd macro iteration: "); else - sprintf (macroerror, "After %d kbd macro iterations: ", + sprintf (macroerror, "After %"pI"d kbd macro iterations: ", executing_kbd_macro_iterations); } else @@ -1300,7 +1301,7 @@ some_mouse_moved (void) /* This is the actual command reading loop, sans error-handling encapsulation. */ -static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object, +static int read_key_sequence (Lisp_Object *, int, Lisp_Object, int, int, int); void safe_run_hooks (Lisp_Object); static void adjust_point_for_property (EMACS_INT, int); @@ -2267,7 +2268,8 @@ do { if (polling_stopped_here) start_polling (); \ Value is t if we showed a menu and the user rejected it. */ Lisp_Object -read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event, +read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, + Lisp_Object prev_event, int *used_mouse_menu, struct timeval *end_time) { volatile Lisp_Object c; @@ -6462,11 +6464,15 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem)); else if (STRINGP (name_alist_or_stem)) { - int len = SBYTES (name_alist_or_stem); - char *buf = (char *) alloca (len + 50); - sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem), - XINT (symbol_int) + 1); + char *buf; + ptrdiff_t len = (SBYTES (name_alist_or_stem) + + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT)); + USE_SAFE_ALLOCA; + SAFE_ALLOCA (buf, char *, len); + esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem), + XINT (symbol_int) + 1); value = intern (buf); + SAFE_FREE (); } else if (name_table != 0 && name_table[symbol_num]) value = intern (name_table[symbol_num]); @@ -6482,7 +6488,7 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s if (NILP (value)) { - char buf[20]; + char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)]; sprintf (buf, "key-%"pI"d", symbol_num); value = intern (buf); } @@ -7405,7 +7411,7 @@ menu_bar_items (Lisp_Object old) { /* The number of keymaps we're scanning right now, and the number of keymaps we have allocated space for. */ - int nmaps; + ptrdiff_t nmaps; /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1] in the current keymaps, or nil where it is not a prefix. */ @@ -7413,7 +7419,7 @@ menu_bar_items (Lisp_Object old) Lisp_Object def, tail; - int mapno; + ptrdiff_t mapno; Lisp_Object oquit; /* In order to build the menus, we need to call the keymap @@ -7458,7 +7464,7 @@ menu_bar_items (Lisp_Object old) recognized when the menu-bar (or mode-line) is updated, which does not normally happen after every command. */ Lisp_Object tem; - int nminor; + ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); nmaps = 0; @@ -7962,7 +7968,7 @@ Lisp_Object tool_bar_items (Lisp_Object reuse, int *nitems) { Lisp_Object *maps; - int nmaps, i; + ptrdiff_t nmaps, i; Lisp_Object oquit; Lisp_Object *tmaps; @@ -8002,7 +8008,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems) recognized when the tool-bar (or mode-line) is updated, which does not normally happen after every command. */ Lisp_Object tem; - int nminor; + ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); nmaps = 0; @@ -8274,10 +8280,11 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION); const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : ""; const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : ""; - EMACS_INT max_lbl = 2 * tool_bar_max_label_size; + ptrdiff_t max_lbl = + 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)); char *buf = (char *) xmalloc (max_lbl + 1); Lisp_Object new_lbl; - size_t caption_len = strlen (capt); + ptrdiff_t caption_len = strlen (capt); if (caption_len <= max_lbl && capt[0] != '\0') { @@ -8290,7 +8297,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) if (strlen (label) <= max_lbl && label[0] != '\0') { - int j; + ptrdiff_t j; if (label != buf) strcpy (buf, label); @@ -8399,10 +8406,10 @@ append_tool_bar_item (void) and do auto-saving in the inner call of read_char. */ static Lisp_Object -read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event, - int *used_mouse_menu) +read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps, + Lisp_Object prev_event, int *used_mouse_menu) { - int mapno; + ptrdiff_t mapno; if (used_mouse_menu) *used_mouse_menu = 0; @@ -8430,7 +8437,7 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event, Lisp_Object *realmaps = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); Lisp_Object value; - int nmaps1 = 0; + ptrdiff_t nmaps1 = 0; /* Use the maps that are not nil. */ for (mapno = 0; mapno < nmaps; mapno++) @@ -8481,17 +8488,18 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event, We make this bigger when necessary, and never free it. */ static char *read_char_minibuf_menu_text; /* Size of that buffer. */ -static int read_char_minibuf_menu_width; +static ptrdiff_t read_char_minibuf_menu_width; static Lisp_Object -read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) +read_char_minibuf_menu_prompt (int commandflag, + ptrdiff_t nmaps, Lisp_Object *maps) { - int mapno; + ptrdiff_t mapno; register Lisp_Object name; - int nlength; + ptrdiff_t nlength; /* FIXME: Use the minibuffer's frame width. */ - int width = FRAME_COLS (SELECTED_FRAME ()) - 4; - int idx = -1; + ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4; + ptrdiff_t idx = -1; int nobindings = 1; Lisp_Object rest, vector; char *menu; @@ -8516,16 +8524,13 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) /* Make sure we have a big enough buffer for the menu text. */ width = max (width, SBYTES (name)); - if (read_char_minibuf_menu_text == 0) + if (STRING_BYTES_BOUND - 4 < width) + memory_full (SIZE_MAX); + if (width + 4 > read_char_minibuf_menu_width) { - read_char_minibuf_menu_width = width + 4; - read_char_minibuf_menu_text = (char *) xmalloc (width + 4); - } - else if (width + 4 > read_char_minibuf_menu_width) - { - read_char_minibuf_menu_width = width + 4; read_char_minibuf_menu_text = (char *) xrealloc (read_char_minibuf_menu_text, width + 4); + read_char_minibuf_menu_width = width + 4; } menu = read_char_minibuf_menu_text; @@ -8544,7 +8549,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) while (1) { int notfirst = 0; - int i = nlength; + ptrdiff_t i = nlength; Lisp_Object obj; Lisp_Object orig_defn_macro; @@ -8643,7 +8648,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) < width || !notfirst) { - int thiswidth; + ptrdiff_t thiswidth; /* Punctuate between strings. */ if (notfirst) @@ -8659,9 +8664,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) if (! char_matches) { /* Add as much of string as fits. */ - thiswidth = SCHARS (desc); - if (thiswidth + i > width) - thiswidth = width - i; + thiswidth = min (SCHARS (desc), width - i); memcpy (menu + i, SDATA (desc), thiswidth); i += thiswidth; strcpy (menu + i, " = "); @@ -8669,9 +8672,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) } /* Add as much of string as fits. */ - thiswidth = SCHARS (s); - if (thiswidth + i > width) - thiswidth = width - i; + thiswidth = min (SCHARS (s), width - i); memcpy (menu + i, SDATA (s), thiswidth); i += thiswidth; menu[i] = 0; @@ -8746,10 +8747,10 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) NEXT may be the same array as CURRENT. */ static int -follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs, - Lisp_Object *next) +follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current, + Lisp_Object *defs, Lisp_Object *next) { - int i, first_binding; + ptrdiff_t i, first_binding; first_binding = nmaps; for (i = nmaps - 1; i >= 0; i--) @@ -8849,7 +8850,7 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt, The return value is non-zero if the remapping actually took place. */ static int -keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey, +keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey, int input, int doit, int *diff, Lisp_Object prompt) { Lisp_Object next, key; @@ -8871,7 +8872,7 @@ keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey, *diff = len - (fkey->end - fkey->start); - if (input + *diff >= bufsize) + if (bufsize - input <= *diff) error ("Key sequence too long"); /* Shift the keys that follow fkey->end. */ @@ -8942,7 +8943,7 @@ keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey, from the selected window's buffer. */ static int -read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, +read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, int dont_downcase_last, int can_return_switch_frame, int fix_current_buffer) { @@ -8959,8 +8960,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, /* The number of keymaps we're scanning right now, and the number of keymaps we have allocated space for. */ - int nmaps; - int nmaps_allocated = 0; + ptrdiff_t nmaps; + ptrdiff_t nmaps_allocated = 0; /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in the current keymaps. */ @@ -8984,7 +8985,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, /* The index in submaps[] of the first keymap that has a binding for this key sequence. In other words, the lowest i such that submaps[i] is non-nil. */ - int first_binding; + ptrdiff_t first_binding; /* Index of the first key that has no binding. It is useless to try fkey.start larger than that. */ int first_unbound; @@ -9145,8 +9146,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, } else { - int nminor; - int total; + ptrdiff_t nminor; + ptrdiff_t total; Lisp_Object *maps; nminor = current_minor_maps (0, &maps); @@ -9212,7 +9213,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, echo_local_start and keys_local_start allow us to throw away just one key. */ int echo_local_start IF_LINT (= 0); - int keys_local_start, local_first_binding; + int keys_local_start; + ptrdiff_t local_first_binding; eassert (indec.end == t || (indec.end > t && indec.end <= mock_input)); eassert (indec.start <= indec.end); @@ -9549,7 +9551,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, && (NILP (fake_prefixed_keys) || NILP (Fmemq (key, fake_prefixed_keys)))) { - if (t + 1 >= bufsize) + if (bufsize - t <= 1) error ("Key sequence too long"); keybuf[t] = posn; @@ -9630,7 +9632,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, insert the dummy prefix event `menu-bar'. */ if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) { - if (t + 1 >= bufsize) + if (bufsize - t <= 1) error ("Key sequence too long"); keybuf[t] = posn; keybuf[t+1] = key; @@ -10385,19 +10387,21 @@ give to the command you invoke, if it asks for an argument. */) char *newmessage; int message_p = push_message (); int count = SPECPDL_INDEX (); + ptrdiff_t newmessage_len, newmessage_alloc; + USE_SAFE_ALLOCA; record_unwind_protect (pop_message_unwind, Qnil); binding = Fkey_description (bindings, Qnil); - - newmessage - = (char *) alloca (SCHARS (SYMBOL_NAME (function)) - + SBYTES (binding) - + 100); - sprintf (newmessage, "You can run the command `%s' with %s", - SDATA (SYMBOL_NAME (function)), - SDATA (binding)); + newmessage_alloc = + (sizeof "You can run the command `' with " + + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding)); + SAFE_ALLOCA (newmessage, char *, newmessage_alloc); + newmessage_len = + esprintf (newmessage, "You can run the command `%s' with %s", + SDATA (SYMBOL_NAME (function)), + SDATA (binding)); message2 (newmessage, - strlen (newmessage), + newmessage_len, STRING_MULTIBYTE (binding)); if (NUMBERP (Vsuggest_key_bindings)) waited = sit_for (Vsuggest_key_bindings, 0, 2); @@ -10407,6 +10411,7 @@ give to the command you invoke, if it asks for an argument. */) if (!NILP (waited) && message_p) restore_message (); + SAFE_FREE (); unbind_to (count, Qnil); } } @@ -10636,14 +10641,17 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0, (void) { Lisp_Object temp; - XSETFASTINT (temp, command_loop_level + minibuf_level); + /* Wrap around reliably on integer overflow. */ + EMACS_INT sum = (command_loop_level & INTMASK) + (minibuf_level & INTMASK); + XSETINT (temp, sum); return temp; } DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1, "FOpen dribble file: ", doc: /* Start writing all keyboard characters to a dribble file called FILE. -If FILE is nil, close any open dribble file. */) +If FILE is nil, close any open dribble file. +The file will be closed when Emacs exits. */) (Lisp_Object file) { if (dribble)