NetBSD-Bugs archive

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

lib/50380: strptime() returns incorrect values in tm_gmtoff



>Number:         50380
>Category:       lib
>Synopsis:       strptime() returns incorrect values in tm_gmtoff
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Oct 29 14:05:01 +0000 2015
>Originator:     Balazs Scheidler
>Release:        /*	$NetBSD: strptime.c,v 1.49 2015/10/09 17:21:45 christos Exp $	*/
>Organization:
>Environment:
>Description:
I was trying to reuse the strptime() implementation from NetBSD in a project of mine, specifically it had good support for %z and %Z specifiers.

The issue is that it doesn't work, and I've fixed that up in my local tree, but I've figured those should be fixed upstream as well.

tm_gmtoff should be in seconds, at least tm(3) documents it as such:

http://man.netbsd.org/6.1/usr/share/man/html3/tm.html

$ grep -n TM_GMTOFF strptime.orig.c
428:#ifdef TM_GMTOFF
429:				tm->TM_GMTOFF = 0;
441:#ifdef TM_GMTOFF
442:					tm->TM_GMTOFF = -(timezone);
484:#ifdef TM_GMTOFF
485:				tm->TM_GMTOFF = 0;
501:#ifdef TM_GMTOFF
502:					tm->TM_GMTOFF = -5 - i;
513:#ifdef TM_GMTOFF
514:					tm->TM_GMTOFF = -4 - i;
525:#ifdef TM_GMTOFF
528:						tm->TM_GMTOFF = 
529:                                                   ('A' - 1) - (int)*bp;
531:						tm->TM_GMTOFF = 'A' - (int)*bp;
533:						tm->TM_GMTOFF = (int)*bp - 'M';
573:#ifdef TM_GMTOFF
574:			tm->TM_GMTOFF = offs;


Of course zero initialization doesn't matter, but a few of the instances above are definitely bogus:

* strptime.c:443: "timezone" seems to be a function on NetBSD (unlike Linux, where it is actually the seconds from UTC as set in localtime)
* strptime.c:502, 514, 529, 531 & 533: expressions such as "(-5 - i)" and "-4 - i" seems to set gmtoff as hours and not seconds
* strptime.c:574: is the code that parses %z, there "offs" must be multiplied by 3600/100=36 to get the correct value.

I am not personally using NetBSD, but the software I write does support NetBSD, and the exact reason I am planning a private
strptime() implementation is its unreliability on various platforms, especially wrt timezones.

All in all, I am personally not affected by the bug right now, but some of my users are or could be in the future.

I've figured I'd file this PR to make NetBSD better.
>How-To-Repeat:
Well, just write a simple program that calls strptime() with %z and/or %Z format strings and watch tm_gmtoff being set to an incorrect value.

>Fix:

The timezone() function part I don't really know, but the others are either to be multiplied by 3600 (to get seconds from hours), the "%z" one at the end should be multiplied by 36 to get the proper value.



Home | Main Index | Thread Index | Old Index