mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-05 08:53:39 +02:00
gdesktopappinfo: Fail early if trying to launch an invalid executable
GDesktopAppInfo never failed in the most simple of the cases: when a desktop file or a command line app info was pointing to an invalid executable (for the context). The reason for this is that we're launching all the programs using gio-launch-desktop which will always exist in a sane GLib installation, and thus our call to execvp won't ever fail on failure. This was partially mitigated by not allowing to create a desktop app icon using a non-existent executable (even if not fully correctly) but still did not work in case a custom PATH was provided in the launch context. To avoid this, use g_find_program_for_path() to find early if a program that we're about to launch is available, and if it's not the case return the same error that g_spawn_async_with_fds() would throw in such cases. While this is slowing a bit our preparation phase, would avoid to leave to the exec function the job to find where our program is. Add tests simulating this behavior.
This commit is contained in:
@@ -2919,6 +2919,46 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
|
||||
emit_launch_started (launch_context, info, sn_id);
|
||||
}
|
||||
|
||||
g_assert (argc > 0);
|
||||
|
||||
if (!g_path_is_absolute (argv[0]) ||
|
||||
!g_file_test (argv[0], G_FILE_TEST_IS_EXECUTABLE) ||
|
||||
g_file_test (argv[0], G_FILE_TEST_IS_DIR))
|
||||
{
|
||||
char *program = g_steal_pointer (&argv[0]);
|
||||
char *program_path = NULL;
|
||||
|
||||
if (!g_path_is_absolute (program))
|
||||
{
|
||||
const char *env_path = g_environ_getenv (envp, "PATH");
|
||||
|
||||
program_path = g_find_program_for_path (program,
|
||||
env_path,
|
||||
info->path);
|
||||
}
|
||||
|
||||
if (program_path)
|
||||
{
|
||||
argv[0] = g_steal_pointer (&program_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sn_id)
|
||||
g_app_launch_context_launch_failed (launch_context, sn_id);
|
||||
|
||||
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT,
|
||||
_("Program ‘%s’ not found in $PATH"),
|
||||
program);
|
||||
|
||||
g_free (program);
|
||||
g_clear_pointer (&sn_id, g_free);
|
||||
g_clear_list (&launched_uris, NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_free (program);
|
||||
}
|
||||
|
||||
if (g_once_init_enter (&gio_launch_desktop_path))
|
||||
{
|
||||
const gchar *tmp = NULL;
|
||||
|
Reference in New Issue
Block a user