From 14909ffe1e31e22f6a2c74724a5f812acb2d6f25 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Fri, 14 Feb 2025 21:05:47 -0300 Subject: [PATCH] gio/subprocess: Initialize pid variable to 0 The documentation for g_spawn_async_with_pipes_and_fds() states: > If an error occurs, child_pid, stdin_pipe_out, stdout_pipe_out, and > stderr_pipe_out will not be filled with valid values. Before 2dc3a6f0c80e5a8f786369eee0c45bfe19b55f4f, the `child_pid` argument was `self->pid`, and GObject zero-initializes structs. So the pid field was properly initialized to zero. After 2dc3a6f0c80e5a8f786369eee0c45bfe19b55f4f, however, the out variable is now declared inside initable_init(), and it's unitialized. So if g_spawn_async_with_pipes_and_fds() errors out, `pid` will have trash value in it, and the following assertion will fail: ``` g_assert (success == (pid != 0)); ``` Fix that by initializing the `pid` variable to zero. Add a test to exercise the fail code path, and prevent errors like this in the future. --- gio/gsubprocess.c | 2 +- gio/tests/gsubprocess.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c index 1972fd2c0..2cdd53dca 100644 --- a/gio/gsubprocess.c +++ b/gio/gsubprocess.c @@ -305,7 +305,7 @@ initable_init (GInitable *initable, gint *pipe_ptrs[3] = { NULL, NULL, NULL }; gint pipe_fds[3] = { -1, -1, -1 }; gint close_fds[3] = { -1, -1, -1 }; - GPid pid; + GPid pid = 0; #ifdef G_OS_UNIX gint stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; #endif diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c index 2ba28d693..cdda4e052 100644 --- a/gio/tests/gsubprocess.c +++ b/gio/tests/gsubprocess.c @@ -1352,6 +1352,22 @@ test_terminate (void) g_object_unref (proc); } +static void +test_fail_initialization (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocess *proc; + + proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, + error, + "thisprogramshouldnotexistprettyplease", + NULL); + + g_assert_null (proc); + g_assert_error (local_error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT); +} + #ifdef G_OS_UNIX static void send_signal (gpointer user_data) @@ -2244,6 +2260,7 @@ main (int argc, char **argv) g_test_add_func ("/gsubprocess/communicate/utf8/invalid", test_communicate_utf8_invalid); g_test_add_func ("/gsubprocess/communicate/nothing", test_communicate_nothing); g_test_add_func ("/gsubprocess/terminate", test_terminate); + g_test_add_func ("/gsubprocess/fail-initialization", test_fail_initialization); g_test_add_func ("/gsubprocess/env", test_env); g_test_add_func ("/gsubprocess/env/inherit", test_env_inherit); g_test_add_func ("/gsubprocess/cwd", test_cwd);