lynx-dev
[Top][All Lists]
Advanced

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

Re: LYNX-DEV Year 2000 Compliance


From: Bela Lubkin
Subject: Re: LYNX-DEV Year 2000 Compliance
Date: Thu, 26 Feb 1998 03:29:36 -0800

I have done a code review of the Lynx code set (lynx-2.7.1ac-0.97, the
newest I had at hand).  I found a few minor Y2K issues, which should be
fixed before 2.8 (if not already fixed in current development code).

Method of analysis: I grepped the entire Lynx source tree for all
occurrences of the strings:

  1899
  1900
  1901
  1999
  2000
  2001
  date
  time
  year
  yr

(ignoring case).  I manually examined the output to identify all code
which actually manipulated dates.  Then I closely examined each of those
hot spots.

=============================================================================

Results:

1. src/LYUtils.c LYmktime()

This routine is capable of parsing various date formats, including some
that have 2-digit years.  When parsing a 2-digit year, it assumes that
the basis of this year is the current century.  That is, if it sees:

  Mon, 01-Jan-96 13:45:35 GMT

and the current date is 26-Feb-1998, it understands a date of
01-Jan-1996.  If the current date is 04-Feb-2002, it understands a date
of 01-Jan-2096.

This code should only be receiving 2-digit years if it's talking to a
buggy, non-Y2K-compliant sender.  Software which is sending 21st century
dates "should not" still have Y2K bugs.  However, Lynx must be prepared
to deal sanely with any such software which does still exist after 1999.

If we're receiving a 2-digit year, it is most likely a truncated year.
A good heuristic for dealing with these is: if it's 70 or higher, the
sender intended 19xx; otherwise 20xx.  It is extremely *un*likely that
in 2002, "01-Jan-96" would actually mean to refer to 2096!

LYmktime() is used to parse "expires" meta values, cookie attribute
values and HTTP headers, and "date" HTTP headers.  Most of these are
generated by HTTP servers, which I think we can assume will change or
die.  Meta values are generated by web page authors; they live in
potentially static .html files.  Non-Y2K-compliant web pages could exist
for years to come.

RECOMMENDATION: apply this patch.

*** src/LYUtils.c Mon Nov 24 11:17:20 1997
--- src/LYUtils.c+ Thu Feb 26 03:05:30 1998
***************
*** 5392,5398 ****
          LYstrncpy(temp, start, 4);
      } else if ((s - start) == 2) {
        now = time(NULL);
!       LYstrncpy(temp, ((char *)ctime(&now) + 20), 2);
        strncat(temp, start, 2);
        temp[4] = '\0'; 
      } else {
--- 5392,5410 ----
          LYstrncpy(temp, start, 4);
      } else if ((s - start) == 2) {
        now = time(NULL);
!       /*
!        * Assume that received 2-digit dates >= 70 are 19xx; others
!        * are 20xx.  Only matters when dealing with broken software
!        * (HTTP server or web page) which is not Y2K compliant.  The
!        * line is drawn on a best-guess basis; it is impossible for
!        * this to be completely accurate because it depends on what
!        * the broken sender software intends.  (This totally breaks
!        * in 2100 -- setting up the next crisis...) - BL
!        */
!       if (atoi(start) >= 70)
!           LYstrncpy(temp, "19", 2);
!       else
!           LYstrncpy(temp, "20", 2);
        strncat(temp, start, 2);
        temp[4] = '\0'; 
      } else {

2. WWW/Library/Implementation/HTFTP.c

Two functions are at risk: parse_windows_nt_dir_entry() (which is
disabled), and parse_cms_dir_entry().  Both assume that the sending
software (WinNT and VM/CMS FTP servers) send non-Y2K-compliant dates,
with a 2-digit year field.  At the very least, we can assume that new
Y2K versions of these servers will appear, requiring new or modified
versions of these parsing functions.

Both functions also have the same bug as above: they assume that
received 2-digit years refer to the current century:

                /* Not this year, so show the year. */
                if (atoi(cpd) < atoi((char *)&ThisYear[2])) {
                    sprintf((char *)&date[6], "  %c%c%s",
                                              ThisYear[0], ThisYear[1], cpd);
                } else {
                    sprintf((char *)&date[6], "  %c%c%s",
                                              LastYear[0], LastYear[1], cpd);
                }

ThisYear and LastYear are based on the current year, e.g.:

  current year    ThisYear[]   LastYear[]
      1998           1998        1997
      1999           1999        1998
      2000           2000        1999
      2000           2001        2000
      2000           2002        2001

ThisYear's century is used unless the received 2-digit year is less than
the last 2 digits of the current year.  ThisYear's and LastYear's
centuries differ only in 2000.  In 2000, the last 2 digits of the
current year are 00, which is always <= cpd.  So ThisYear's century is
always used.

RECOMMENDATION: replace with code that decides based on the same
criteria as above: >=70 is 19xx, otherwise 20xx.

3. In the disabled parse_windows_nt_dir_entry(),

    if (strlen(cp) == 8 &&
        isdigit(*cp) && isdigit(*(cp+1)) && *(cp+2) == '-' &&
        isdigit(*(cp+3)) && isdigit(*(cp+1)) && *(cp+5) == '-') {
                                      ^^^^
                            should be cp+4

RECOMMENDATION: delete parse_windows_nt_dir_entry() function if it's
actually unnecessary.

>Bela<

-- 
Tales of our recent world trip, http://www.armory.com/~alexia/trip/trip.html

reply via email to

[Prev in Thread] Current Thread [Next in Thread]