Date: Tue, 18 Feb 1997 16:21:25 +0100 (CET) From: Arne Henrik Juul <arnej@imf.unit.no> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/2762: Precedence mistake in libncurses Message-ID: <199702181521.QAA16402@frida.imf.unit.no> Resent-Message-ID: <199702181530.HAA10019@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 2762 >Category: bin >Synopsis: Precedence mistake in libncurses >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Feb 18 07:30:02 PST 1997 >Last-Modified: >Originator: Arne Henrik Juul >Organization: Norwegian University of Technology and Science >Release: FreeBSD 2.2-GAMMA i386 >Environment: Applies both to 2.2-GAMMA and 3.0-current as of Feb, 1997. diff generated from a 3.0-current checkout. >Description: Some code in libncurses looks wrong, like somebody misunderstood the C precedence rules for bit operators and ==. (Since it is commonly agreed that those precedence rules are wrong, this is not very surprising :-) There is also a pretty strange macro definition: BLANK is #defined as ' '|A_NORMAL without any parantheses. A_NORMAL is 0, so using BLANK in comparisons like this: if (*ptr != BLANK) expands to if (*ptr != ' '| 0x00000000 ) which evaluates like if ((*ptr != ' ')|0) which doesn't really hurt, but makes for some pretty silly warnings. Also, it makes the code dependant upon A_NORMAL actually being 0, which hurts modularity and abstraction. A bit worse is the mistakes with & and ==, since this changes the semantics to something I'm pretty sure was not intended. This code: if (win->_line[y][x]&A_CHARTEXT == ' ') was probably meant to mask out attributes, then compare to space. It will expand to if (win->_line[y][x]& 0x000000ff == ' ') and evaluate to if (win->_line[y][x]& 0) so the body never gets executed. This should all be reported back to whomever maintains libncurses, to make sure we are making the correct fix and that they will fix it in their code. I don't know who those maintainers are; sorry. >How-To-Repeat: make libncurses, and watch out for the warnings of "suggest parentheses around comparison in operand of &" and "|". >Fix: This fix looks right to me, but maybe the ncurses writers had some strange reason for their seemingly wrong (and inconsistent) definition of BLANK. It doesn't actually change any behaviour in regard to BLANK, so it's pretty safe anyway. Index: src/lib/libncurses/lib_addch.c =================================================================== RCS file: /usr/cvs/src/lib/libncurses/lib_addch.c,v retrieving revision 1.6 diff -u -r1.6 lib_addch.c --- lib_addch.c 1996/09/26 01:08:27 1.6 +++ lib_addch.c 1997/02/18 14:58:15 @@ -56,7 +56,7 @@ T(("win attr = %x", win->_attrs)); ch |= win->_attrs; - if (win->_line[y][x]&A_CHARTEXT == ' ') + if ((win->_line[y][x]&A_CHARTEXT) == ' ') ch |= win->_bkgd; else ch |= (win->_bkgd&A_ATTRIBUTES); Index: src/lib/libncurses/lib_bkgd.c =================================================================== RCS file: /usr/cvs/src/lib/libncurses/lib_bkgd.c,v retrieving revision 1.7 diff -u -r1.7 lib_bkgd.c --- lib_bkgd.c 1996/12/22 14:24:49 1.7 +++ lib_bkgd.c 1997/02/18 14:58:15 @@ -27,7 +27,7 @@ T(("wbkgd(%x, %x) called", win, ch)); for (y = 0; y <= win->_maxy; y++) for (x = 0; x <= win->_maxx; x++) - if (win->_line[y][x]&A_CHARTEXT == ' ') + if ((win->_line[y][x]&A_CHARTEXT) == ' ') win->_line[y][x] |= ch; else win->_line[y][x] |= (ch&A_ATTRIBUTES); Index: src/lib/libncurses/lib_clrbot.c =================================================================== RCS file: /usr/cvs/src/lib/libncurses/lib_clrbot.c,v retrieving revision 1.3 diff -u -r1.3 lib_clrbot.c --- lib_clrbot.c 1996/09/26 01:08:36 1.3 +++ lib_clrbot.c 1997/02/18 14:56:51 @@ -12,7 +12,7 @@ #include "curses.priv.h" -#define BLANK ' '|A_NORMAL +#define BLANK (' '|A_NORMAL) int wclrtobot(WINDOW *win) { Index: src/lib/libncurses/lib_clreol.c =================================================================== RCS file: /usr/cvs/src/lib/libncurses/lib_clreol.c,v retrieving revision 1.3 diff -u -r1.3 lib_clreol.c --- lib_clreol.c 1996/09/26 01:08:39 1.3 +++ lib_clreol.c 1997/02/18 14:56:58 @@ -12,7 +12,7 @@ #include "curses.priv.h" -#define BLANK ' '|A_NORMAL +#define BLANK (' '|A_NORMAL) int wclrtoeol(WINDOW *win) { Index: src/lib/libncurses/lib_doupdate.c =================================================================== RCS file: /usr/cvs/src/lib/libncurses/lib_doupdate.c,v retrieving revision 1.11 diff -u -r1.11 lib_doupdate.c --- lib_doupdate.c 1996/09/26 01:08:51 1.11 +++ lib_doupdate.c 1997/02/18 14:57:05 @@ -195,7 +195,7 @@ ** */ -#define BLANK ' '|A_NORMAL +#define BLANK (' '|A_NORMAL) static void ClrUpdate(WINDOW *scr) { Index: src/lib/libncurses/lib_erase.c =================================================================== RCS file: /usr/cvs/src/lib/libncurses/lib_erase.c,v retrieving revision 1.3 diff -u -r1.3 lib_erase.c --- lib_erase.c 1995/05/30 05:46:14 1.3 +++ lib_erase.c 1997/02/18 14:57:51 @@ -13,7 +13,7 @@ #include "curses.priv.h" #include "terminfo.h" -#define BLANK ' ' +#define BLANK (' '|A_NORMAL) int werase(WINDOW *win) { >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702181521.QAA16402>