Loading...
--- Libc/Libc-498.1.7/stdtime/FreeBSD/strptime.c.patch
+++ Libc/Libc-763.13/stdtime/FreeBSD/strptime.c.patch
@@ -1,8 +1,8 @@
---- strptime.c.orig 2008-04-24 01:10:36.000000000 -0700
-+++ strptime.c 2008-04-24 02:01:31.000000000 -0700
-@@ -61,10 +61,13 @@ static char sccsid[] __unused = "@(#)str
+--- strptime.c.orig 2009-11-14 13:55:44.000000000 -0800
++++ strptime.c 2009-11-18 16:56:27.000000000 -0800
+@@ -61,41 +61,55 @@ static char sccsid[] __unused = "@(#)str
#endif /* not lint */
- __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $");
+ __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.37 2009/09/02 04:56:30 ache Exp $");
+#include "xlocale_private.h"
+
@@ -14,28 +14,28 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
-@@ -72,30 +75,41 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime
++#include <stdint.h>
++#include <limits.h>
+ #include "un-namespace.h"
#include "libc_private.h"
#include "timelocal.h"
-static char * _strptime(const char *, const char *, struct tm *, int *);
-+static char * _strptime(const char *, const char *, struct tm *, int *, locale_t) __DARWIN_ALIAS(_strptime);
+time_t _mktime(struct tm *, const char *);
#define asizeof(a) (sizeof (a) / sizeof ((a)[0]))
+enum {CONVERT_NONE, CONVERT_GMT, CONVERT_ZONE};
++
++#define _strptime(b,f,t,c,l) _strptime0(b,f,t,c,l,-1,0,-1)
+
static char *
-_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp)
-+_strptime(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t loc)
++_strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t loc, int year, int yday, int wday)
{
char c;
const char *ptr;
int i,
-+ year = -1,
-+ yday = 0,
-+ wday = -1,
len;
int Ealternative, Oalternative;
- struct lc_time_T *tptr = __get_current_time_locale();
@@ -50,7 +50,7 @@
+ while (isspace_l((unsigned char)*ptr, loc)) {
+ ptr++;
+ }
-+ return ((*ptr)==0) ? fmt : 0; /* trailing whitespace is ok */
++ return ((*ptr)==0) ? (char *)fmt : 0; /* trailing whitespace is ok */
+ }
c = *ptr++;
@@ -445,7 +445,7 @@
if (errno == ERANGE || (long)(t = n) != n) {
errno = sverrno;
return 0;
-@@ -458,24 +508,37 @@ label:
+@@ -458,24 +508,82 @@ label:
errno = sverrno;
buf = cp;
gmtime_r(&t, tm);
@@ -466,10 +466,55 @@
+#if __DARWIN_UNIX03
+ if (c == 'Y') {
-+ for (i = 0; *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
-+ i *= 10;
-+ i += *buf - '0';
++ int savei = 0;
++ const char *savebuf = buf;
++ int64_t i64 = 0;
++ int overflow = 0;
++
++ for (len = 0; *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
++ i64 *= 10;
++ i64 += *buf - '0';
++ if (++len <= 4) {
++ savei = i64;
++ savebuf = buf + 1;
++ }
++ if (i64 > INT_MAX) {
++ overflow++;
++ break;
++ }
+ }
++ /*
++ * Conformance requires %Y to be more then 4
++ * digits. However, there are several cases
++ * where %Y is immediately followed by other
++ * digits values. So we do the conformance
++ * case first (as many digits as possible),
++ * and if we fail, we backup and try just 4
++ * digits for %Y.
++ */
++ if (len > 4 && !overflow) {
++ struct tm savetm = *tm;
++ int saveconv = *convp;
++ const char *saveptr = ptr;
++ char *ret;
++
++ if (i64 < 1900)
++ return 0;
++
++ tm->tm_year = i64 - 1900;
++
++ if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%')
++ ptr++;
++ ret = _strptime0(buf, ptr, tm, convp, loc, tm->tm_year, yday, wday);
++ if (ret) return ret;
++ /* Failed, so try 4-digit year */
++ *tm = savetm;
++ *convp = saveconv;
++ ptr = saveptr;
++ }
++ buf = savebuf;
++ i = savei;
+ } else {
+ len = 2;
+#else /* !__DARWIN_UNIX03 */
@@ -487,7 +532,7 @@
if (c == 'Y')
i -= 1900;
if (c == 'y' && i < 69)
-@@ -483,35 +546,58 @@ label:
+@@ -483,37 +591,40 @@ label:
if (i < 0)
return 0;
@@ -543,29 +588,30 @@
+ break;
+ }
+ return 0;
-+ }
-+
-+ case 'z':
-+ {
-+ char sign;
-+ int hr, min;
-+
-+ if ((buf[0] != '+' && buf[0] != '-')
-+ || !isdigit_l((unsigned char)buf[1], loc)
-+ || !isdigit_l((unsigned char)buf[2], loc)
-+ || !isdigit_l((unsigned char)buf[3], loc)
-+ || !isdigit_l((unsigned char)buf[4], loc))
-+ return 0;
-+ sscanf(buf, "%c%2d%2d", &sign, &hr, &min);
-+ *convp = CONVERT_ZONE;
-+ tm->tm_gmtoff = 60 * (60 * hr + min);
-+ if (sign == '-')
-+ tm->tm_gmtoff = -tm->tm_gmtoff;
-+ buf += 5;
+ }
+- break;
+
+ case 'z':
+ {
+@@ -529,7 +640,7 @@ label:
+ buf++;
+ i = 0;
+ for (len = 4; len > 0; len--) {
+- if (isdigit((unsigned char)*buf)) {
++ if (isdigit_l((unsigned char)*buf, loc)) {
+ i *= 10;
+ i += *buf - '0';
+ buf++;
+@@ -539,7 +650,7 @@ label:
+
+ tm->tm_hour -= sign * (i / 100);
+ tm->tm_min -= sign * (i % 100);
+- *GMTp = 1;
++ *convp = CONVERT_GMT;
}
break;
}
-@@ -524,14 +610,39 @@ char *
+@@ -552,14 +663,39 @@ char *
strptime(const char * __restrict buf, const char * __restrict fmt,
struct tm * __restrict tm)
{