NetBSD-Bugs archive

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

Re: bin/41945: calendar(1) doesn't recognize days of the week correctly sometimes



    Date:        Thu, 27 Aug 2009 04:28:40 +0000
    From:        David Holland <dholland-bugs%NetBSD.org@localhost>
    Message-ID:  <20090827042840.GA12220%netbsd.org@localhost>

  | The problem is that it's conflating days of the week with days of the
  | month. Friday is day 6 of the week, apparently.

No, it is much simpler than that, a beginners programming bug....

  | The logic involved is structured with chewing gum and fixing it
  | robustly does not look to be entirely trivial. :-/

Try the patch below.

It seems as if someone believed that

        if (f & (A|B))

means "if both A and B are set in f" - that's obvious, as the code
does (essentially)

        if (f & (A|B))
                return (1);
        if (f & A)
                /* other stuff */

in which the other stuff cannot possibly be executed, as if A was
set, we would have already returned.

The patch just rewrites those tests to be
        if ((f & (A|B)) == (A|B))
which is clearly what the code author intended.

How this has lasted in calendar all this time (and unnoticed) I
hate to imagine - I guess very few people ever use this thing
(and at that, just how many of us system admins do what the man
page says and set the system holiday files correctly for the current year,
every year...)

kre

--- /usr/src/usr.bin/calendar/calendar.c        2005-07-15 16:45:04.000000000 
+0700
+++ calendar.c  2009-10-14 17:23:43.000000000 +0700
@@ -276,13 +276,15 @@
                }
        }
 
-       if (flags & (F_WILDMONTH|F_WILDDAY))
+       if ((flags & (F_WILDMONTH|F_WILDDAY)) == (F_WILDMONTH|F_WILDDAY))
                return (1);
 
-       if ((flags & (F_WILDMONTH|F_ISDAY)) && (day == tp->tm_mday))
+       if (((flags & (F_WILDMONTH|F_ISDAY)) == (F_WILDMONTH|F_ISDAY)) &&
+           (day == tp->tm_mday))
                return (1);
 
-       if ((flags & (F_ISMONTH|F_WILDDAY)) && (month == tp->tm_mon + 1))
+       if (((flags & (F_ISMONTH|F_WILDDAY)) == (F_ISMONTH|F_WILDDAY)) &&
+           (month == tp->tm_mon + 1))
                return (1);
 
        if (flags & F_ISDAY)




Home | Main Index | Thread Index | Old Index