Ticket #2988: treat only ESC<char><end> or <ESC><char><ESC> as valid - Denys Vlasenko <vda.linux@googlemail.com> - 2012-10-22 1749.patch

File treat only ESC<char><end> or <ESC><char><ESC> as valid - Denys Vlasenko <vda.linux@googlemail.com> - 2012-10-22 1749.patch, 2.4 KB (added by slavazanko, 11 years ago)
  • lib/tty/key.c

    From: Denys Vlasenko <vda.linux@googlemail.com>
    Subject: [PATCH 4/5] keyboard input: treat only ESC<char><end> or <ESC><char><ESC> as valid
    Date: Mon, 22 Oct 2012 16:49:44 +0200
    
    This change prevents misinterpreting an unknown ESC sequence's
    tail as a garbage input. To reproduce, run "sleep 3" and
    hold down Down_Arrow key until sleep runs.
    With debugging log enabled, the following can be seen:
    
    entered get_key_code(no_delay:0)
     c=tty_lowlevel_getch()=27
     push_char(27) !0
     c=xgetch_second()=91
     push_char(91) !0
     2 c=tty_lowlevel_getch()=66
     push_char(66)
      seq_buffer[0]:27   <---- the saved Down Arrow sequence "ESC [ B"
      seq_buffer[1]:91
      seq_buffer[2]:66
      seq_buffer[3]:0
     pending_keys!=NULL. m=-1
     d=*pending_keys++=27
     d=ALT(*pending_keys++)=ALT(91)=8283
     ^^^^^^^^^^^^^^^^^^^^^^^ we misinterpret "ESC [ B" as "ESC ["
    return correct_key_code(8283)
    entered get_key_code(no_delay:0)
     pending_keys!=NULL. m=-1
     d=*pending_keys++=66
     ^^^^^^^^^^^^ we think user pressed "B"
    return correct_key_code(66)
    
    With this patch, no bogus "input" is generated.
    
    Longer unknown sequences need an additional fix, coming next.
    
    Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
    ---
     lib/tty/key.c |   11 +++++++++--
     1 files changed, 9 insertions(+), 2 deletions(-)
    
    diff --git a/lib/tty/key.c b/lib/tty/key.c
    index 77185ce..9b97aa8 100644
    a b get_key_code (int no_delay) 
    18741874        { 
    18751875            int d = *pending_keys++; 
    18761876            keylog (" d=*pending_keys++=%d\n", d); 
    1877           check_pend: 
    18781877            if (*pending_keys == 0) 
    18791878            { 
    18801879                pending_keys = NULL; 
    get_key_code (int no_delay) 
    18821881            } 
    18831882            else if (d == ESC_CHAR) 
    18841883            { 
     1884                int bad_seq; 
    18851885                d = ALT (*pending_keys++); 
    18861886                keylog (" d=ALT(*pending_keys++)=ALT(%d)=%d\n", pending_keys[-1], d); 
    1887                 goto check_pend; 
     1887                bad_seq = (*pending_keys != ESC_CHAR && *pending_keys != 0); 
     1888                if (*pending_keys == 0 || bad_seq) 
     1889                { 
     1890                    pending_keys = NULL; 
     1891                    seq_append = NULL; 
     1892                } 
     1893                if (bad_seq) 
     1894                    goto nodelay_try_again; 
    18881895            } 
    18891896            if ((d > 127 && d < 256) && use_8th_bit_as_meta) 
    18901897            {