Subject: lib/5056: strptime(3) is broken
To: None <gnats-bugs@gnats.netbsd.org>
From: NAKAJIMA Yoshihiro <nakayosh@kcn.or.jp>
List: netbsd-bugs
Date: 02/24/1998 23:33:57
>Number: 5056
>Category: lib
>Synopsis: strptime(3) is broken
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: lib-bug-people (Library Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Feb 24 06:35:01 1998
>Last-Modified:
>Originator: NAKAJIMA Yoshihiro
>Organization:
>Release: NetBSD-current 98/02/23
>Environment:
System: NetBSD asura 1.3D NetBSD 1.3D (ASURA) #3: Tue Feb 24 21:15:07 JST 1998 nakayosh@asura:/usr/src/sys/arch/i386/compile/ASURA i386
>Description:
strptime(3) is broken.
1. `%m' assigns [1,12] to tm_mon.
2. `%I' requires [0,11].
3. `%S' requires [1,61].
>How-To-Repeat:
% cat test.c
#include <stdio.h>
#include <time.h>
int main(void)
{
char *mon[] = { "Jan", "Feb" /* snip */ };
struct tm tm;
char *format, *buffer;
printf("CASE 1:\t");
format = "%m";
buffer = "01"; /* Jan */
strptime(buffer, format, &tm);
printf("%s\n", mon[tm.tm_mon]);
printf("CASE 2:\t");
format = "%I";
buffer = "12";
if (strptime(buffer, format, &tm) == NULL)
printf("ERROR\n");
else
printf("%02d\n", tm.tm_hour);
printf("CASE 3:\t");
format = "%S";
buffer = "00";
if (strptime(buffer, format, &tm) == NULL)
printf("ERROR\n");
else
printf("%02d\n", tm.tm_sec);
return 0;
}
% cc test.c
% ./a.out
CASE 1: Feb
CASE 2: ERROR
CASE 3: ERROR
>Fix:
diff -u src/lib/libc/time/strptime.c.orig src/lib/libc/time/strptime.c
--- src/lib/libc/time/strptime.c.orig Wed Jan 21 21:16:48 1998
+++ src/lib/libc/time/strptime.c Tue Feb 24 21:35:37 1998
@@ -240,7 +240,7 @@
/* FALLTHROUGH */
case 'I':
_LEGAL_ALT(_ALT_O);
- if (!(_conv_num(&bp, &tm->tm_hour, 0, 11)))
+ if (!(_conv_num(&bp, &tm->tm_hour, 1, 12)))
return (0);
break;
@@ -260,6 +260,7 @@
_LEGAL_ALT(_ALT_O);
if (!(_conv_num(&bp, &tm->tm_mon, 1, 12)))
return (0);
+ tm->tm_mon--;
break;
case 'p': /* The locale's equivalent of AM/PM. */
@@ -290,7 +291,7 @@
case 'S': /* The seconds. */
_LEGAL_ALT(_ALT_O);
- if (!(_conv_num(&bp, &tm->tm_sec, 1, 61)))
+ if (!(_conv_num(&bp, &tm->tm_sec, 0, 61)))
return (0);
break;
>Audit-Trail:
>Unformatted: