gkdbus: Fix underflow and unreachable code bug
[platform/upstream/glib.git] / gio / tests / appinfo.c
1
2 #include <locale.h>
3 #include <string.h>
4
5 #include <glib/gstdio.h>
6 #include <gio/gio.h>
7 #include <gio/gdesktopappinfo.h>
8
9 static void
10 test_launch_for_app_info (GAppInfo *appinfo)
11 {
12   GError *error = NULL;
13   gboolean success;
14   GFile *file;
15   GList *l;
16   const gchar *path;
17   gchar *uri;
18
19   success = g_app_info_launch (appinfo, NULL, NULL, &error);
20   g_assert_no_error (error);
21   g_assert_true (success);
22
23   success = g_app_info_launch_uris (appinfo, NULL, NULL, &error);
24   g_assert_no_error (error);
25   g_assert_true (success);
26
27   path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
28   file = g_file_new_for_path (path);
29   l = NULL;
30   l = g_list_append (l, file);
31
32   success = g_app_info_launch (appinfo, l, NULL, &error);
33   g_assert_no_error (error);
34   g_assert_true (success);
35   g_list_free (l);
36   g_object_unref (file);
37
38   l = NULL;
39   uri = g_strconcat ("file://", g_test_get_dir (G_TEST_BUILT), "/appinfo-test.desktop", NULL);
40   l = g_list_append (l, uri);
41   l = g_list_append (l, "file:///etc/group#adm");
42
43   success = g_app_info_launch_uris (appinfo, l, NULL, &error);
44   g_assert_no_error (error);
45   g_assert_true (success);
46
47   g_list_free (l);
48   g_free (uri);
49 }
50
51 static void
52 test_launch (void)
53 {
54   GAppInfo *appinfo;
55   const gchar *path;
56
57   path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
58   appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
59   g_assert_true (G_IS_APP_INFO (appinfo));
60
61   test_launch_for_app_info (appinfo);
62   g_object_unref (appinfo);
63 }
64
65 static void
66 test_launch_no_app_id (void)
67 {
68   const gchar desktop_file_base_contents[] =
69     "[Desktop Entry]\n"
70     "Type=Application\n"
71     "GenericName=generic-appinfo-test\n"
72     "Name=appinfo-test\n"
73     "Name[de]=appinfo-test-de\n"
74     "X-GNOME-FullName=example\n"
75     "X-GNOME-FullName[de]=Beispiel\n"
76     "Comment=GAppInfo example\n"
77     "Comment[de]=GAppInfo Beispiel\n"
78     "Icon=testicon.svg\n"
79     "Terminal=false\n"
80     "StartupNotify=true\n"
81     "StartupWMClass=appinfo-class\n"
82     "MimeType=image/png;image/jpeg;\n"
83     "Keywords=keyword1;test keyword;\n"
84     "Categories=GNOME;GTK;\n";
85
86   gchar *exec_line_variants[2];
87   gsize i;
88
89   exec_line_variants[0] = g_strdup_printf (
90       "Exec=%s/appinfo-test --option %%U %%i --name %%c --filename %%k %%m %%%%",
91       g_test_get_dir (G_TEST_BUILT));
92   exec_line_variants[1] = g_strdup_printf (
93       "Exec=%s/appinfo-test --option %%u %%i --name %%c --filename %%k %%m %%%%",
94       g_test_get_dir (G_TEST_BUILT));
95
96   g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=791337");
97
98   for (i = 0; i < G_N_ELEMENTS (exec_line_variants); i++)
99     {
100       gchar *desktop_file_contents;
101       GKeyFile *fake_desktop_file;
102       GAppInfo *appinfo;
103       gboolean loaded;
104
105       g_test_message ("Exec line variant #%" G_GSIZE_FORMAT, i);
106
107       desktop_file_contents = g_strdup_printf ("%s\n%s",
108                                                desktop_file_base_contents,
109                                                exec_line_variants[i]);
110
111       /* We load a desktop file from memory to force the app not
112        * to have an app ID, which would check different codepaths.
113        */
114       fake_desktop_file = g_key_file_new ();
115       loaded = g_key_file_load_from_data (fake_desktop_file, desktop_file_contents, -1, G_KEY_FILE_NONE, NULL);
116       g_assert_true (loaded);
117
118       appinfo = (GAppInfo*)g_desktop_app_info_new_from_keyfile (fake_desktop_file);
119       g_assert_nonnull (appinfo);
120
121       test_launch_for_app_info (appinfo);
122
123       g_free (desktop_file_contents);
124       g_object_unref (appinfo);
125       g_key_file_unref (fake_desktop_file);
126     }
127
128   g_free (exec_line_variants[1]);
129   g_free (exec_line_variants[0]);
130 }
131
132 static void
133 test_locale (const char *locale)
134 {
135   GAppInfo *appinfo;
136   gchar *orig = NULL;
137   const gchar *path;
138
139   orig = g_strdup (setlocale (LC_ALL, NULL));
140   g_setenv ("LANGUAGE", locale, TRUE);
141   setlocale (LC_ALL, "");
142
143   path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
144   appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
145
146   if (g_strcmp0 (locale, "C") == 0)
147     {
148       g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test");
149       g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example");
150       g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example");
151     }
152   else if (g_str_has_prefix (locale, "en"))
153     {
154       g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test");
155       g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example");
156       g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example");
157     }
158   else if (g_str_has_prefix (locale, "de"))
159     {
160       g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test-de");
161       g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo Beispiel");
162       g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "Beispiel");
163     }
164
165   g_object_unref (appinfo);
166
167   g_setenv ("LANGUAGE", orig, TRUE);
168   setlocale (LC_ALL, "");
169   g_free (orig);
170 }
171
172 static void
173 test_text (void)
174 {
175   test_locale ("C");
176   test_locale ("en_US");
177   test_locale ("de");
178   test_locale ("de_DE.UTF-8");
179 }
180
181 static void
182 test_basic (void)
183 {
184   GAppInfo *appinfo;
185   GAppInfo *appinfo2;
186   GIcon *icon, *icon2;
187   const gchar *path;
188
189   path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
190   appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
191   g_assert_nonnull (appinfo);
192
193   g_assert_cmpstr (g_app_info_get_id (appinfo), ==, "appinfo-test-static.desktop");
194   g_assert_nonnull (strstr (g_app_info_get_executable (appinfo), "true"));
195
196   icon = g_app_info_get_icon (appinfo);
197   g_assert_true (G_IS_THEMED_ICON (icon));
198   icon2 = g_themed_icon_new ("testicon");
199   g_assert_true (g_icon_equal (icon, icon2));
200   g_object_unref (icon2);
201
202   appinfo2 = g_app_info_dup (appinfo);
203   g_assert_cmpstr (g_app_info_get_id (appinfo), ==, g_app_info_get_id (appinfo2));
204   g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
205
206   g_object_unref (appinfo);
207   g_object_unref (appinfo2);
208 }
209
210 static void
211 test_show_in (void)
212 {
213   GAppInfo *appinfo;
214   const gchar *path;
215
216   path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
217   appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
218   g_assert_true (G_IS_APP_INFO (appinfo));
219
220   g_assert_true (g_app_info_should_show (appinfo));
221   g_object_unref (appinfo);
222
223   path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-gnome.desktop", NULL);
224   appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
225   g_assert_true (g_app_info_should_show (appinfo));
226   g_object_unref (appinfo);
227
228   path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-notgnome.desktop", NULL);
229   appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
230   g_assert_false (g_app_info_should_show (appinfo));
231   g_object_unref (appinfo);
232 }
233
234 static void
235 test_commandline (void)
236 {
237   GAppInfo *appinfo;
238   GError *error;
239   gchar *cmdline;
240   gchar *cmdline_out;
241
242   cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
243   cmdline_out = g_strconcat (cmdline, " %u", NULL);
244
245   error = NULL;
246   appinfo = g_app_info_create_from_commandline (cmdline,
247                                                 "cmdline-app-test",
248                                                 G_APP_INFO_CREATE_SUPPORTS_URIS,
249                                                 &error);
250   g_assert_no_error (error);
251   g_assert_nonnull (appinfo);
252   g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test");
253   g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out);
254   g_assert_true (g_app_info_supports_uris (appinfo));
255   g_assert_false (g_app_info_supports_files (appinfo));
256
257   g_object_unref (appinfo);
258
259   g_free (cmdline_out);
260   cmdline_out = g_strconcat (cmdline, " %f", NULL);
261
262   error = NULL;
263   appinfo = g_app_info_create_from_commandline (cmdline,
264                                                 "cmdline-app-test",
265                                                 G_APP_INFO_CREATE_NONE,
266                                                 &error);
267   g_assert_no_error (error);
268   g_assert_nonnull (appinfo);
269   g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test");
270   g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out);
271   g_assert_false (g_app_info_supports_uris (appinfo));
272   g_assert_true (g_app_info_supports_files (appinfo));
273
274   g_object_unref (appinfo);
275
276   g_free (cmdline);
277   g_free (cmdline_out);
278 }
279
280 static void
281 test_launch_context (void)
282 {
283   GAppLaunchContext *context;
284   GAppInfo *appinfo;
285   gchar *str;
286   gchar *cmdline;
287
288   cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
289
290   context = g_app_launch_context_new ();
291   appinfo = g_app_info_create_from_commandline (cmdline,
292                                                 "cmdline-app-test",
293                                                 G_APP_INFO_CREATE_SUPPORTS_URIS,
294                                                 NULL);
295
296   str = g_app_launch_context_get_display (context, appinfo, NULL);
297   g_assert_null (str);
298
299   str = g_app_launch_context_get_startup_notify_id (context, appinfo, NULL);
300   g_assert_null (str);
301
302   g_object_unref (appinfo);
303   g_object_unref (context);
304
305   g_free (cmdline);
306 }
307
308 static gboolean launched_reached;
309
310 static void
311 launched (GAppLaunchContext *context,
312           GAppInfo          *info,
313           GVariant          *platform_data,
314           gpointer           user_data)
315 {
316   gint pid;
317
318   pid = 0;
319   g_assert_true (g_variant_lookup (platform_data, "pid", "i", &pid));
320   g_assert_cmpint (pid, !=, 0);
321
322   launched_reached = TRUE;
323 }
324
325 static void
326 launch_failed (GAppLaunchContext *context,
327                const gchar       *startup_notify_id)
328 {
329   g_assert_not_reached ();
330 }
331
332 static void
333 test_launch_context_signals (void)
334 {
335   GAppLaunchContext *context;
336   GAppInfo *appinfo;
337   GError *error = NULL;
338   gboolean success;
339   gchar *cmdline;
340
341   cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
342
343   context = g_app_launch_context_new ();
344   g_signal_connect (context, "launched", G_CALLBACK (launched), NULL);
345   g_signal_connect (context, "launch_failed", G_CALLBACK (launch_failed), NULL);
346   appinfo = g_app_info_create_from_commandline (cmdline,
347                                                 "cmdline-app-test",
348                                                 G_APP_INFO_CREATE_SUPPORTS_URIS,
349                                                 NULL);
350
351   success = g_app_info_launch (appinfo, NULL, context, &error);
352   g_assert_no_error (error);
353   g_assert_true (success);
354
355   g_assert_true (launched_reached);
356
357   g_object_unref (appinfo);
358   g_object_unref (context);
359
360   g_free (cmdline);
361 }
362
363 static void
364 test_tryexec (void)
365 {
366   GAppInfo *appinfo;
367   const gchar *path;
368
369   path = g_test_get_filename (G_TEST_BUILT, "appinfo-test2.desktop", NULL);
370   appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
371
372   g_assert_null (appinfo);
373 }
374
375 /* Test that we can set an appinfo as default for a mime type or
376  * file extension, and also add and remove handled mime types.
377  */
378 static void
379 test_associations (void)
380 {
381   GAppInfo *appinfo;
382   GAppInfo *appinfo2;
383   GError *error = NULL;
384   gboolean result;
385   GList *list;
386   gchar *cmdline;
387
388   cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
389   appinfo = g_app_info_create_from_commandline (cmdline,
390                                                 "cmdline-app-test",
391                                                 G_APP_INFO_CREATE_SUPPORTS_URIS,
392                                                 NULL);
393   g_free (cmdline);
394
395   result = g_app_info_set_as_default_for_type (appinfo, "application/x-glib-test", &error);
396   g_assert_no_error (error);
397   g_assert_true (result);
398
399   appinfo2 = g_app_info_get_default_for_type ("application/x-glib-test", FALSE);
400
401   g_assert_nonnull (appinfo2);
402   g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
403
404   g_object_unref (appinfo2);
405
406   result = g_app_info_set_as_default_for_extension (appinfo, "gio-tests", &error);
407   g_assert_no_error (error);
408   g_assert_true (result);
409
410   appinfo2 = g_app_info_get_default_for_type ("application/x-extension-gio-tests", FALSE);
411
412   g_assert_nonnull (appinfo2);
413   g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
414
415   g_object_unref (appinfo2);
416
417   result = g_app_info_add_supports_type (appinfo, "application/x-gio-test", &error);
418   g_assert_no_error (error);
419   g_assert_true (result);
420
421   list = g_app_info_get_all_for_type ("application/x-gio-test");
422   g_assert_cmpint (g_list_length (list), ==, 1);
423   appinfo2 = list->data;
424   g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
425   g_object_unref (appinfo2);
426   g_list_free (list);
427
428   g_assert_true (g_app_info_can_remove_supports_type (appinfo));
429   result = g_app_info_remove_supports_type (appinfo, "application/x-gio-test", &error);
430   g_assert_no_error (error);
431   g_assert_true (result);
432
433   g_assert_true (g_app_info_can_delete (appinfo));
434   g_assert_true (g_app_info_delete (appinfo));
435   g_object_unref (appinfo);
436 }
437
438 static void
439 test_environment (void)
440 {
441   GAppLaunchContext *ctx;
442   gchar **env;
443   const gchar *path;
444
445   g_unsetenv ("FOO");
446   g_unsetenv ("BLA");
447   path = g_getenv ("PATH");
448
449   ctx = g_app_launch_context_new ();
450
451   env = g_app_launch_context_get_environment (ctx);
452
453   g_assert_null (g_environ_getenv (env, "FOO"));
454   g_assert_null (g_environ_getenv (env, "BLA"));
455   g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path);
456
457   g_strfreev (env);
458
459   g_app_launch_context_setenv (ctx, "FOO", "bar");
460   g_app_launch_context_setenv (ctx, "BLA", "bla");
461
462   env = g_app_launch_context_get_environment (ctx);
463
464   g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "bar");
465   g_assert_cmpstr (g_environ_getenv (env, "BLA"), ==, "bla");
466   g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path);
467
468   g_strfreev (env);
469
470   g_app_launch_context_setenv (ctx, "FOO", "baz");
471   g_app_launch_context_unsetenv (ctx, "BLA");
472
473   env = g_app_launch_context_get_environment (ctx);
474
475   g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "baz");
476   g_assert_null (g_environ_getenv (env, "BLA"));
477
478   g_strfreev (env);
479
480   g_object_unref (ctx);
481 }
482
483 static void
484 test_startup_wm_class (void)
485 {
486   GDesktopAppInfo *appinfo;
487   const char *wm_class;
488   const gchar *path;
489
490   path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
491   appinfo = g_desktop_app_info_new_from_filename (path);
492   wm_class = g_desktop_app_info_get_startup_wm_class (appinfo);
493
494   g_assert_cmpstr (wm_class, ==, "appinfo-class");
495
496   g_object_unref (appinfo);
497 }
498
499 static void
500 test_supported_types (void)
501 {
502   GAppInfo *appinfo;
503   const char * const *content_types;
504   const gchar *path;
505
506   path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
507   appinfo = G_APP_INFO (g_desktop_app_info_new_from_filename (path));
508   content_types = g_app_info_get_supported_types (appinfo);
509
510   g_assert_cmpint (g_strv_length ((char**)content_types), ==, 2);
511   g_assert_cmpstr (content_types[0], ==, "image/png");
512
513   g_object_unref (appinfo);
514 }
515
516 static void
517 test_from_keyfile (void)
518 {
519   GDesktopAppInfo *info;
520   GKeyFile *kf;
521   GError *error = NULL;
522   const gchar *categories;
523   gchar **categories_list;
524   gsize categories_count;
525   gchar **keywords;
526   const gchar *file;
527   const gchar *name;
528   const gchar *path;
529
530   path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
531   kf = g_key_file_new ();
532   g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, &error);
533   g_assert_no_error (error);
534   info = g_desktop_app_info_new_from_keyfile (kf);
535   g_key_file_unref (kf);
536   g_assert_nonnull (info);
537
538   g_object_get (info, "filename", &file, NULL);
539   g_assert_null (file);
540
541   file = g_desktop_app_info_get_filename (info);
542   g_assert_null (file);
543   categories = g_desktop_app_info_get_categories (info);
544   g_assert_cmpstr (categories, ==, "GNOME;GTK;");
545   categories_list = g_desktop_app_info_get_string_list (info, "Categories", &categories_count);
546   g_assert_cmpint (categories_count, ==, 2);
547   g_assert_cmpint (g_strv_length (categories_list), ==, 2);
548   g_assert_cmpstr (categories_list[0], ==, "GNOME");
549   g_assert_cmpstr (categories_list[1], ==, "GTK");
550   keywords = (gchar **)g_desktop_app_info_get_keywords (info);
551   g_assert_cmpint (g_strv_length (keywords), ==, 2);
552   g_assert_cmpstr (keywords[0], ==, "keyword1");
553   g_assert_cmpstr (keywords[1], ==, "test keyword");
554   name = g_desktop_app_info_get_generic_name (info);
555   g_assert_cmpstr (name, ==, "generic-appinfo-test");
556   g_assert_false (g_desktop_app_info_get_nodisplay (info));
557
558   g_strfreev (categories_list);
559   g_object_unref (info);
560 }
561
562 int
563 main (int argc, char *argv[])
564 {
565   g_setenv ("XDG_CURRENT_DESKTOP", "GNOME", TRUE);
566
567   g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
568
569   g_test_add_func ("/appinfo/basic", test_basic);
570   g_test_add_func ("/appinfo/text", test_text);
571   g_test_add_func ("/appinfo/launch", test_launch);
572   g_test_add_func ("/appinfo/launch/no-appid", test_launch_no_app_id);
573   g_test_add_func ("/appinfo/show-in", test_show_in);
574   g_test_add_func ("/appinfo/commandline", test_commandline);
575   g_test_add_func ("/appinfo/launch-context", test_launch_context);
576   g_test_add_func ("/appinfo/launch-context-signals", test_launch_context_signals);
577   g_test_add_func ("/appinfo/tryexec", test_tryexec);
578   g_test_add_func ("/appinfo/associations", test_associations);
579   g_test_add_func ("/appinfo/environment", test_environment);
580   g_test_add_func ("/appinfo/startup-wm-class", test_startup_wm_class);
581   g_test_add_func ("/appinfo/supported-types", test_supported_types);
582   g_test_add_func ("/appinfo/from-keyfile", test_from_keyfile);
583
584   return g_test_run ();
585 }