summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2021-11-12 13:24:20 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2021-11-12 14:06:11 +0000
commit629081baf655c2ffc6df7b03073045b023ec8b36 (patch)
treebd1bb4ddb082dafb8fd4a8068f603189f7ed35c6
parentdc1c84c776588472d9b3759051a24e378035596c (diff)
downloadlibgweather-629081baf655c2ffc6df7b03073045b023ec8b36.tar.gz
Avoid a potential NULL dereference
When asynchronously querying for the nearest location at the given location we should keep a reference on the parent location, in case it goes away mid-search. This is especially important when passing `NULL` as the parent location: the current code uses a `g_autoptr()` to store the "world" node, and then passes the pointer unmodified; if that happened, the location would be released at the end of the function, and the asynchronously invoked callback would get a garbage pointer.
-rw-r--r--libgweather/gweather-location.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/libgweather/gweather-location.c b/libgweather/gweather-location.c
index e064fc7..a5cfe40 100644
--- a/libgweather/gweather-location.c
+++ b/libgweather/gweather-location.c
@@ -789,13 +789,18 @@ _got_place (GObject *source_object,
foreach_city (info->location, (GFunc) find_nearest_city, &data, country_code, NULL, NULL);
+ gweather_location_unref (info->location);
g_slice_free (ArgData, info);
if (data.location == NULL) {
g_task_return_pointer (task, NULL, NULL);
} else {
- GWeatherLocation *location;
- location = _gweather_location_new_detached (data.location, geocode_place_get_town (place), TRUE, data.latitude, data.longitude);
+ GWeatherLocation *location =
+ _gweather_location_new_detached (data.location,
+ geocode_place_get_town (place),
+ TRUE,
+ data.latitude,
+ data.longitude);
g_task_return_pointer (task, location, (GDestroyNotify) gweather_location_unref);
}
@@ -805,18 +810,19 @@ _got_place (GObject *source_object,
/**
* gweather_location_detect_nearest_city:
- * @loc: (allow-none): The parent location, which will be searched recursively
+ * @loc: (nullable): the parent location, which will be searched recursively
* @lat: Latitude, in degrees
* @lon: Longitude, in degrees
- * @cancellable: optional, NULL to ignore
- * @callback: callback function for GAsyncReadyCallback argument for GAsyncResult
+ * @cancellable: (nullable): a cancellable instance
+ * @callback: callback function
* @user_data: user data passed to @callback
*
- * Initializes geocode reversing to find place for (@lat, @lon) coordinates. Calls the callback
- * function passed by user when the result is ready.
+ * Initializes geocode reversing to find place for (@lat, @lon) coordinates.
*
- * @loc must be at most a %GWEATHER_LOCATION_ADM1 location.
- * This restriction may be lifted in a future version.
+ * Calls the callback function passed by user when the result is ready.
+ *
+ * The given location must be at most a %GWEATHER_LOCATION_ADM1 location; this
+ * restriction may be lifted in a future version.
*/
void
gweather_location_detect_nearest_city (GWeatherLocation *loc,
@@ -836,7 +842,7 @@ gweather_location_detect_nearest_city (GWeatherLocation *loc,
loc->level == GWEATHER_LOCATION_NAMED_TIMEZONE);
if (loc == NULL)
- loc = world = gweather_location_get_world ();
+ world = gweather_location_get_world ();
location = geocode_location_new (lat, lon, GEOCODE_LOCATION_ACCURACY_CITY);
reverse = geocode_reverse_new_for_location (location);
@@ -846,7 +852,9 @@ gweather_location_detect_nearest_city (GWeatherLocation *loc,
data = g_slice_new0 (ArgData);
data->latitude = lat;
data->longitude = lon;
- data->location = loc;
+ data->location = loc != NULL
+ ? gweather_location_ref (loc)
+ : g_steal_pointer (&world);
data->task = task;
geocode_reverse_resolve_async (reverse, cancellable, _got_place, data);
@@ -854,7 +862,7 @@ gweather_location_detect_nearest_city (GWeatherLocation *loc,
/**
* gweather_location_detect_nearest_location_finish:
- * @result:
+ * @result:
* @error: Stores error if any occurs in retrieving the result
*
* Fetches the location from @result.