aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-10-11 14:01:48 +0300
committerEli Zaretskii2013-10-11 14:01:48 +0300
commit48621e69064ea74eef6530d299cdc3548e170ce2 (patch)
tree783dc060c8f9dda66307e6f561d5dc178f0d31ec /src
parentb9ff995e4c091ca99c8752bb996e155ce7147a00 (diff)
downloademacs-48621e69064ea74eef6530d299cdc3548e170ce2.tar.gz
emacs-48621e69064ea74eef6530d299cdc3548e170ce2.zip
Fix bug #15575 with crashes in TTY menus.
src/xdisp.c (display_tty_menu_item): Make sure we never write beyond the end of the frame's glyph matrix. src/term.c (tty_menu_display): Don't move cursor while overwriting frame's glyphs with menu items. Limit the number of items displayed to what can be shown on the available screen lines, excluding the echo area. (tty_menu_activate): Limit the Y coordinate allowed by read_menu_input to the last screen line used for menu display.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/term.c10
-rw-r--r--src/xdisp.c9
3 files changed, 28 insertions, 3 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index df44bca7b1c..6947c5eddd5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
12013-10-11 Eli Zaretskii <eliz@gnu.org>
2
3 * xdisp.c (display_tty_menu_item): Make sure we never write beyond
4 the end of the frame's glyph matrix. (Bug#15575)
5
6 * term.c (tty_menu_display): Don't move cursor while overwriting
7 frame's glyphs with menu items. Limit the number of items
8 displayed to what can be shown on the available screen lines,
9 excluding the echo area.
10 (tty_menu_activate): Limit the Y coordinate allowed by
11 read_menu_input to the last screen line used for menu display.
12
12013-10-11 Paul Eggert <eggert@cs.ucla.edu> 132013-10-11 Paul Eggert <eggert@cs.ucla.edu>
2 14
3 * lisp.h (eassume): New macro. 15 * lisp.h (eassume): New macro.
diff --git a/src/term.c b/src/term.c
index a4f8f2ea17c..9437faee8a2 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2919,17 +2919,20 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces,
2919 int i, face, width, enabled, mousehere, row, col; 2919 int i, face, width, enabled, mousehere, row, col;
2920 struct frame *sf = SELECTED_FRAME (); 2920 struct frame *sf = SELECTED_FRAME ();
2921 struct tty_display_info *tty = FRAME_TTY (sf); 2921 struct tty_display_info *tty = FRAME_TTY (sf);
2922 /* Don't try to display more menu items than the console can display
2923 using the available screen lines. Exclude the echo area line, as
2924 it will be overwritten by the help-echo anyway. */
2925 int max_items = min (menu->count, FRAME_LINES (sf) - 1);
2922 2926
2923 menu_help_message = NULL; 2927 menu_help_message = NULL;
2924 2928
2925 width = menu->width; 2929 width = menu->width;
2926 col = cursorX (tty); 2930 col = cursorX (tty);
2927 row = cursorY (tty); 2931 row = cursorY (tty);
2928 for (i = 0; i < menu->count; i++) 2932 for (i = 0; i < max_items; i++)
2929 { 2933 {
2930 int max_width = width + 2; /* +2 for padding blanks on each side */ 2934 int max_width = width + 2; /* +2 for padding blanks on each side */
2931 2935
2932 cursor_to (sf, y + i, x);
2933 if (menu->submenu[i]) 2936 if (menu->submenu[i])
2934 max_width += 2; /* for displaying " >" after the item */ 2937 max_width += 2; /* for displaying " >" after the item */
2935 enabled 2938 enabled
@@ -3285,7 +3288,8 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3285 while (!leave) 3288 while (!leave)
3286 { 3289 {
3287 int input_status; 3290 int input_status;
3288 int min_y = state[0].y, max_y = min_y + state[0].menu->count - 1; 3291 int min_y = state[0].y;
3292 int max_y = min (min_y + state[0].menu->count, FRAME_LINES (sf)) - 1;
3289 3293
3290 input_status = read_menu_input (sf, &x, &y, min_y, max_y, &first_time); 3294 input_status = read_menu_input (sf, &x, &y, min_y, max_y, &first_time);
3291 if (input_status) 3295 if (input_status)
diff --git a/src/xdisp.c b/src/xdisp.c
index 6c189c698e1..7cfb0ab51ad 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -20640,6 +20640,14 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
20640 20640
20641 eassert (FRAME_TERMCAP_P (f)); 20641 eassert (FRAME_TERMCAP_P (f));
20642 20642
20643 /* Don't write beyond the matrix's last row. This can happen for
20644 TTY screens that are not high enough to show the entire menu.
20645 (This is actually a bit of defensive programming, as
20646 tty_menu_display already limits the number of menu items to one
20647 less than the number of screen lines.) */
20648 if (y >= f->desired_matrix->nrows)
20649 return;
20650
20643 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID); 20651 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
20644 it.first_visible_x = 0; 20652 it.first_visible_x = 0;
20645 it.last_visible_x = FRAME_COLS (f) - 1; 20653 it.last_visible_x = FRAME_COLS (f) - 1;
@@ -20654,6 +20662,7 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
20654 20662
20655 /* Arrange for the menu item glyphs to start at (X,Y) and have the 20663 /* Arrange for the menu item glyphs to start at (X,Y) and have the
20656 desired face. */ 20664 desired face. */
20665 eassert (x < f->desired_matrix->matrix_w);
20657 it.current_x = it.hpos = x; 20666 it.current_x = it.hpos = x;
20658 it.current_y = it.vpos = y; 20667 it.current_y = it.vpos = y;
20659 saved_used = row->used[TEXT_AREA]; 20668 saved_used = row->used[TEXT_AREA];