[libical] Add patch for RH bug #1176204 (Avoid putenv() in libical)

Milan Crha mcrha at fedoraproject.org
Mon Dec 22 11:41:15 UTC 2014


commit 20113692c2b6f2e8ced104fee79bd29a501b9718
Author: Milan Crha <mcrha at redhat.com>
Date:   Mon Dec 22 12:41:24 2014 +0100

    Add patch for RH bug #1176204 (Avoid putenv() in libical)

 libical-1.0-avoid-putenv.patch |  179 ++++++++++++++++++++++++++++++++++++++++
 libical.spec                   |    7 ++-
 2 files changed, 185 insertions(+), 1 deletions(-)
---
diff --git a/libical-1.0-avoid-putenv.patch b/libical-1.0-avoid-putenv.patch
new file mode 100644
index 0000000..ee4518b
--- /dev/null
+++ b/libical-1.0-avoid-putenv.patch
@@ -0,0 +1,179 @@
+diff -up libical-1.0/src/libical/icaltime.c.old libical-1.0/src/libical/icaltime.c
+--- libical-1.0/src/libical/icaltime.c.old	2014-11-26 13:29:50.809112801 +0100
++++ libical-1.0/src/libical/icaltime.c	2014-11-26 14:56:05.740893525 +0100
+@@ -64,11 +64,6 @@
+ #define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
+ #endif
+ 
+-#ifdef HAVE_PTHREAD
+- #include <pthread.h>    
+-    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;
+ 
+@@ -85,7 +80,7 @@ static time_t make_time(struct tm *tm, i
+ 
+   /* check that year specification within range */
+ 
+-  if (tm->tm_year < 70 || tm->tm_year > 138)
++  if (be_strict && sizeof (time_t) == 4 && (tm->tm_year < 70 || tm->tm_year > 138))
+     return((time_t) -1);
+ 
+   /* check that month specification within range */
+@@ -96,7 +91,7 @@ static time_t make_time(struct tm *tm, i
+   /* check for upper bound of Jan 17, 2038 (to avoid possibility of
+      32-bit arithmetic overflow) */
+   
+-  if (tm->tm_year == 138) {
++  if (be_strict && sizeof (time_t) == 4 && tm->tm_year == 138) {
+     if (tm->tm_mon > 0)
+       return((time_t) -1);
+     else if (tm->tm_mday > 17)
+@@ -289,99 +284,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.
+  *
+@@ -395,8 +303,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 ();
+@@ -424,25 +330,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)
diff --git a/libical.spec b/libical.spec
index 9f2c36f..1aa6702 100644
--- a/libical.spec
+++ b/libical.spec
@@ -1,12 +1,13 @@
 Summary:	Reference implementation of the iCalendar data type and serialization format
 Name:		libical
 Version:	1.0
-Release:	7%{?dist}
+Release:	8%{?dist}
 License:	LGPLv2 or MPLv1.1
 URL:		http://freeassociation.sourceforge.net/
 Source:		http://downloads.sourceforge.net/freeassociation/%{name}-%{version}.tar.gz
 Patch0:		libical-1.0-r1150.patch
 Patch1:		libical-1.0-r1156.patch
+Patch2:		libical-1.0-avoid-putenv.patch
 
 BuildRequires:	bison, byacc, flex
 BuildRequires:	cmake
@@ -28,6 +29,7 @@ applications that use libical.
 %setup -q
 %patch0 -p1 -b .r1150
 %patch1 -p1 -b .r1156
+%patch2 -p1 -b .avoid-putenv
 
 %build
 mkdir -p %{_target_platform}
@@ -63,6 +65,9 @@ rm -fv %{buildroot}%{_libdir}/lib*.a
 %{_includedir}/libical/
 
 %changelog
+* Mon Dec 22 2014 Milan Crha <mcrha at redhat.com> - 1.0-8
+- Add patch for RH bug #1176204 (Avoid putenv() in libical)
+
 * Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.0-7
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
 


More information about the scm-commits mailing list