X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/224c70764cab4e0e39a26aaf3ad3016552f62f55..1f2f436a38f7ae2d39a943ad2898d8fed4ed2e58:/stdtime/FreeBSD/strptime.c.patch diff --git a/stdtime/FreeBSD/strptime.c.patch b/stdtime/FreeBSD/strptime.c.patch index 2c6acc5..5bce7e0 100644 --- a/stdtime/FreeBSD/strptime.c.patch +++ b/stdtime/FreeBSD/strptime.c.patch @@ -1,8 +1,8 @@ ---- strptime.c.orig 2007-04-03 12:19:24.000000000 -0700 -+++ strptime.c 2007-04-03 12:39:20.000000000 -0700 -@@ -61,10 +61,13 @@ +--- 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 #include #include -@@ -72,30 +75,41 @@ ++#include ++#include + #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++; @@ -63,7 +63,7 @@ buf++; else if (c != *buf++) return 0; -@@ -114,18 +128,18 @@ +@@ -114,18 +128,18 @@ label: break; case '+': @@ -85,7 +85,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -133,17 +147,21 @@ +@@ -133,17 +147,21 @@ label: if (i < 19) return 0; @@ -109,7 +109,7 @@ if (buf == 0) return 0; break; -@@ -161,47 +179,55 @@ +@@ -161,47 +179,55 @@ label: goto label; case 'F': @@ -173,7 +173,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -209,19 +235,19 @@ +@@ -209,19 +235,19 @@ label: if (i < 1 || i > 366) return 0; @@ -197,7 +197,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -237,8 +263,8 @@ +@@ -237,8 +263,8 @@ label: tm->tm_sec = i; } @@ -208,7 +208,7 @@ ptr++; break; -@@ -254,11 +280,11 @@ +@@ -254,11 +280,11 @@ label: * XXX The %l specifier may gobble one too many * digits if used incorrectly. */ @@ -222,7 +222,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -271,8 +297,8 @@ +@@ -271,8 +297,8 @@ label: tm->tm_hour = i; @@ -233,7 +233,7 @@ ptr++; break; -@@ -282,7 +308,7 @@ +@@ -282,7 +308,7 @@ label: * specifiers. */ len = strlen(tptr->am); @@ -242,7 +242,7 @@ if (tm->tm_hour > 12) return 0; if (tm->tm_hour == 12) -@@ -292,7 +318,7 @@ +@@ -292,7 +318,7 @@ label: } len = strlen(tptr->pm); @@ -251,7 +251,7 @@ if (tm->tm_hour > 12) return 0; if (tm->tm_hour != 12) -@@ -307,34 +333,28 @@ +@@ -307,34 +333,28 @@ label: case 'a': for (i = 0; i < asizeof(tptr->weekday); i++) { len = strlen(tptr->weekday[i]); @@ -295,7 +295,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -342,23 +362,46 @@ +@@ -342,23 +362,46 @@ label: if (i > 53) return 0; @@ -352,7 +352,7 @@ ptr++; break; -@@ -372,11 +415,18 @@ +@@ -372,11 +415,18 @@ label: * XXX The %e specifier may gobble one too many * digits if used incorrectly. */ @@ -374,7 +374,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -386,8 +436,8 @@ +@@ -386,8 +436,8 @@ label: tm->tm_mday = i; @@ -385,7 +385,7 @@ ptr++; break; -@@ -398,19 +448,19 @@ +@@ -398,19 +448,19 @@ label: if (Oalternative) { if (c == 'B') { len = strlen(tptr->alt_month[i]); @@ -411,7 +411,7 @@ break; } } -@@ -422,11 +472,11 @@ +@@ -422,11 +472,11 @@ label: break; case 'm': @@ -425,7 +425,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -436,8 +486,8 @@ +@@ -436,8 +486,8 @@ label: tm->tm_mon = i - 1; @@ -436,7 +436,7 @@ ptr++; break; -@@ -450,7 +500,7 @@ +@@ -450,7 +500,7 @@ label: sverrno = errno; errno = 0; @@ -445,7 +445,7 @@ if (errno == ERANGE || (long)(t = n) != n) { errno = sverrno; return 0; -@@ -458,24 +508,37 @@ +@@ -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,10 +546,10 @@ +@@ -483,37 +591,40 @@ label: if (i < 0) return 0; @@ -501,43 +546,72 @@ ptr++; break; -@@ -502,7 +565,7 @@ - zonestr[cp - buf] = '\0'; - tzset(); - if (0 == strcmp(zonestr, "GMT")) { + case 'Z': + { + const char *cp; +- char *zonestr; ++ size_t tzlen, len; + + for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} +- if (cp - buf) { +- zonestr = alloca(cp - buf + 1); +- strncpy(zonestr, buf, cp - buf); +- zonestr[cp - buf] = '\0'; +- tzset(); +- if (0 == strcmp(zonestr, "GMT")) { - *GMTp = 1; -+ *convp = CONVERT_GMT; - } else if (0 == strcmp(zonestr, tzname[0])) { - tm->tm_isdst = 0; - } else if (0 == strcmp(zonestr, tzname[1])) { -@@ -514,6 +577,26 @@ +- } else if (0 == strcmp(zonestr, tzname[0])) { +- tm->tm_isdst = 0; +- } else if (0 == strcmp(zonestr, tzname[1])) { +- tm->tm_isdst = 1; +- } else { +- return 0; +- } +- buf += cp - buf; ++ len = cp - buf; ++ if (len == 3 && strncmp(buf, "GMT", 3) == 0) { ++ *convp = CONVERT_GMT; ++ buf += len; ++ break; } ++ tzset(); ++ tzlen = strlen(tzname[0]); ++ if (len == tzlen && strncmp(buf, tzname[0], tzlen) == 0) { ++ tm->tm_isdst = 0; ++ buf += len; ++ break; ++ } ++ tzlen = strlen(tzname[1]); ++ if (len == tzlen && strncmp(buf, tzname[1], tzlen) == 0) { ++ tm->tm_isdst = 1; ++ buf += len; ++ break; ++ } ++ return 0; + } +- 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; -+ -+ 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; } - } - return (char *)buf; -@@ -524,14 +607,39 @@ +@@ -552,14 +663,39 @@ char * strptime(const char * __restrict buf, const char * __restrict fmt, struct tm * __restrict tm) {