Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
time: in strptime(), make %z accept [+-]HH:MM tz [BZ #17887]
In ISO 8601, +03:30 is a valid time zone. Currently, strptime() only
parses it as a 2-digit time zone an believes this is +03:00. This change
makes it accept a single colon.
  • Loading branch information
Vincent Bernat authored and Mike Frysinger committed Sep 18, 2015
1 parent 900f33e commit e952e1d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 13 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
@@ -1,3 +1,9 @@
2015-09-18 Vincent Bernat <vincent@bernat.im>

[BZ #17887]
* time/strptime_l.c (__strptime_internal): Make %z accept
[+-]HH:MM time zones.

2015-09-18 Vincent Bernat <vincent@bernat.im>

[BZ #17886]
Expand Down
10 changes: 5 additions & 5 deletions NEWS
Expand Up @@ -11,11 +11,11 @@ Version 2.23

2542, 2543, 2558, 2898, 4404, 6803, 14341, 14912, 15384, 15786, 15918,
16141, 16296, 16415, 16517, 16519, 16520, 16521, 16734, 16973, 16985,
17118, 17243, 17244, 17787, 17886, 17905, 18084, 18086, 18240, 18265,
18370, 18421, 18480, 18525, 18595, 18610, 18618, 18647, 18661, 18674,
18675, 18681, 18757, 18778, 18781, 18787, 18789, 18790, 18795, 18796,
18820, 18823, 18824, 18857, 18863, 18870, 18872, 18873, 18875, 18887,
18921, 18951, 18952, 18961, 18966, 18967, 18970, 18977.
17118, 17243, 17244, 17787, 17886, 17887, 17905, 18084, 18086, 18240,
18265, 18370, 18421, 18480, 18525, 18595, 18610, 18618, 18647, 18661,
18674, 18675, 18681, 18757, 18778, 18781, 18787, 18789, 18790, 18795,
18796, 18820, 18823, 18824, 18857, 18863, 18870, 18872, 18873, 18875,
18887, 18921, 18951, 18952, 18961, 18966, 18967, 18970, 18977.

* The obsolete header <regexp.h> has been removed. Programs that require
this header must be updated to use <regex.h> instead.
Expand Down
10 changes: 7 additions & 3 deletions time/strptime_l.c
Expand Up @@ -749,9 +749,11 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
rp++;
break;
case 'z':
/* We recognize three formats: if two digits are given, these
specify hours. If fours digits are used, minutes are
also specified. 'Z' is equivalent to +0000. */
/* We recognize four formats:
1. Two digits specify hours.
2. Four digits specify hours and minutes.
3. Two digits, ':', and two digits specify hours and minutes.
4. 'Z' is equivalent to +0000. */
{
val = 0;
while (ISSPACE (*rp))
Expand All @@ -770,6 +772,8 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
{
val = val * 10 + *rp++ - '0';
++n;
if (*rp == ':' && n == 2 && isdigit (*(rp + 1)))
++rp;
}
if (n == 2)
val *= 100;
Expand Down
25 changes: 20 additions & 5 deletions time/tst-strptime2.c
Expand Up @@ -35,7 +35,8 @@ static bool verbose;
following fields:
Sign field consisting of a '+' or '-' sign,
Hours field in two decimal digits, and
optional Minutes field in two decimal digits.
optional Minutes field in two decimal digits. Optionally,
a ':' is used to seperate hours and minutes.
This function may write test strings with minutes values outside
the valid range 00-59. These are invalid strings and useful for
Expand All @@ -56,7 +57,7 @@ static bool verbose;
range of 00 to 59. */

static long int
mkbuf (char *buf, bool neg, unsigned int hhmm, size_t ndigits)
mkbuf (char *buf, bool neg, bool colon, unsigned int hhmm, size_t ndigits)
{
const int mm_max = 59;
char sign = neg ? '-' : '+';
Expand All @@ -66,7 +67,10 @@ mkbuf (char *buf, bool neg, unsigned int hhmm, size_t ndigits)
long int expect = LONG_MAX;

i = sprintf (buf, "%s %c", dummy_string, sign);
snprintf (buf + i, ndigits + 1, "%04u", hhmm);
if (colon)
snprintf (buf + i, ndigits + 2, "%02u:%02u", hh, mm);
else
snprintf (buf + i, ndigits + 1, "%04u", hhmm);

if (mm <= mm_max && (ndigits == 2 || ndigits == 4))
{
Expand Down Expand Up @@ -177,11 +181,22 @@ do_test (void)
{
/* Test both positive and negative signs. */

expect = mkbuf (buf, false, hhmm, ndigits);
expect = mkbuf (buf, false, false, hhmm, ndigits);
result |= compare (buf, expect, nresult);

expect = mkbuf (buf, true, hhmm, ndigits);
expect = mkbuf (buf, true, false, hhmm, ndigits);
result |= compare (buf, expect, nresult);

/* Test with colon as well. */

if (ndigits >= 3)
{
expect = mkbuf (buf, false, true, hhmm, ndigits);
result |= compare (buf, expect, nresult);

expect = mkbuf (buf, true, true, hhmm, ndigits);
result |= compare (buf, expect, nresult);
}
}

if (result > 0 || verbose)
Expand Down

0 comments on commit e952e1d

Please sign in to comment.