NetBSD-Bugs archive

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

lib/54329: libedit: undefined terminal behavior in terminal_move_to_line (fix included)



>Number:         54329
>Category:       lib
>Synopsis:       libedit: undefined terminal behavior in terminal_move_to_line (fix included)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Jun 27 05:05:00 +0000 2019
>Originator:     Raphael Poss
>Release:        all
>Organization:
>Environment:
all
>Description:
The algorithm for terminal_move_to_line()
uses the DO termcap (aka cud or parm_down_cursor), which produces
undefined behavior when the cursor is on the last line. See the manual at https://www.gnu.org/software/termutils/manual/termcap-1.3/html_chapter/termcap_4.html#SEC23, which says:

    DO', UP', LE', RI'
    Strings of commands to move the cursor n lines down vertically, up
    vertically, or n columns left or right. Do not attempt to move past any
    edge of the screen with these commands; the effect of trying that is
    undefined. Only a few terminal descriptions provide these commands, and
    most programs do not use them.

A patch is included below.

(Credits to Jordan Lewis of Cockroach Labs and Nikhil Benesch for investigating this)
>How-To-Repeat:
For reviewers trying to understand why DO is not appropriate on the last line, I encourage you to try running "tput cud 5" while on the last line of your terminal versus somewhere higher up. That command outputs a DO cap with an argument of 5, which should move the cursor 5 lines down. This will work as long as the cursor doesn't hit the last line.
>Fix:
The following patch seems to help:

diff --git a/src/terminal.c b/src/terminal.c
index d8db3d1..fb865b6 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -509,15 +509,10 @@ terminal_move_to_line(EditLine *el, int where)
                return;
        }
        if ((del = where - el->el_cursor.v) > 0) {
-               if ((del > 1) && GoodStr(T_DO)) {
-                       terminal_tputs(el, tgoto(Str(T_DO), del, del), del);
-                       del = 0;
-               } else {
-                       for (; del > 0; del--)
-                               terminal__putc(el, '\n');
-                       /* because the \n will become \r\n */
-                       el->el_cursor.h = 0;
-               }
+               for (; del > 0; del--)
+                       terminal__putc(el, '\n');
+               /* because the \n will become \r\n */
+               el->el_cursor.h = 0;
        } else {                /* del < 0 */
                if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
                        terminal_tputs(el, tgoto(Str(T_UP), -del, -del), -del);



Home | Main Index | Thread Index | Old Index