From nick@triantos.com  Thu Mar  6 22:30:23 2003
Return-Path: <nick@triantos.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id B6B2737B401
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  6 Mar 2003 22:30:23 -0800 (PST)
Received: from triantos.com (mail.triantos.com [66.127.67.82])
	by mx1.FreeBSD.org (Postfix) with SMTP id C020A43FA3
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  6 Mar 2003 22:30:22 -0800 (PST)
	(envelope-from nick@triantos.com)
Received: (qmail 90966 invoked from network); 7 Mar 2003 06:31:51 -0000
Received: from router.triantos.com (HELO yoonicksxp) (66.127.67.83)
  by triantos.com with SMTP; 7 Mar 2003 06:31:51 -0000
Message-Id: <000601c2e473$0c2bbc40$1601a8c0@triantos.com>
Date: Thu, 6 Mar 2003 22:30:03 -0800
From: "Nick Triantos" <nick@triantos.com>
To: <FreeBSD-gnats-submit@freebsd.org>
Subject: strptime() does not fill in some fields of struct tm

>Number:         48993
>Category:       misc
>Synopsis:       strptime() does not fill in some fields of struct tm
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    mtm
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 06 22:40:04 PST 2003
>Closed-Date:    Mon May 19 11:19:52 PDT 2003
>Last-Modified:  Mon May 19 11:19:52 PDT 2003
>Originator:     Nick Triantos
>Release:        FreeBSD 5.0-RELEASE i386
>Organization:
triantos.com
>Environment:
System: FreeBSD yoonicks-bsd.triantos.com 5.0-RELEASE FreeBSD
5.0-RELEASE #0: Thu Jan 16 22:16:53 GMT 2003
root@hollin.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC i386
using out-of-the box freebsd 5.0 libc


	
>Description:
	
The strptime() function does not fill in the complete 'tm' struct upon
successful return.  This behaviour is different than on Linux and
Windows.  In particular, the tm_wday and tm_yday fields are 0 on exit
from the function.

I found this bug because TMDA (http://www.tmda.net) failed to display
dates correctly.  I debugged through the python, into the python souce,
and eventually into the source for
'/usr/src/lib/libc/stdtime/strptime.c'.

>How-To-Repeat:

Compile this simple program:

#include <time.h>
#include <stdio.h>

char *orig   = "27 Feb 2003 16:45:59";
char *format = "%d %b %Y %H:%M:%S";
struct tm timeobj;

int main(int argc, char *argv[])
{
    printf("orig  : %s\n", orig);
    printf("format: %s\n", format);

    if (strptime(orig, format, &timeobj) == NULL) {
        printf("ERROR: Couldn't parse the string.\n");
        return 1;
    }

    printf("\n");
    printf("timeobj = {\n");
    printf("    tm_sec    = %d\n", timeobj.tm_sec);
    printf("    tm_min    = %d\n", timeobj.tm_min);
    printf("    tm_hour   = %d\n", timeobj.tm_hour);
    printf("    tm_mday   = %d\n", timeobj.tm_mday);
    printf("    tm_mon    = %d (0-11)\n", timeobj.tm_mon);
    printf("    tm_year   = %d (%d)\n", timeobj.tm_year,
timeobj.tm_year+1900);
    printf("    tm_wday   = %d (days since Sun)\n", timeobj.tm_wday);
    printf("    tm_yday   = %d (days since Jan 1)\n", timeobj.tm_yday);
    printf("}\n");

    return 0;
}

>Fix:

Change file /usr/src/lib/libc/stdtime/strptime.c, function strptime() to
match below.  In particular, if (ret && !got_GMT), the function should
call mktime() and localtime_r() to get localtime_r() to fill in the
remaining fields.

- - - - -

strptime(const char * __restrict buf, const char * __restrict fmt,
    struct tm * __restrict tm)
{
	char *ret;

	if (__isthreaded)
		_pthread_mutex_lock(&gotgmt_mutex);

	got_GMT = 0;
	ret = _strptime(buf, fmt, tm);
	if (ret) {
		if (got_GMT) {
			time_t t = timegm(tm);
			localtime_r(&t, tm);
			got_GMT = 0;
		} else {
			time_t t = mktime(tm);
			localtime_r(&t, tm);
		}
	}

	if (__isthreaded)
		_pthread_mutex_unlock(&gotgmt_mutex);

	return ret;
}

>Release-Note:
>Audit-Trail:

From: Mike Makonnen <mtm@identd.net>
To: "Nick Triantos" <nick@triantos.com>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: misc/48993: strptime() does not fill in some fields of struct
 tm
Date: Fri, 7 Mar 2003 08:08:19 -0500

 Well, the man page says:
 
      If the format string does not contain enough conversion specifications to
      completely specify the resulting struct tm, the unspecified members of
      timeptr are left untouched.  For example, if format is ``%H:%M:%S'', only
      tm_hour, tm_sec and tm_min will be modified.  If time relative to today
      is desired, initialize the timeptr structure with today's date before
      passing it to strptime().
 
 This is a clear contradiction with the actual code since, if the %s or %Z
 specifiers are used then GMT processing is assumed (unconditionaly for the first
 and conditional upon a GMT string in the second case) and the rest of the fields
 are filled in. This does not occur if a non-GMT time is used. This strikes me as
 inconsistent. Either the rest of the fields should be unconditionaly filled in
 or not. Your suggestion seems reasonable, but I don't know if there are any
 Standards issues involved.
 I'll supply a patch to  freebsd-standards, and if no one objects, commit it.
 
 Cheers
 -- 
 Mike Makonnen  | GPG-KEY: http://www.identd.net/~mtm/mtm.asc
 mtm@identd.net | Fingerprint: D228 1A6F C64E 120A A1C9  A3AA DAE1 E2AF DBCC 68B9
State-Changed-From-To: open->patched 
State-Changed-By: mtm 
State-Changed-When: Sat Mar 29 03:56:15 PST 2003 
State-Changed-Why:  
Fix committed to -CURRENT 


Responsible-Changed-From-To: freebsd-bugs->mtm 
Responsible-Changed-By: mtm 
Responsible-Changed-When: Sat Mar 29 03:56:15 PST 2003 
Responsible-Changed-Why:  
Take this PR as a reminder to MFC (in about 4 weeks). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48993 
State-Changed-From-To: patched->closed 
State-Changed-By: mtm 
State-Changed-When: Mon May 19 11:15:34 PDT 2003 
State-Changed-Why:  
I have backed out this change from -CURRENT. There is  
software that depends on this behaviour. We would also be 
diverging from behaviour in teh other BSDs. 

My suggestion is that you submit a patch to the ports team 
to be applied at build time (if this was a port that was malfunctioning). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48993 
>Unformatted:
