[gupnp/gupnp-1.4] ServiceProxy: Fix double-free on ProxyAction
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp/gupnp-1.4] ServiceProxy: Fix double-free on ProxyAction
- Date: Sat, 8 Jan 2022 09:20:32 +0000 (UTC)
commit 774d996767b2085966b3eb98fb6e07dc178d37e3
Author: Jens Georg <mail jensge org>
Date: Sat Jan 8 09:21:10 2022 +0100
ServiceProxy: Fix double-free on ProxyAction
If call_finish() is not called, do not unref the action since it is
bound to the task's lifetime anyway
libgupnp/gupnp-service-proxy.c | 2 +-
tests/test-bugs.c | 82 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 78 insertions(+), 6 deletions(-)
---
diff --git a/libgupnp/gupnp-service-proxy.c b/libgupnp/gupnp-service-proxy.c
index 5e78ebf..bcf9439 100644
--- a/libgupnp/gupnp-service-proxy.c
+++ b/libgupnp/gupnp-service-proxy.c
@@ -775,7 +775,7 @@ action_task_got_response (SoupSession *session,
g_task_return_pointer (task,
g_task_get_task_data (task),
- (GDestroyNotify) gupnp_service_proxy_action_unref);
+ NULL);
g_object_unref (task);
diff --git a/tests/test-bugs.c b/tests/test-bugs.c
index df1a29e..24cf1fc 100644
--- a/tests/test-bugs.c
+++ b/tests/test-bugs.c
@@ -173,11 +173,19 @@ test_on_timeout (G_GNUC_UNUSED gpointer user_data)
static void
test_run_loop (GMainLoop *loop)
{
- guint timeout_id = 0;
-
- timeout_id = g_timeout_add_seconds (2, test_on_timeout, NULL);
- g_main_loop_run (loop);
- g_source_remove (timeout_id);
+ guint timeout_id = 0;
+ int timeout = 2;
+
+ const char *timeout_str = g_getenv ("GUPNP_TEST_TIMEOUT");
+ if (timeout_str != NULL) {
+ long t = atol (timeout_str);
+ if (t != 0)
+ timeout = t;
+ }
+
+ timeout_id = g_timeout_add_seconds (timeout, test_on_timeout, NULL);
+ g_main_loop_run (loop);
+ g_source_remove (timeout_id);
}
/* Test if a call on a service proxy keeps argument order */
@@ -837,6 +845,69 @@ test_ggo_63 ()
g_main_loop_unref (d.loop);
}
+void
+test_ggo_60_call_ready (GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ g_main_loop_quit ((GMainLoop *) user_data);
+}
+
+void
+test_ggo_60_no_crash ()
+{
+ // Test that there is no crash if not calling call_finish() on call_async()
+ GUPnPContext *context = NULL;
+ GError *error = NULL;
+ GUPnPControlPoint *cp = NULL;
+ GUPnPRootDevice *rd;
+ TestServiceProxyData data = { .proxy = NULL,
+ .loop = g_main_loop_new (NULL, FALSE) };
+
+ context = create_context (0, &error);
+ g_assert_no_error (error);
+ g_assert (context != NULL);
+
+ cp = gupnp_control_point_new (
+ context,
+ "urn:test-gupnp-org:service:TestService:1");
+
+ gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
+
+ g_signal_connect (G_OBJECT (cp),
+ "service-proxy-available",
+ G_CALLBACK (test_on_sp_available),
+ &data);
+
+
+ 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);
+ test_run_loop (data.loop);
+ g_assert (data.proxy != NULL);
+
+ // We just use the default of "Action not implemented" response, since
+ // it does not matter for the actual test
+
+ GUPnPServiceProxyAction *action =
+ gupnp_service_proxy_action_new ("Ping", NULL);
+ gupnp_service_proxy_call_action_async (data.proxy,
+ action,
+ NULL,
+ test_ggo_60_call_ready,
+ data.loop);
+
+ test_run_loop (data.loop);
+ gupnp_service_proxy_action_unref (action);
+ g_object_unref (data.proxy);
+ g_object_unref (rd);
+ g_object_unref (cp);
+ g_object_unref (context);
+ g_main_loop_unref (data.loop);
+}
+
int
main (int argc, char *argv[]) {
g_test_init (&argc, &argv, NULL);
@@ -849,6 +920,7 @@ main (int argc, char *argv[]) {
g_test_add_func ("/bugs/ggo/58", test_ggo_58);
g_test_add_func ("/bugs/ggo/42", test_ggo_42);
g_test_add_func ("/bugs/ggo/63", test_ggo_63);
+ g_test_add_func ("/bugs/ggo/60/no-crash", test_ggo_60_no_crash);
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]