Merge lp:~dshea/timezonemap/memory-problems into lp:timezonemap

Proposed by David Shea
Status: Needs review
Proposed branch: lp:~dshea/timezonemap/memory-problems
Merge into: lp:timezonemap
Diff against target: 155 lines (+47/-20)
3 files modified
debian/control (+2/-2)
src/cc-timezone-map.c (+35/-4)
src/tz.c (+10/-14)
To merge this branch: bzr merge lp:~dshea/timezonemap/memory-problems
Reviewer Review Type Date Requested Status
Timezone Map Team Pending
Review via email: mp+295635@code.launchpad.net

Description of the change

This fixes a memory leak and an access of freed memory, and works around a call to setenv which is not thread-safe. tz_location_set_locally could probably be removed but it's kind of part of the public interface so I didn't want to mess with that.

To post a comment you must log in.
62. By David Shea

Fix the calculation of time zone offsets.

g_get_real_time returns microseconds, not milliseconds.

Unmerged revisions

62. By David Shea

Fix the calculation of time zone offsets.

g_get_real_time returns microseconds, not milliseconds.

61. By David Shea

Do not use tz_location_get_utc_offset

The function in tz.c to fetch the timezone offset for a given location
sets the TZ environment variable which, besides being potentially
surprising to the rest of the process, is not thread-safe. Instead,
skip the function entirely and use the glib functions for querying time
zone data.

Increase the required glib version to 2.26 for the GTimeZone functions.

60. By David Shea

Fix an invalid memory access

When truncating the list for the distance-based location search, do not
attempt to read the rest of the list after it has been freed.

59. By David Shea

Fix memory leaks in tz.c

Use a stack-allocated block for the user_data struct passed to
parse_cities15000, since the struct itself is not needed after
parse_file, and no one can forget to free it if it's not dynamically
allocated the first place.

Use const strings in tz_data_file_get so that the return value does not
need to be duplicated and freed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2015-05-07 13:47:16 +0000
+++ debian/control 2016-06-28 17:25:08 +0000
@@ -9,7 +9,7 @@
9 gir1.2-glib-2.0,9 gir1.2-glib-2.0,
10 gir1.2-gtk-3.0,10 gir1.2-gtk-3.0,
11 intltool (>= 0.35.0),11 intltool (>= 0.35.0),
12 libglib2.0-dev (>= 2.25.0),12 libglib2.0-dev (>= 2.26.0),
13 libgtk-3-dev (>= 3.1.4),13 libgtk-3-dev (>= 3.1.4),
14 libcairo2-dev (>= 1.10),14 libcairo2-dev (>= 1.10),
15 libjson-glib-dev,15 libjson-glib-dev,
@@ -57,7 +57,7 @@
57Depends: ${shlibs:Depends}, 57Depends: ${shlibs:Depends},
58 ${misc:Depends},58 ${misc:Depends},
59 libtimezonemap1 (= ${binary:Version}),59 libtimezonemap1 (= ${binary:Version}),
60 libglib2.0-dev (>= 2.25.0),60 libglib2.0-dev (>= 2.26.0),
61 libgtk-3-dev (>= 3.1.4),61 libgtk-3-dev (>= 3.1.4),
62 libjson-glib-dev62 libjson-glib-dev
63Replaces: gir1.2-timezonemap-1.0 (<< 0.3)63Replaces: gir1.2-timezonemap-1.0 (<< 0.3)
6464
=== modified file 'src/cc-timezone-map.c'
--- src/cc-timezone-map.c 2015-05-07 16:43:32 +0000
+++ src/cc-timezone-map.c 2016-06-28 17:25:08 +0000
@@ -843,6 +843,39 @@
843 return 0;843 return 0;
844}844}
845845
846/* Return the UTC offset (in hours) for the standard (winter) time at a location */
847static gdouble
848get_location_offset (CcTimezoneLocation *location)
849{
850 const gchar *zone_name;
851 GTimeZone *zone;
852 gint interval;
853 gint64 curtime;
854 gint32 offset;
855
856 g_return_val_if_fail (location != NULL, 0);
857 zone_name = cc_timezone_location_get_zone (location);
858 g_return_val_if_fail (zone_name != NULL, 0);
859
860 zone = g_time_zone_new (zone_name);
861
862 /* Query the zone based on the current time, since otherwise the data
863 * may not make sense. */
864 curtime = g_get_real_time () / 1000000; /* convert to seconds */
865 interval = g_time_zone_find_interval (zone, G_TIME_TYPE_UNIVERSAL, curtime);
866
867 offset = g_time_zone_get_offset (zone, interval);
868 if (g_time_zone_is_dst (zone, interval))
869 {
870 /* Subtract an hour's worth of seconds to get the standard time offset */
871 offset -= (60 * 60);
872 }
873
874 g_time_zone_unref (zone);
875
876 return offset / (60.0 * 60.0);
877}
878
846static void879static void
847set_location (CcTimezoneMap *map,880set_location (CcTimezoneMap *map,
848 CcTimezoneLocation *location)881 CcTimezoneLocation *location)
@@ -854,11 +887,8 @@
854887
855 if (priv->location)888 if (priv->location)
856 {889 {
857 info = tz_info_from_location (priv->location);890 priv->selected_offset = get_location_offset (priv->location);
858 priv->selected_offset = tz_location_get_utc_offset (priv->location)
859 / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
860 priv->show_offset = TRUE;891 priv->show_offset = TRUE;
861 tz_info_free (info);
862 }892 }
863 else893 else
864 {894 {
@@ -940,6 +970,7 @@
940 /* Cut the list off here */970 /* Cut the list off here */
941 node->prev->next = NULL;971 node->prev->next = NULL;
942 g_list_free(node);972 g_list_free(node);
973 break;
943 }974 }
944975
945 node = g_list_next(node);976 node = g_list_next(node);
946977
=== modified file 'src/tz.c'
--- src/tz.c 2013-12-16 17:01:37 +0000
+++ src/tz.c 2016-06-28 17:25:08 +0000
@@ -41,7 +41,7 @@
41#endif41#endif
42static int compare_country_names (const void *a, const void *b);42static int compare_country_names (const void *a, const void *b);
43static void sort_locations_by_country (GPtrArray *locations);43static void sort_locations_by_country (GPtrArray *locations);
44static gchar * tz_data_file_get (gchar *env, gchar *defaultfile);44static const gchar * tz_data_file_get (const gchar *env, const gchar *defaultfile);
4545
46void parse_file (const char * filename,46void parse_file (const char * filename,
47 const guint ncolumns,47 const guint ncolumns,
@@ -179,7 +179,7 @@
179TzDB *179TzDB *
180tz_load_db (void)180tz_load_db (void)
181{181{
182 gchar *tz_data_file, *admin1_file, *country_file;182 const gchar *tz_data_file, *admin1_file, *country_file;
183 TzDB *tz_db;183 TzDB *tz_db;
184 char buf[4096];184 char buf[4096];
185185
@@ -217,23 +217,19 @@
217 tz_db = g_new0 (TzDB, 1);217 tz_db = g_new0 (TzDB, 1);
218 tz_db->locations = g_ptr_array_new ();218 tz_db->locations = g_ptr_array_new ();
219219
220 Triple * triple = g_new (Triple, 1);220 Triple triple;
221 triple->first = tz_db->locations;221 triple.first = tz_db->locations;
222 triple->second = stateHash;222 triple.second = stateHash;
223 triple->third = countryHash;223 triple.third = countryHash;
224224
225 parse_file (tz_data_file, 19, parse_cities15000, triple);225 parse_file (tz_data_file, 19, parse_cities15000, &triple);
226226
227 g_hash_table_destroy (stateHash);227 g_hash_table_destroy (stateHash);
228 g_hash_table_destroy (countryHash);228 g_hash_table_destroy (countryHash);
229 triple->second = NULL;
230 triple->third = NULL;
231229
232 /* now sort by country */230 /* now sort by country */
233 sort_locations_by_country (tz_db->locations);231 sort_locations_by_country (tz_db->locations);
234232
235 g_free (tz_data_file);
236
237 return tz_db;233 return tz_db;
238}234}
239235
@@ -391,14 +387,14 @@
391 * Private functions *387 * Private functions *
392 * ----------------- */388 * ----------------- */
393389
394static gchar *390static const gchar *
395tz_data_file_get (gchar *env, gchar *defaultfile)391tz_data_file_get (const gchar *env, const gchar *defaultfile)
396{392{
397 /* Allow passing this in at runtime, to support loading it from the build393 /* Allow passing this in at runtime, to support loading it from the build
398 * tree during tests. */394 * tree during tests. */
399 const gchar * filename = g_getenv (env);395 const gchar * filename = g_getenv (env);
400396
401 return filename ? g_strdup (filename) : g_strdup (defaultfile);397 return filename ? filename : defaultfile;
402}398}
403399
404#ifdef __sun400#ifdef __sun

Subscribers

People subscribed via source and target branches

to all changes: