diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2021-11-12 13:24:20 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2021-11-12 14:06:11 +0000 |
commit | 629081baf655c2ffc6df7b03073045b023ec8b36 (patch) | |
tree | bd1bb4ddb082dafb8fd4a8068f603189f7ed35c6 | |
parent | dc1c84c776588472d9b3759051a24e378035596c (diff) | |
download | libgweather-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.c | 32 |
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. |