[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] don't _rl_erase_at_end_of_line with char spanning line boundary

From: Grisha Levit
Subject: [PATCH] don't _rl_erase_at_end_of_line with char spanning line boundary
Date: Tue, 18 Apr 2023 04:01:40 -0400

Not actually likely but: if output-meta is turned off, and the locale
has printable characters with the 8th bit set, and the octal-escape
representation of such a character ends the line and spans a screen
line boundary, deleting the character will cause
_rl_erase_at_end_of_line to decrement _rl_last_c_pos past 0.

The patch below avoids calling _rl_erase_at_end_of_line in such a case
but I'm not sure the code in that function makes sense in any
situation when the line takes up more than one screen-width:

  3183    for (i = 0; i < l; i++)
  3184      visible_line[--_rl_last_c_pos] = '\0';

since it ends up 0-ing out portions of the first physical line rather
than the last.

Contrived reproducer:

printf -v s '%*s' "$((COLUMNS/10+1))"
INPUTRC=<(echo 'set output-meta off') PS1='$ ' LC_ALL=en_GB.ISO8859-1 \
    bash --norc -in <<<${s// /$' \260'}$'\cH'

$  \260 \260 \260 \260 \260 \260 \260 \260 \
ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 1 thread T0
    #0 _rl_erase_at_end_of_line display.c:3198
    #1 _rl_rubout_char text.c:1236

diff --git a/lib/readline/text.c b/lib/readline/text.c
index 62e4da2a..5ea3e276 100644
--- a/lib/readline/text.c
+++ b/lib/readline/text.c
@@ -1232,9 +1232,10 @@ _rl_rubout_char (int count, int key)
       if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
          int l;
          l = rl_character_len (c, rl_point);
-         _rl_erase_at_end_of_line (l);
+          if (_rl_last_c_pos >= l)
+           _rl_erase_at_end_of_line (l);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]