From cjc@cc942873-a.ewndsr1.nj.home.com Wed Nov 10 21:39:57 1999
Return-Path: <cjc@cc942873-a.ewndsr1.nj.home.com>
Received: from cc942873-a.ewndsr1.nj.home.com (cc942873-a.ewndsr1.nj.home.com [24.2.89.207])
	by hub.freebsd.org (Postfix) with ESMTP id 5FD3914D25
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 10 Nov 1999 21:39:52 -0800 (PST)
	(envelope-from cjc@cc942873-a.ewndsr1.nj.home.com)
Received: (from cjc@localhost)
	by cc942873-a.ewndsr1.nj.home.com (8.9.3/8.9.3) id AAA45760;
	Thu, 11 Nov 1999 00:43:29 -0500 (EST)
	(envelope-from cjc)
Message-Id: <199911110543.AAA45760@cc942873-a.ewndsr1.nj.home.com>
Date: Thu, 11 Nov 1999 00:43:29 -0500 (EST)
From: "Crist J. Clark" <cjc@cc942873-a.ewndsr1.nj.home.com>
Reply-To: cjc@cc942873-a.ewndsr1.nj.home.com
To: FreeBSD-gnats-submit@freebsd.org
Cc: kevin.ruddy@powerdog.com
Subject: strptime(3) '%C' conversion incorrect
X-Send-Pr-Version: 3.2

>Number:         14817
>Category:       bin
>Synopsis:       strptime(3) '%C' conversion incorrect
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Nov 10 21:40:01 PST 1999
>Closed-Date:    Fri Jul 13 07:22:35 PDT 2001
>Last-Modified:  Fri Jul 13 07:22:51 PDT 2001
>Originator:     Crist J. Clark
>Release:        FreeBSD 3.3-STABLE i386
>Organization:
>Environment:

	FreeBSD 3.3-STABLE. Default C library

>Description:

	The strptime(3) function fills a time 'tm structure' from a
user's string using a format also provided by the user. However, the
'%C' conversion does not work as described in strftime(3) (which
strptime(3) references as containing the key for the conversions), nor
does a simple 'date +%C' return what the actual strptime(3) function
wants.

>How-To-Repeat:

	A C fragment,

		struct tm tm;

		strptime("19","%C",&tm);

		printf("%d\n",tm.tm_year);

Which fails using the existing code. It should return,

		0

Or of we were to substitute "20" for "19",

		100

>Fix:
	
	I actually looked at strptime(3) to fix something else (it
can't read formats that run together, e.g "%y%j%H%M%S"), when I
noticed the way it handles '%C' is contradictory to the manpages and
date(1)'s operation. It was a quick fix. Patch:



--- /usr/src/lib/libc/stdtime/strptime.c        Sun Aug 29 21:55:58 1999
+++ strptime.c  Thu Nov 11 00:38:39 1999
@@ -1,4 +1,13 @@
 /*
+ * 1999/11/11, cjclark@alum.mit.edu
+ *
+ * The '%C' conversion specification did not conform to the documentation
+ * in strftime(3) or in the operation of 'date +%C'. Fixed. The '%C' 
+ * conversion demands _exactly_ two digits (like the output) and must
+ * be in the range 19-20. This 19-20 is converted to 0 or 100 being added
+ * to tm_year.
+ */
+/*
  * Powerdog Industries kindly requests feedback from anyone modifying
  * this function:
  *
@@ -115,12 +124,6 @@
                                return 0;
                        break;
 
-               case 'C':
-                       buf = _strptime(buf, Locale->date_fmt, tm);
-                       if (buf == 0)
-                               return 0;
-                       break;
-
                case 'c':
                        buf = _strptime(buf, "%x %X", tm);
                        if (buf == 0)
@@ -163,7 +166,20 @@
                                return 0;
                        break;
 
-               case 'j':
+               case 'C': /* "Century" (required to be two digits) */
+                       if (!(isdigit((unsigned char)*buf) && isdigit((unsigned char)*(buf+1))))
+                               return 0;
+                       i = 10*(*buf++ - '0');
+                       i += *buf++ - '0';
+
+                       if ((i < 19) || (i > 20))
+                         return 0;
+
+                       tm->tm_year = i*100 - 1900;
+
+                       break;
+
+               case 'j': /* Day of year */
                        if (!isdigit((unsigned char)*buf))
                                return 0;

>Release-Note:
>Audit-Trail:

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: cjc@cc942873-a.ewndsr1.nj.home.com
Cc: FreeBSD-gnats-submit@FreeBSD.ORG, kevin.ruddy@powerdog.com
Subject: Re: bin/14817: strptime(3) '%C' conversion incorrect 
Date: Thu, 11 Nov 1999 11:19:27 +0200

 On Thu, 11 Nov 1999 00:43:29 EST, "Crist J. Clark" wrote:
 
 > However, the '%C' conversion does not work as described in strftime(3)
 > (which strptime(3) references as containing the key for the
 > conversions), nor does a simple 'date +%C' return what the actual
 > strptime(3) function wants.
 
 I think that strptime(3) does behave as expected.  I think you're
 assuming too much.
 
 > 		struct tm tm;
 > 
 > 		strptime("19","%C",&tm);
 > 
 > 		printf("%d\n",tm.tm_year);
 
 You can't expect tm_year to contain anything sensible after your call to
 strptime, because you haven't given it enough information.  Try using it
 in conjunction with %g and you'll get sensible results.
 
 Ciao,
 Sheldon.
 

From: "Crist J. Clark" <cjc@cc942873-a.ewndsr1.nj.home.com>
To: sheldonh@uunet.co.za (Sheldon Hearn)
Cc: FreeBSD-gnats-submit@FreeBSD.ORG, kevin.ruddy@powerdog.com
Subject: Re: bin/14817: strptime(3) '%C' conversion incorrect
Date: Thu, 11 Nov 1999 10:43:26 -0500 (EST)

 Sheldon Hearn wrote,
 > On Thu, 11 Nov 1999 00:43:29 EST, "Crist J. Clark" wrote:
 > 
 > > However, the '%C' conversion does not work as described in strftime(3)
 > > (which strptime(3) references as containing the key for the
 > > conversions), nor does a simple 'date +%C' return what the actual
 > > strptime(3) function wants.
 > 
 > I think that strptime(3) does behave as expected.  I think you're
 > assuming too much.
 
 No, it does not. In /usr/src/lib/libc/stdtime/strptime.c we have,
 
                  case 'C':
                         buf = _strptime(buf, Locale->date_fmt, tm);
                         if (buf == 0)
                                 return 0;
                         break;
 
 And in stdftime.c we have,
 
                         case 'C':
                                 /*
                                 ** %C used to do a...
                                 **      _fmt("%a %b %e %X %Y", t);
                                 ** ...whereas now POSIX 1003.2 calls for
                                 ** something completely different.
                                 ** (ado, 5/24/93)
                                 */
                                 pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
                                         "%02d", pt, ptlim);
                                 continue;
 
 Which quite clearly points out theat strptime(3) is using something
 like the _old_ (pre-93!) definition of '%C' contrary to POSIX,
 strftime(3) documentation and functionality, and date(1) functionality.
 
 stdptime.c is clearly wrong.
 
 > > 		struct tm tm;
 > > 
 > > 		strptime("19","%C",&tm);
 > > 
 > > 		printf("%d\n",tm.tm_year);
 > 
 > You can't expect tm_year to contain anything sensible after your call to
 > strptime, because you haven't given it enough information.  Try using it
 > in conjunction with %g and you'll get sensible results.
 
 Well, I would go to show that using the existing '%C' combined with
 '%g' would not work either, but ran into a little problem. '%g' (or
 '%G') is not defined at all in strptime.c.
 
 However, I one might think "%C %y" would accomplish what you would
 like. Unfortunately, '%y' _sets_ tm.tm_year, so even if '%C' did
 what it was supposed to, the result would be wiped out.
 
 So, now that I look at it more closely, since '%y' cannot be used in
 combination with '%C' anyway, '%C' is pretty useless even if it works.
 I also now realize if you have a date like, "10/20/50," there is no
 way to tell strptime() that you mean 1950 and _not_ 2050. You'd have
 to fix tm.tm_year yourself.
 
 It actually might be best to simply elimiate '%C' from strptime.c
 altogether (since the current implementation is incorrect and a fix is
 almost useless even if it works) and make note of some of these issues
 on the manpages. 
 -- 
 Crist J. Clark                           cjclark@home.com
 

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: "Crist J. Clark" <cjc@cc942873-a.ewndsr1.nj.home.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/14817: strptime(3) '%C' conversion incorrect 
Date: Wed, 08 Dec 1999 18:00:59 +0200

 Hi there!
 
 Can you let me know whether rev 1.12 of strptime.c fixed the problem.  I
 haven't looked any deeper than the commit message. :-)
 
 Thanks,
 Sheldon.
 
State-Changed-From-To: open->analyzed 
State-Changed-By: ache 
State-Changed-When: Wed Dec 8 08:34:18 PST 1999 
State-Changed-Why:  
Fixed in -current by different way 
State-Changed-From-To: analyzed->closed 
State-Changed-By: dd 
State-Changed-When: Fri Jul 13 07:22:35 PDT 2001 
State-Changed-Why:  
fixed long ago 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=14817 
>Unformatted:
