1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

- Introducing Jamie Lokier's function for date to epoch conversion used in the

date parser function. This makes our function less dependent on system-
  provided functions and instead we do all the magic ourselves. We also no
  longer depend on the TZ environment variable.
This commit is contained in:
Daniel Stenberg 2008-09-23 11:00:01 +00:00
parent a5f4cfc612
commit d369a2b775
4 changed files with 62 additions and 34 deletions

19
CHANGES
View File

@ -7,6 +7,25 @@
Changelog
Daniel Stenberg (23 Sep 2008)
- Introducing Jamie Lokier's function for date to epoch conversion used in the
date parser function. This makes our function less dependent on system-
provided functions and instead we do all the magic ourselves. We also no
longer depend on the TZ environment variable. Switching to our own converter
has some side-effect and they are noted here for future reference (taken
from a mail by mr Lokier):
time_t is not measured in seconds in the ANSI C standard - or even counted
uniformly - weird platforms can use other numeric representations of dates
in time_t - hence the difftime() function.
On POSIX time_t is measured in UTC seconds, which means not including leap
seconds. But it's mentioned in a few places that some old POSIX-ish
environments include leap seconds in their time_t counts...
I'm pretty sure [the new implementation is] correct on anything truly POSIX.
And it's obviously a lot less dependent on platform quirks and corner cases
in many ways than the mktime() version.
- Rob Crittenden brought a patch to "add some locking for thread-safety to NSS
implementation".

View File

@ -26,6 +26,7 @@ This release includes the following bugfixes:
o recv() failures cause CURLE_RECV_ERROR
o SFTP over SOCKS crash fixed
o thread-safety issues addressed for NSS-powered libcurls
o removed the use of mktime() and gmtime(_r)() in date parsing and conversions
This release includes the following known bugs:
@ -40,6 +41,7 @@ advice from friends like these:
Keith Mok, Yang Tse, Daniel Fandrich, Guenter Knauf, Dmitriy Sergeyev,
Linus Nielsen Feltzing, Martin Drasar, Stefan Krause, Dmitry Kurochkin,
Mike Revi, Andres Garcia, Michael Goffioul, Markus Moeller, Rob Crittenden
Mike Revi, Andres Garcia, Michael Goffioul, Markus Moeller, Rob Crittenden,
Jamie Lokier
Thanks! (and sorry if I forgot to mention someone)

View File

@ -222,6 +222,38 @@ enum assume {
DATE_TIME
};
/* struct tm to time since epoch in GMT time zone */
static time_t my_timegm(struct tm * tm)
{
int month_days_cumulative [12] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
int month, year, leap_days;
if(tm->tm_year < 70)
/* we don't support years before 1970 as they will cause this function
to return a negative value */
return -1;
year = tm->tm_year + 1900;
month = tm->tm_mon;
if (month < 0) {
year += (11 - month) / 12;
month = 11 - (11 - month) % 12;
}
else if (month >= 12) {
year -= month / 12;
month = month % 12;
}
leap_days = year - (tm->tm_mon <= 1);
leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
- (1969 / 4) + (1969 / 100) - (1969 / 400));
return ((((time_t) (year - 1970) * 365
+ leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24
+ tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
}
static time_t parsedate(const char *date)
{
time_t t = 0;
@ -247,7 +279,8 @@ static time_t parsedate(const char *date)
/* a name coming up */
char buf[32]="";
size_t len;
sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]", buf);
sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]",
buf);
len = strlen(buf);
if(wdaynum == -1) {
@ -374,45 +407,20 @@ static time_t parsedate(const char *date)
tm.tm_yday = 0;
tm.tm_isdst = 0;
/* mktime() returns a time_t. time_t is often 32 bits, even on many
/* my_timegm() returns a time_t. time_t is often 32 bits, even on many
architectures that feature 64 bit 'long'.
Some systems have 64 bit time_t and deal with years beyond 2038. However,
even some of the systems with 64 bit time_t returns -1 for dates beyond
03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
even on some of the systems with 64 bit time_t mktime() returns -1 for
dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
*/
t = mktime(&tm);
t = my_timegm(&tm);
/* time zone adjust (cast t to int to compare to negative one) */
if(-1 != (int)t) {
struct tm *gmt;
long delta;
time_t t2;
#ifdef HAVE_GMTIME_R
/* thread-safe version */
struct tm keeptime2;
gmt = (struct tm *)gmtime_r(&t, &keeptime2);
if(!gmt)
return -1; /* illegal date/time */
t2 = mktime(gmt);
#else
/* It seems that at least the MSVC version of mktime() doesn't work
properly if it gets the 'gmt' pointer passed in (which is a pointer
returned from gmtime() pointing to static memory), so instead we copy
the tm struct to a local struct and pass a pointer to that struct as
input to mktime(). */
struct tm gmt2;
gmt = gmtime(&t); /* use gmtime_r() if available */
if(!gmt)
return -1; /* illegal date/time */
gmt2 = *gmt;
t2 = mktime(&gmt2);
#endif
/* Add the time zone diff (between the given timezone and GMT) and the
diff between the local time zone and GMT. */
delta = (long)((tzoff!=-1?tzoff:0) + (t - t2));
/* Add the time zone diff between local time zone and GMT. */
long delta = (long)(tzoff!=-1?tzoff:0);
if((delta>0) && (t + delta < t))
return -1; /* time_t overflow */

View File

@ -21,7 +21,6 @@ curl_getdate() testing
# using one of the 'right' zones that take into account leap seconds
# which causes the cookie expiry times to be different.
<setenv>
TZ=GMT
</setenv>
<command>
nothing