From owner-freebsd-stable Wed Sep 22 8:36:39 1999 Delivered-To: freebsd-stable@freebsd.org Received: from chronis.pobox.com (chronis.pobox.com [208.210.124.49]) by hub.freebsd.org (Postfix) with ESMTP id BFFDC15017 for ; Wed, 22 Sep 1999 08:36:35 -0700 (PDT) (envelope-from scott@chronis.pobox.com) Received: by chronis.pobox.com (Postfix, from userid 1001) id D0F299B46; Wed, 22 Sep 1999 11:36:33 -0400 (EDT) Date: Wed, 22 Sep 1999 11:36:33 -0400 From: scott To: freebsd-stable@freebsd.org Subject: strptime bug? Message-ID: <19990922113633.A15733@chronis.pobox.com> Mail-Followup-To: freebsd-stable@freebsd.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.95.7i Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG I have a number of dates in YYYYMMDD format (eg 19990922), and am using strptime to parse them, but it's not working: #include #include 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