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>
index | next in thread | raw e-mail
>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:
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702181521.QAA16402>
