aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-10-30 14:24:29 -0700
committerPaul Eggert2019-10-30 14:43:14 -0700
commit581601e650cc8bdcf3ed83c6ae36744601c12ce9 (patch)
tree37cc3bd330820866ff9d3aa2bf37e2fd84725739 /src
parent40ae02ff50a8f05660a7f9f234320875b6358c9d (diff)
downloademacs-581601e650cc8bdcf3ed83c6ae36744601c12ce9.tar.gz
emacs-581601e650cc8bdcf3ed83c6ae36744601c12ce9.zip
Fix keyboard.c infloops on circular lists
Fix infinite loops in keyboard.c when a circular list is found in a hook, or in help-event-list, or in the argument of event-convert-list, or in a keymap where a Lucid event type list is expected, or in a menu or tab spec. * src/keyboard.c (safe_run_hooks_error, menu_bar_items) (parse_menu_item, parse_tab_bar_item, parse_tool_bar_item): Use FOR_EACH_TAIL to avoid infloop on circular lists. (help_char_p, Fevent_convert_list, lucid_event_type_list_p): Use FOR_EACH_TAIL_SAFE to avoid infloop on circular lists, when the action is idempotent so a circular list can be treated as a noncircular one.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 0eab8fdfae1..7d3b0244b20 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1784,10 +1784,10 @@ safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args)
1784 1784
1785 if (SYMBOLP (hook)) 1785 if (SYMBOLP (hook))
1786 { 1786 {
1787 Lisp_Object val;
1788 bool found = false; 1787 bool found = false;
1789 Lisp_Object newval = Qnil; 1788 Lisp_Object newval = Qnil;
1790 for (val = find_symbol_value (hook); CONSP (val); val = XCDR (val)) 1789 Lisp_Object val = find_symbol_value (hook);
1790 FOR_EACH_TAIL (val)
1791 if (EQ (fun, XCAR (val))) 1791 if (EQ (fun, XCAR (val)))
1792 found = true; 1792 found = true;
1793 else 1793 else
@@ -1797,9 +1797,8 @@ safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args)
1797 /* Not found in the local part of the hook. Let's look at the global 1797 /* Not found in the local part of the hook. Let's look at the global
1798 part. */ 1798 part. */
1799 newval = Qnil; 1799 newval = Qnil;
1800 for (val = (NILP (Fdefault_boundp (hook)) ? Qnil 1800 val = NILP (Fdefault_boundp (hook)) ? Qnil : Fdefault_value (hook);
1801 : Fdefault_value (hook)); 1801 FOR_EACH_TAIL (val)
1802 CONSP (val); val = XCDR (val))
1803 if (EQ (fun, XCAR (val))) 1802 if (EQ (fun, XCAR (val)))
1804 found = true; 1803 found = true;
1805 else 1804 else
@@ -3196,14 +3195,13 @@ record_menu_key (Lisp_Object c)
3196static bool 3195static bool
3197help_char_p (Lisp_Object c) 3196help_char_p (Lisp_Object c)
3198{ 3197{
3199 Lisp_Object tail;
3200
3201 if (EQ (c, Vhelp_char)) 3198 if (EQ (c, Vhelp_char))
3202 return 1; 3199 return true;
3203 for (tail = Vhelp_event_list; CONSP (tail); tail = XCDR (tail)) 3200 Lisp_Object tail = Vhelp_event_list;
3201 FOR_EACH_TAIL_SAFE (tail)
3204 if (EQ (c, XCAR (tail))) 3202 if (EQ (c, XCAR (tail)))
3205 return 1; 3203 return true;
3206 return 0; 3204 return false;
3207} 3205}
3208 3206
3209/* Record the input event C in various ways. */ 3207/* Record the input event C in various ways. */
@@ -6581,22 +6579,16 @@ The return value is an event type (a character or symbol) which
6581has the same base event type and all the specified modifiers. */) 6579has the same base event type and all the specified modifiers. */)
6582 (Lisp_Object event_desc) 6580 (Lisp_Object event_desc)
6583{ 6581{
6584 Lisp_Object base; 6582 Lisp_Object base = Qnil;
6585 int modifiers = 0; 6583 int modifiers = 0;
6586 Lisp_Object rest;
6587 6584
6588 base = Qnil; 6585 FOR_EACH_TAIL_SAFE (event_desc)
6589 rest = event_desc;
6590 while (CONSP (rest))
6591 { 6586 {
6592 Lisp_Object elt; 6587 Lisp_Object elt = XCAR (event_desc);
6593 int this = 0; 6588 int this = 0;
6594 6589
6595 elt = XCAR (rest);
6596 rest = XCDR (rest);
6597
6598 /* Given a symbol, see if it is a modifier name. */ 6590 /* Given a symbol, see if it is a modifier name. */
6599 if (SYMBOLP (elt) && CONSP (rest)) 6591 if (SYMBOLP (elt) && CONSP (XCDR (event_desc)))
6600 this = parse_solitary_modifier (elt); 6592 this = parse_solitary_modifier (elt);
6601 6593
6602 if (this != 0) 6594 if (this != 0)
@@ -6605,7 +6597,6 @@ has the same base event type and all the specified modifiers. */)
6605 error ("Two bases given in one event"); 6597 error ("Two bases given in one event");
6606 else 6598 else
6607 base = elt; 6599 base = elt;
6608
6609 } 6600 }
6610 6601
6611 /* Let the symbol A refer to the character A. */ 6602 /* Let the symbol A refer to the character A. */
@@ -6755,24 +6746,23 @@ parse_solitary_modifier (Lisp_Object symbol)
6755bool 6746bool
6756lucid_event_type_list_p (Lisp_Object object) 6747lucid_event_type_list_p (Lisp_Object object)
6757{ 6748{
6758 Lisp_Object tail;
6759
6760 if (! CONSP (object)) 6749 if (! CONSP (object))
6761 return 0; 6750 return false;
6762 6751
6763 if (EQ (XCAR (object), Qhelp_echo) 6752 if (EQ (XCAR (object), Qhelp_echo)
6764 || EQ (XCAR (object), Qvertical_line) 6753 || EQ (XCAR (object), Qvertical_line)
6765 || EQ (XCAR (object), Qmode_line) 6754 || EQ (XCAR (object), Qmode_line)
6766 || EQ (XCAR (object), Qtab_line) 6755 || EQ (XCAR (object), Qtab_line)
6767 || EQ (XCAR (object), Qheader_line)) 6756 || EQ (XCAR (object), Qheader_line))
6768 return 0; 6757 return false;
6769 6758
6770 for (tail = object; CONSP (tail); tail = XCDR (tail)) 6759 Lisp_Object tail = object;
6760 FOR_EACH_TAIL_SAFE (object)
6771 { 6761 {
6772 Lisp_Object elt; 6762 Lisp_Object elt = XCAR (object);
6773 elt = XCAR (tail);
6774 if (! (FIXNUMP (elt) || SYMBOLP (elt))) 6763 if (! (FIXNUMP (elt) || SYMBOLP (elt)))
6775 return 0; 6764 return false;
6765 tail = XCDR (object);
6776 } 6766 }
6777 6767
6778 return NILP (tail); 6768 return NILP (tail);
@@ -7401,7 +7391,7 @@ menu_bar_items (Lisp_Object old)
7401 Lisp_Object *maps; 7391 Lisp_Object *maps;
7402 7392
7403 Lisp_Object mapsbuf[3]; 7393 Lisp_Object mapsbuf[3];
7404 Lisp_Object def, tail; 7394 Lisp_Object def;
7405 7395
7406 ptrdiff_t mapno; 7396 ptrdiff_t mapno;
7407 Lisp_Object oquit; 7397 Lisp_Object oquit;
@@ -7484,12 +7474,12 @@ menu_bar_items (Lisp_Object old)
7484 7474
7485 /* Move to the end those items that should be at the end. */ 7475 /* Move to the end those items that should be at the end. */
7486 7476
7487 for (tail = Vmenu_bar_final_items; CONSP (tail); tail = XCDR (tail)) 7477 Lisp_Object tail = Vmenu_bar_final_items;
7478 FOR_EACH_TAIL (tail)
7488 { 7479 {
7489 int i;
7490 int end = menu_bar_items_index; 7480 int end = menu_bar_items_index;
7491 7481
7492 for (i = 0; i < end; i += 4) 7482 for (int i = 0; i < end; i += 4)
7493 if (EQ (XCAR (tail), AREF (menu_bar_items_vector, i))) 7483 if (EQ (XCAR (tail), AREF (menu_bar_items_vector, i)))
7494 { 7484 {
7495 Lisp_Object tem0, tem1, tem2, tem3; 7485 Lisp_Object tem0, tem1, tem2, tem3;
@@ -7726,10 +7716,12 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7726 item = XCDR (item); 7716 item = XCDR (item);
7727 7717
7728 /* Parse properties. */ 7718 /* Parse properties. */
7729 while (CONSP (item) && CONSP (XCDR (item))) 7719 FOR_EACH_TAIL (item)
7730 { 7720 {
7731 tem = XCAR (item); 7721 tem = XCAR (item);
7732 item = XCDR (item); 7722 item = XCDR (item);
7723 if (!CONSP (item))
7724 break;
7733 7725
7734 if (EQ (tem, QCenable)) 7726 if (EQ (tem, QCenable))
7735 { 7727 {
@@ -7780,7 +7772,6 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7780 ASET (item_properties, ITEM_PROPERTY_TYPE, type); 7772 ASET (item_properties, ITEM_PROPERTY_TYPE, type);
7781 } 7773 }
7782 } 7774 }
7783 item = XCDR (item);
7784 } 7775 }
7785 } 7776 }
7786 else if (inmenubar || !NILP (start)) 7777 else if (inmenubar || !NILP (start))
@@ -8198,12 +8189,13 @@ parse_tab_bar_item (Lisp_Object key, Lisp_Object item)
8198 item = XCDR (item); 8189 item = XCDR (item);
8199 8190
8200 /* Process the rest of the properties. */ 8191 /* Process the rest of the properties. */
8201 for (; CONSP (item) && CONSP (XCDR (item)); item = XCDR (XCDR (item))) 8192 FOR_EACH_TAIL (item)
8202 { 8193 {
8203 Lisp_Object ikey, value; 8194 Lisp_Object ikey = XCAR (item);
8204 8195 item = XCDR (item);
8205 ikey = XCAR (item); 8196 if (!CONSP (item))
8206 value = XCAR (XCDR (item)); 8197 break;
8198 Lisp_Object value = XCAR (item);
8207 8199
8208 if (EQ (ikey, QCenable)) 8200 if (EQ (ikey, QCenable))
8209 { 8201 {
@@ -8590,12 +8582,13 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
8590 item = XCDR (item); 8582 item = XCDR (item);
8591 8583
8592 /* Process the rest of the properties. */ 8584 /* Process the rest of the properties. */
8593 for (; CONSP (item) && CONSP (XCDR (item)); item = XCDR (XCDR (item))) 8585 FOR_EACH_TAIL (item)
8594 { 8586 {
8595 Lisp_Object ikey, value; 8587 Lisp_Object ikey = XCAR (item);
8596 8588 item = XCDR (item);
8597 ikey = XCAR (item); 8589 if (!CONSP (item))
8598 value = XCAR (XCDR (item)); 8590 break;
8591 Lisp_Object value = XCAR (item);
8599 8592
8600 if (EQ (ikey, QCenable)) 8593 if (EQ (ikey, QCenable))
8601 { 8594 {