diff options
author | Jens Georg <mail@jensge.org> | 2022-11-07 15:41:08 +0100 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2022-11-07 15:41:08 +0100 |
commit | c87d858815a1e45dcb51c796be89b19f2a52ac3f (patch) | |
tree | c88c8e7aea19f1999aed76d8f872d27f40b98420 | |
parent | c961f9d7208c2b857a09c3aa13bd53711b2b08d5 (diff) | |
download | gupnp-c87d858815a1e45dcb51c796be89b19f2a52ac3f.tar.gz |
service: Initialize GError properly
Trying to propagate an error over some unintialized error causes a
warning and, more importantly, an invalid free
Fixes #80
-rw-r--r-- | libgupnp/gupnp-service.c | 2 | ||||
-rw-r--r-- | tests/test-service.c | 80 |
2 files changed, 81 insertions, 1 deletions
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", "<http://127.0.0.1:1312>"); + + 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 (); } |