Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Sep 1999 11:36:33 -0400
From:      scott <scott@chronis.pobox.com>
To:        freebsd-stable@freebsd.org
Subject:   strptime bug?
Message-ID:  <19990922113633.A15733@chronis.pobox.com>

next in thread | raw e-mail | index | archive | help
I have a number of dates in YYYYMMDD format (eg 19990922), and am
using strptime to parse them, but it's not working:


#include <stdio.h>
#include <time.h>

int main(int argc, char * argv[]) {
    struct tm t;
    char * foo;
    foo = strptime("19991023", "%Y%m %d", &t);
    if (foo == NULL)
        printf("foo is NULL!\n");
    else
        printf("foo: '%s'\n", foo);
    printf("tm.tm_year: %d tm.tm_month: %d tm.tm_mday: %d\n", t.tm_year, t.tm_mon, t.tm_mday);
    return 0;
}


this prints out:
0922 11:17 chronis:libc/stdtime# /tmp/t
foo: ''
tm.tm_year: 19989123 tm.tm_month: 671465728 tm.tm_mday: -1077945476
0922 11:17 chronis:libc/stdtime#

(BTW)
0922 11:34 chronis:login/pay% uname -a
FreeBSD chronis.pobox.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Sep 20
09:58:31 EDT 1999 root@chronis.pobox.com:/usr/src/sys/compile/MYBSD  i386

So I took a closer look at the code for strptime in
/usr/src/lib/libc/stdtime/strptime.c and found what appears to be the
problem.  Below is a snippit from when the code evaluates a format for
year ('%y') (or year including century '%Y').


		case 'y':
			if (*buf == 0 || isspace((unsigned char)*buf))
				break;

			if (!isdigit((unsigned char)*buf))
				return 0;

			for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
				i *= 10;
				i += *buf - '0';
			}
			if (c == 'Y')
				i -= 1900;
			if (c == 'y' && i < 69)
				i += 100;
			if (i < 0)
				return 0;

			tm->tm_year = i;

			if (*buf != 0 && isspace((unsigned char)*buf))
				while (*ptr != 0 && !isspace((unsigned char)*ptr))
					ptr++;
			break;

The problem appears to be that the for (1 = 0... loop isn't terminated
after the maximum of 4 digits.  While one may argue that years can be
 > 9999, I think it's safe to say all this will change before that
becomes relevant.  Additionally, the check for month ('%m'), isn't
bounded at 2 digits, and there should never be more than 12 months.

In my opinion, these checks against a maximum number of digits should
be done.  If there's a consensus on this, I'll post a patch for the
maintainers, otherwise, I'll either have to learn to live with this
deficiency, or patch my own systems.

Apologies if this has been discussed before, a quick search of the
archives didn't turn up anything directly relevant.


scott



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990922113633.A15733>