public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/2] [BZ #16141] strptime: fix %z minutes calculation
@ 2014-12-02 23:48 James Perkins
  0 siblings, 0 replies; only message in thread
From: James Perkins @ 2014-12-02 23:48 UTC (permalink / raw)
  To: libc-alpha

This is a fix for [BZ #16141] strptime %z offset restriction.

strptime supports the parsing of a timezone offset from UTC time into the
broken-out time field tm_gmtoff. It supports timezone offsets between
UTC-12:00 and UTC+12:00, returning an error (NULL) for values outside
that range.

However, the minutes portion calculation is correct only for minutes
portion values evenly divisible by 3. This is because the minutes value
is converted to decimal time, and rounding results in an incorrect offset
calculation. For example, a +1159 offset string results in a tm_gmtoff
of 43128 (== 11 * 3600 + 3528) seconds, instead of 43140 (== 11 * 3600 +
59 * 60) seconds.

This fix calculates the offset from the hour and minute portions directly,
without the rounding errors introduced by decimal time.

James

2014-12-02  James Perkins  james@loowit.net

	[BZ #16141]
	* time/strptime_l.c (__strptime_internal): Fix %z minutes
	calculation, removing incorrect decimal time rounding, so that
	all minute values result in a valid seconds value

---
 time/strptime_l.c |   12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/time/strptime_l.c b/time/strptime_l.c
index 2140c47..92bd71b 100644
--- a/time/strptime_l.c
+++ b/time/strptime_l.c
@@ -770,20 +770,16 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
 	    else if (n != 4)
 	      /* Only two or four digits recognized.  */
 	      return NULL;
-	    else
-	      {
-		/* We have to convert the minutes into decimal.  */
-		if (val % 100 >= 60)
-		  return NULL;
-		val = (val / 100) * 100 + ((val % 100) * 50) / 30;
-	      }
+	    else if (val % 100 >= 60)
+	      /* minutes valid range is 0 through 59. */
+	      return NULL;
 	    /* minimum UTC-12, used aboard ships */
 	    if (neg && val > 1200)
 	      return NULL;
 	    /* maximum UTC+14, Pacific/Kiritimati and Pacific/Apia summer time */
 	    if (!neg && val > 1400)
 	      return NULL;
-	    tm->tm_gmtoff = (val * 3600) / 100;
+	    tm->tm_gmtoff = (val / 100) * 3600 + (val % 100) * 60;
 	    if (neg)
 	      tm->tm_gmtoff = -tm->tm_gmtoff;
 	  }
-- 
1.7.9.5

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-12-02 23:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-02 23:48 [PATCH 2/2] [BZ #16141] strptime: fix %z minutes calculation James Perkins

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).