[libgweather/wip/hadess/serialisation-fix: 1/17] GWeatherLocation: Fix double-free with "nearest stations"
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgweather/wip/hadess/serialisation-fix: 1/17] GWeatherLocation: Fix double-free with "nearest stations"
- Date: Wed, 10 Oct 2018 12:52:24 +0000 (UTC)
commit b2a1468accc3ead062eb4c0c48deaa5a5ab792c7
Author: Bastien Nocera <hadess hadess net>
Date: Tue Oct 9 14:39:08 2018 +0200
GWeatherLocation: Fix double-free with "nearest stations"
The nearest station code would try to (badly) copy the nearest station's
location to add it as a child, but the copy was shallow, and the string
pointers, and other allocated memory wasn't duplicated, leading to
double-frees and invalid memory accesses if the world was unref'ed.
This also fixes the newly created GWeatherLocation to use g_slice_* to
allocate the memory chunk, otherwise we'll have memory corruption when
we try to free it with g_slice_free() in the unref() code.
libgweather/gweather-location.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
---
diff --git a/libgweather/gweather-location.c b/libgweather/gweather-location.c
index d122e0e..976b8b9 100644
--- a/libgweather/gweather-location.c
+++ b/libgweather/gweather-location.c
@@ -136,12 +136,15 @@ location_new (GWeatherLocationLevel level)
return loc;
}
+static void add_timezones (GWeatherLocation *loc, GPtrArray *zones);
+
static void
add_nearest_weather_station (GWeatherLocation *location)
{
- GWeatherLocation **siblings;
+ GWeatherLocation **siblings, *station;
GWeatherLocation *closest = NULL;
double min_distance = G_MAXDOUBLE;
+ GPtrArray *zones;
guint i;
g_assert (location->parent);
@@ -172,7 +175,30 @@ add_nearest_weather_station (GWeatherLocation *location)
}
location->children = g_new0 (GWeatherLocation *, 2);
- location->children[0] = g_memdup (closest, sizeof(GWeatherLocation));
+ location->children[0] = g_slice_new0 (GWeatherLocation);
+ station = location->children[0];
+ station->english_name = g_strdup (closest->english_name);
+ station->local_name = g_strdup (closest->local_name);
+ station->msgctxt = g_strdup (closest->msgctxt);
+ station->local_sort_name = g_strdup (closest->local_sort_name);
+ station->english_sort_name = g_strdup (closest->english_sort_name);
+ station->parent = location;
+ station->level = closest->level;
+ station->country_code = g_strdup (closest->country_code);
+ station->tz_hint = g_strdup (closest->tz_hint);
+ station->station_code = g_strdup (closest->station_code);
+ station->forecast_zone = g_strdup (closest->forecast_zone);
+ station->radar = g_strdup (closest->radar);
+ station->latitude = closest->latitude;
+ station->longitude = closest->longitude;
+ station->latlon_valid = closest->latlon_valid;
+
+ zones = g_ptr_array_new ();
+ add_timezones (station, zones);
+ g_ptr_array_add (zones, NULL);
+ station->zones = (GWeatherTimezone **)g_ptr_array_free (zones, FALSE);
+
+ station->ref_count = 1;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]