diff -up libical-1.0.1/src/libical/icaltime.c.avoid-putenv libical-1.0.1/src/libical/icaltime.c --- libical-1.0.1/src/libical/icaltime.c.avoid-putenv 2014-10-09 17:07:05.000000000 +0200 +++ libical-1.0.1/src/libical/icaltime.c 2015-01-26 11:56:35.153309240 +0100 @@ -64,11 +64,6 @@ #define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0) #endif -#ifdef HAVE_PTHREAD - #include - static pthread_mutex_t tzid_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - /* * Function to convert a struct tm time specification * to an ANSI time_t using the specified time zone. @@ -77,7 +72,7 @@ * local daylight savings time applied to the result. * This function expects well-formed input. */ -static time_t make_time(struct tm *tm, int tzm) +static time_t make_time(struct tm *tm, int tzm, int be_strict) { time_t tim; @@ -91,13 +86,13 @@ static time_t make_time(struct tm *tm, i #if (SIZEOF_TIME_T == 4) /* check that year specification within range */ - if (tm->tm_year < 70 || tm->tm_year > 138) + if (be_strict && (tm->tm_year < 70 || tm->tm_year > 138)) return((time_t) -1); /* check for upper bound of Jan 17, 2038 (to avoid possibility of 32-bit arithmetic overflow) */ - if (tm->tm_year == 138) { + if (be_strict && tm->tm_year == 138) { if (tm->tm_mon > 0) return((time_t) -1); else if (tm->tm_mday > 17) @@ -291,99 +286,12 @@ time_t icaltime_as_timet(const struct ic stm.tm_year = tt.year-1900; stm.tm_isdst = -1; - t = make_time(&stm, 0); + t = make_time(&stm, 0, 1); return t; } - -/* Structure used by set_tz to hold an old value of TZ, and the new - value, which is in memory we will have to free in unset_tz */ -/* This will hold the last "TZ=XXX" string we used with putenv(). After we - call putenv() again to set a new TZ string, we can free the previous one. - As far as I know, no libc implementations actually free the memory used in - the environment variables (how could they know if it is a static string or - a malloc'ed string?), so we have to free it ourselves. */ -static char* saved_tz = NULL; - -/* If you use set_tz(), you must call unset_tz() some time later to restore the - original TZ. Pass unset_tz() the string that set_tz() returns. Call both the functions - locking the tzid mutex as in icaltime_as_timet_with_zone */ -char* set_tz(const char* tzid) -{ - char *old_tz, *old_tz_copy = NULL, *new_tz; - - /* Get the old TZ setting and save a copy of it to return. */ - old_tz = getenv("TZ"); - if(old_tz){ - old_tz_copy = (char*)malloc(strlen (old_tz) + 4); - - if(old_tz_copy == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return 0; - } - - strcpy (old_tz_copy, "TZ="); - strcpy (old_tz_copy + 3, old_tz); - } - - /* Create the new TZ string. */ - new_tz = (char*)malloc(strlen (tzid) + 4); - - if(new_tz == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - free(old_tz_copy); - return 0; - } - - strcpy (new_tz, "TZ="); - strcpy (new_tz + 3, tzid); - - /* Add the new TZ to the environment. */ - putenv(new_tz); - - /* Free any previous TZ environment string we have used in a synchronized manner. */ - - free (saved_tz); - - /* Save a pointer to the TZ string we just set, so we can free it later. */ - saved_tz = new_tz; - - return old_tz_copy; /* This will be zero if the TZ env var was not set */ -} - -void unset_tz(char *tzstr) -{ - /* restore the original environment */ - - if(tzstr!=0){ - putenv(tzstr); - } else { - /* Delete from environment. We prefer unsetenv(3) over putenv(3) - because the former is POSIX and behaves consistently. The later - does not unset the variable in some systems (like NetBSD), leaving - it with an empty value. This causes problems later because further - calls to time related functions in libc will treat times in UTC. */ -#ifdef HAVE_UNSETENV - unsetenv("TZ"); -#else -#ifdef _MSC_VER - putenv("TZ="); // The equals is required to remove with MS Visual C++ -#else - putenv("TZ"); -#endif -#endif - } - - /* Free any previous TZ environment string we have used in a synchronized manner */ - free (saved_tz); - - /* Save a pointer to the TZ string we just set, so we can free it later. - (This can possibly be NULL if there was no TZ to restore.) */ - saved_tz = tzstr; -} - /** Return the time as seconds past the UNIX epoch, using the * given timezone. * @@ -397,8 +305,6 @@ time_t icaltime_as_timet_with_zone(const { icaltimezone *utc_zone; struct tm stm; - time_t t; - char *old_tz; struct icaltimetype local_tt; utc_zone = icaltimezone_get_utc_timezone (); @@ -426,25 +332,8 @@ time_t icaltime_as_timet_with_zone(const stm.tm_mon = local_tt.month-1; stm.tm_year = local_tt.year-1900; stm.tm_isdst = -1; -/* The functions putenv and mktime are not thread safe, inserting a lock -to prevent any crashes */ -#ifdef HAVE_PTHREAD - pthread_mutex_lock (&tzid_mutex); -#endif - - /* Set TZ to UTC and use mktime to convert to a time_t. */ - old_tz = set_tz ("UTC"); - tzset (); - - t = mktime (&stm); - unset_tz (old_tz); - tzset (); - -#ifdef HAVE_PTHREAD - pthread_mutex_unlock (&tzid_mutex); -#endif - return t; + return make_time (&stm, 0, 0); } const char* icaltime_as_ical_string(const struct icaltimetype tt)