From e41e3dc60115e81e0e78a6150dabbef1638e72ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Mon, 31 Oct 2022 16:56:23 +0100 Subject: [PATCH] gdesktopappinfo: Take in account the desktop Path to find executables Desktop files can provide the executable working path and that can be used to pick the file to launch. So take it in account. --- gio/gdesktopappinfo.c | 15 +++++-- gio/tests/appinfo-test-path.desktop.in | 22 ++++++++++ gio/tests/desktop-app-info.c | 60 ++++++++++++++++++++++++++ gio/tests/meson.build | 1 + 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 gio/tests/appinfo-test-path.desktop.in diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index 990b2b736..697c7b9d1 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -56,6 +56,7 @@ #include "gappinfo.h" #include "gappinfoprivate.h" #include "glocalfilemonitor.h" +#include "gutilsprivate.h" #ifdef G_OS_UNIX #include "gdocumentportal.h" @@ -1830,6 +1831,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, char *type; char *try_exec; char *exec; + char *path; gboolean bus_activatable; start_group = g_key_file_get_start_group (key_file); @@ -1851,6 +1853,10 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, } g_free (type); + path = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_PATH, NULL); + try_exec = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, @@ -1858,9 +1864,10 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, if (try_exec && try_exec[0] != '\0') { char *t; - t = g_find_program_in_path (try_exec); + t = g_find_program_for_path (try_exec, NULL, path); if (t == NULL) { + g_free (path); g_free (try_exec); return FALSE; } @@ -1877,6 +1884,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, char **argv; if (!g_shell_parse_argv (exec, &argc, &argv, NULL)) { + g_free (path); g_free (exec); g_free (try_exec); return FALSE; @@ -1888,11 +1896,12 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, /* Since @exec is not an empty string, there must be at least one * argument, so dereferencing argv[0] should return non-NULL. */ g_assert (argc > 0); - t = g_find_program_in_path (argv[0]); + t = g_find_program_for_path (argv[0], NULL, path); g_strfreev (argv); if (t == NULL) { + g_free (path); g_free (exec); g_free (try_exec); return FALSE; @@ -1912,7 +1921,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, info->not_show_in = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL, NULL); info->try_exec = try_exec; info->exec = exec; - info->path = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_PATH, NULL); + info->path = g_steal_pointer (&path); info->terminal = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL) != FALSE; info->startup_notify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, NULL) != FALSE; info->no_fuse = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GIO-NoFuse", NULL) != FALSE; diff --git a/gio/tests/appinfo-test-path.desktop.in b/gio/tests/appinfo-test-path.desktop.in new file mode 100644 index 000000000..39ab12fed --- /dev/null +++ b/gio/tests/appinfo-test-path.desktop.in @@ -0,0 +1,22 @@ +[Desktop Entry] +Type=Application +GenericName=generic-appinfo-test-path +Name=appinfo-test-path +Name[de]=appinfo-test-de +X-GNOME-FullName=example +X-GNOME-FullName[de]=Beispiel +Comment=GAppInfo example +Comment[de]=GAppInfo Beispiel +Path=@installed_tests_dir@ +TryExec=apps +Exec=appinfo-test --option %U %i --name %c --filename %k %m %% +Icon=testicon.svg +Terminal=false +StartupNotify=true +StartupWMClass=appinfo-path-class +MimeType=image/png;image/jpeg; +Keywords=keyword1;test keyword; +Categories=GNOME;GTK; +X-JunkFood=Burger +X-JunkFood[de]=Bratwurst +X-JunkFood[it]= diff --git a/gio/tests/desktop-app-info.c b/gio/tests/desktop-app-info.c index 33eb3985b..0839eb0a2 100644 --- a/gio/tests/desktop-app-info.c +++ b/gio/tests/desktop-app-info.c @@ -1578,6 +1578,64 @@ test_launch_uris_with_invalid_terminal (void) g_free (old_path); } +static void +test_app_path (void) +{ + GDesktopAppInfo *appinfo; + const char *desktop_path; + + desktop_path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-path.desktop", NULL); + appinfo = g_desktop_app_info_new_from_filename (desktop_path); + + g_assert_true (G_IS_DESKTOP_APP_INFO (appinfo)); + + g_clear_object (&appinfo); +} + +static void +test_app_path_wrong (void) +{ + GKeyFile *key_file; + GDesktopAppInfo *appinfo; + const gchar bad_try_exec_file_contents[] = + "[Desktop Entry]\n" + "Type=Application\n" + "Name=appinfo-test\n" + "TryExec=appinfo-test\n" + "Path=this-must-not-exist‼\n" + "Exec=true\n"; + const gchar bad_exec_file_contents[] = + "[Desktop Entry]\n" + "Type=Application\n" + "Name=appinfo-test\n" + "TryExec=true\n" + "Path=this-must-not-exist‼\n" + "Exec=appinfo-test\n"; + + g_assert_true ( + g_file_test (g_test_get_filename (G_TEST_BUILT, "appinfo-test", NULL), + G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)); + + key_file = g_key_file_new (); + + g_assert_true ( + g_key_file_load_from_data (key_file, bad_try_exec_file_contents, -1, + G_KEY_FILE_NONE, NULL)); + + appinfo = g_desktop_app_info_new_from_keyfile (key_file); + g_assert_false (G_IS_DESKTOP_APP_INFO (appinfo)); + + g_assert_true ( + g_key_file_load_from_data (key_file, bad_exec_file_contents, -1, + G_KEY_FILE_NONE, NULL)); + + appinfo = g_desktop_app_info_new_from_keyfile (key_file); + g_assert_false (G_IS_DESKTOP_APP_INFO (appinfo)); + + g_clear_pointer (&key_file, g_key_file_unref); + g_clear_object (&appinfo); +} + int main (int argc, char *argv[]) @@ -1615,6 +1673,8 @@ main (int argc, g_test_add_func ("/desktop-app-info/search", test_search); g_test_add_func ("/desktop-app-info/implements", test_implements); g_test_add_func ("/desktop-app-info/show-in", test_show_in); + g_test_add_func ("/desktop-app-info/app-path", test_app_path); + g_test_add_func ("/desktop-app-info/app-path/wrong", test_app_path_wrong); g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager); g_test_add_func ("/desktop-app-info/launch-as-manager/fail", test_launch_as_manager_fail); g_test_add_func ("/desktop-app-info/launch-default-uri-handler", test_default_uri_handler); diff --git a/gio/tests/meson.build b/gio/tests/meson.build index 11acad460..ea685da0f 100644 --- a/gio/tests/meson.build +++ b/gio/tests/meson.build @@ -628,6 +628,7 @@ endif appinfo_test_desktop_files = [ 'appinfo-test-gnome', 'appinfo-test-notgnome', + 'appinfo-test-path', 'appinfo-test', 'appinfo-test2', ]