NetBSD-Bugs archive

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

lib/55457: libcurses: when passed a pad, wget_wch/wgetch calls wrefresh on the pad



>Number:         55457
>Category:       lib
>Synopsis:       libcurses: when passed a pad, wget_wch/wgetch calls wrefresh on the pad
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 05 05:40:00 +0000 2020
>Originator:     Michael Forney
>Release:        libcurses trunk as of 2020-07-04
>Organization:
>Environment:
>Description:
When you create a pad with newpad(), then when you read a character with wget_wch() or wgetch(), it incorrectly calls wrefresh() on the pad. This causes a region of the screen (starting at 0, 0) to be replaced with the contents of the pad.

According to X/Open Curses issue 7, this refresh operation should not occur when the window is a pad:

> If the current or specified window is not a pad, and it has been moved
> or modified since the last refresh operation, then it will be refreshed
> before another character is read.
>How-To-Repeat:
Here is an example program that illustrates the problem. It should write any input to the pad on the second line. The problem is that the input also overwrites the first line in addition to displaying on the second line.

#include <curses.h>
int
main(void)
{
	WINDOW *pad;
	int c;

	initscr();
	cbreak();
	noecho();

	addstr("abcdefghijklmnopqrstuvwxyz0123456789");
	refresh();

	pad = newpad(1, COLS);
	for (;;) {
		c = wgetch(pad);
		waddch(pad, c);
		prefresh(pad, 0, 0, 1, 0, 1, COLS);
	}
	endwin();
}

>Fix:
Adding a check to see if the window is a pad before calling wrefresh solves the issue:

diff --git a/lib/libcurses/get_wch.c b/lib/libcurses/get_wch.c
index 40a7169..1641c72 100644
--- a/lib/libcurses/get_wch.c
+++ b/lib/libcurses/get_wch.c
@@ -494,7 +494,7 @@ wget_wch(WINDOW *win, wint_t *ch)
 	    && __echoit)
 		return ERR;
 
-	if (is_wintouched(win))
+	if (!(win->flags & __ISPAD) && is_wintouched(win))
 		wrefresh(win);
 #ifdef DEBUG
 	__CTRACE(__CTRACE_INPUT, "wget_wch: __echoit = %d, "
diff --git a/lib/libcurses/getch.c b/lib/libcurses/getch.c
index c96965f..b8a8e8a 100644
--- a/lib/libcurses/getch.c
+++ b/lib/libcurses/getch.c
@@ -809,11 +809,11 @@ wgetch(WINDOW *win)
 	    && __echoit)
 		return ERR;
 
-	if (is_wintouched(win))
-		wrefresh(win);
-	else {
-		if ((_cursesi_screen->curscr->cury != (win->begy + win->cury))
-		    || (_cursesi_screen->curscr->curx != (win->begx + win->curx))) {
+	if (!(win->flags & __ISPAD)) {
+		if (is_wintouched(win))
+			wrefresh(win);
+		else if ((_cursesi_screen->curscr->cury != (win->begy + win->cury))
+		         || (_cursesi_screen->curscr->curx != (win->begx + win->curx))) {
 #ifdef DEBUG
 			__CTRACE(__CTRACE_INPUT, "wgetch: curscr cury %d cury %d curscr curx %d curx %d\n",
 			_cursesi_screen->curscr->cury, win->begy + win->cury,



Home | Main Index | Thread Index | Old Index