From c87d858815a1e45dcb51c796be89b19f2a52ac3f Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Mon, 7 Nov 2022 15:41:08 +0100 Subject: service: Initialize GError properly Trying to propagate an error over some unintialized error causes a warning and, more importantly, an invalid free Fixes #80 --- libgupnp/gupnp-service.c | 2 +- tests/test-service.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/libgupnp/gupnp-service.c b/libgupnp/gupnp-service.c index 4620909..4c491ee 100644 --- a/libgupnp/gupnp-service.c +++ b/libgupnp/gupnp-service.c @@ -1428,7 +1428,7 @@ notify_got_response (GObject *source, GAsyncResult *res, gpointer user_data) g_bytes_ref (data->property_set)); } else { /* Emit 'notify-failed' signal */ - GError *inner_error; + GError *inner_error = NULL; // We have an error, so just propagate that if (error != NULL) { diff --git a/tests/test-service.c b/tests/test-service.c index b63a903..859d25a 100644 --- a/tests/test-service.c +++ b/tests/test-service.c @@ -162,6 +162,83 @@ test_service_notification_cancelled () g_clear_object (&context); g_main_loop_unref (data.loop); } + +static void +on_notify_failed (GUPnPService *service, + GList *callbacks, + GError *error, + gpointer user_data) +{ + TestServiceNotificationCancelledData *data = user_data; + + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED); + g_main_loop_quit (data->loop); +} + +static void +test_service_notification_remote_disappears (void) +{ + // Check that the notification message is cancelled correctly if the service is + // Shut down during sending + GUPnPContext *context = NULL; + GError *error = NULL; + GUPnPRootDevice *rd; + GUPnPServiceInfo *info = NULL; + + TestServiceNotificationCancelledData data = { NULL, NULL }; + + data.loop = g_main_loop_new (NULL, FALSE); + + context = create_context (0, &error); + g_assert_no_error (error); + g_assert (context != NULL); + + rd = gupnp_root_device_new (context, + "TestDevice.xml", + DATA_PATH, + &error); + g_assert_no_error (error); + g_assert (rd != NULL); + gupnp_root_device_set_available (rd, TRUE); + + // Generate SUBSCRIBE message + info = gupnp_device_info_get_service ( + GUPNP_DEVICE_INFO (rd), + "urn:test-gupnp-org:service:TestService:1"); + char *url = gupnp_service_info_get_event_subscription_url (info); + + g_signal_connect (info, + "notify-failed", + G_CALLBACK (on_notify_failed), + &data); + + SoupMessage *msg = soup_message_new ("SUBSCRIBE", url); + + SoupMessageHeaders *h = soup_message_get_request_headers (msg); + soup_message_headers_append (h, "Callback", ""); + + soup_message_headers_append (h, "NT", "upnp:event"); + + SoupSession *session = soup_session_new (); + // FIXME: Add timeout header + soup_session_send_and_read_async (session, + msg, + G_PRIORITY_DEFAULT, + NULL, + NULL, + &data); + + g_main_loop_run (data.loop); + + g_clear_object (&info); + + g_clear_object (&rd); + g_clear_object (&msg); + g_clear_object (&session); + g_clear_object (&context); + g_main_loop_unref (data.loop); +} + int main (int argc, char *argv[]) { @@ -170,5 +247,8 @@ main (int argc, char *argv[]) g_test_add_func ("/service/notify/cancel", test_service_notification_cancelled); + g_test_add_func ("/service/notify/handle-remote-disappering", + test_service_notification_remote_disappears); + return g_test_run (); } -- cgit v1.2.1