NetBSD Problem Report #50380

From  Thu Oct 29 14:04:36 2015
Return-Path: <>
Received: from ( [])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "", Issuer "Postmaster" (verified OK))
	by (Postfix) with ESMTPS id A4C5AA57FE
	for <>; Thu, 29 Oct 2015 14:04:36 +0000 (UTC)
Message-Id: <>
Date: Thu, 29 Oct 2015 14:04:35 +0000 (UTC)
Subject: strptime() returns incorrect values in tm_gmtoff
X-Send-Pr-Version: www-1.0

>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
>Last-Modified:  Thu Oct 29 17:55:01 +0000 2015
>Originator:     Balazs Scheidler
>Release:        /*	$NetBSD: strptime.c,v 1.49 2015/10/09 17:21:45 christos Exp $	*/
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:

$ 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.
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.


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.

From: "Christos Zoulas" <>
Subject: PR/50380 CVS commit: src/lib/libc/time
Date: Thu, 29 Oct 2015 13:54:49 -0400

 Module Name:	src
 Committed By:	christos
 Date:		Thu Oct 29 17:54:49 UTC 2015

 Modified Files:
 	src/lib/libc/time: strptime.3 strptime.c

 Log Message:
 PR/50380: Balazs Scheidler: strptime() returns incorrect values in tm_gmtoff
 - Always offset in seconds.
 - Handle arbitrary timezones.

 To generate a diff of this commit:
 cvs rdiff -u -r1.31 -r1.32 src/lib/libc/time/strptime.3
 cvs rdiff -u -r1.49 -r1.50 src/lib/libc/time/strptime.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD:,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.