gkdbus: Fix underflow and unreachable code bug
[platform/upstream/glib.git] / gio / tests / contenttype.c
1 #include <gio/gio.h>
2 #include <string.h>
3
4 #define g_assert_content_type_equals(s1, s2)                    \
5   do {                                                          \
6     const char *__s1 = (s1), *__s2 = (s2);                      \
7     if (g_content_type_equals (__s1, __s2)) ;                   \
8     else                                                        \
9       g_assertion_message_cmpstr (G_LOG_DOMAIN,                 \
10                                   __FILE__, __LINE__,           \
11                                   G_STRFUNC,                    \
12                                   #s1 " == " #s2,               \
13                                   __s1, " == ", __s2);          \
14   } while (0)
15
16 static void
17 test_guess (void)
18 {
19   gchar *res;
20   gchar *expected;
21   gchar *existing_directory;
22   gboolean uncertain;
23   guchar data[] =
24     "[Desktop Entry]\n"
25     "Type=Application\n"
26     "Name=appinfo-test\n"
27     "Exec=./appinfo-test --option\n";
28
29 #ifdef G_OS_WIN32
30   existing_directory = (gchar *) g_getenv ("SYSTEMROOT");
31
32   if (existing_directory)
33     existing_directory = g_strdup_printf ("%s" G_DIR_SEPARATOR_S, existing_directory);
34 #else
35   existing_directory = g_strdup ("/etc/");
36 #endif
37
38   res = g_content_type_guess (existing_directory, NULL, 0, &uncertain);
39   g_free (existing_directory);
40   expected = g_content_type_from_mime_type ("inode/directory");
41   g_assert_content_type_equals (expected, res);
42   g_assert_true (uncertain);
43   g_free (res);
44   g_free (expected);
45
46   res = g_content_type_guess ("foo.txt", NULL, 0, &uncertain);
47   expected = g_content_type_from_mime_type ("text/plain");
48   g_assert_content_type_equals (expected, res);
49   g_free (res);
50   g_free (expected);
51
52   res = g_content_type_guess ("foo.txt", data, sizeof (data) - 1, &uncertain);
53   expected = g_content_type_from_mime_type ("text/plain");
54   g_assert_content_type_equals (expected, res);
55   g_assert_false (uncertain);
56   g_free (res);
57   g_free (expected);
58
59   /* Sadly win32 & OSX just don't have as large and robust of a mime type database as Linux */
60 #ifndef G_OS_WIN32
61 #ifndef __APPLE__
62   res = g_content_type_guess ("foo", data, sizeof (data) - 1, &uncertain);
63   expected = g_content_type_from_mime_type ("text/plain");
64   g_assert_content_type_equals (expected, res);
65   g_assert_false (uncertain);
66   g_free (res);
67   g_free (expected);
68
69   res = g_content_type_guess ("foo.desktop", data, sizeof (data) - 1, &uncertain);
70   expected = g_content_type_from_mime_type ("application/x-desktop");
71   g_assert_content_type_equals (expected, res);
72   g_assert_false (uncertain);
73   g_free (res);
74   g_free (expected);
75
76   res = g_content_type_guess (NULL, data, sizeof (data) - 1, &uncertain);
77   expected = g_content_type_from_mime_type ("application/x-desktop");
78   g_assert_content_type_equals (expected, res);
79   g_assert_false (uncertain);
80   g_free (res);
81   g_free (expected);
82
83   /* this is potentially ambiguous: it does not match the PO template format,
84    * but looks like text so it can't be Powerpoint */
85   res = g_content_type_guess ("test.pot", (guchar *)"ABC abc", 7, &uncertain);
86   expected = g_content_type_from_mime_type ("text/x-gettext-translation-template");
87   g_assert_content_type_equals (expected, res);
88   g_assert_false (uncertain);
89   g_free (res);
90   g_free (expected);
91
92   res = g_content_type_guess ("test.pot", (guchar *)"msgid \"", 7, &uncertain);
93   expected = g_content_type_from_mime_type ("text/x-gettext-translation-template");
94   g_assert_content_type_equals (expected, res);
95   g_assert_false (uncertain);
96   g_free (res);
97   g_free (expected);
98
99   res = g_content_type_guess ("test.pot", (guchar *)"\xCF\xD0\xE0\x11", 4, &uncertain);
100   expected = g_content_type_from_mime_type ("application/vnd.ms-powerpoint");
101   g_assert_content_type_equals (expected, res);
102   /* we cannot reliably detect binary powerpoint files as long as there is no
103    * defined MIME magic, so do not check uncertain here
104    */
105   g_free (res);
106   g_free (expected);
107
108   res = g_content_type_guess ("test.otf", (guchar *)"OTTO", 4, &uncertain);
109   expected = g_content_type_from_mime_type ("application/x-font-otf");
110   g_assert_content_type_equals (expected, res);
111   g_assert_false (uncertain);
112   g_free (res);
113   g_free (expected);
114 #endif /* __APPLE__ */
115
116   res = g_content_type_guess (NULL, (guchar *)"%!PS-Adobe-2.0 EPSF-1.2", 23, &uncertain);
117   expected = g_content_type_from_mime_type ("image/x-eps");
118   g_assert_content_type_equals (expected, res);
119   g_assert_false (uncertain);
120   g_free (res);
121   g_free (expected);
122
123   /* The data below would be detected as a valid content type, but shouldn’t be read at all. */
124   res = g_content_type_guess (NULL, (guchar *)"%!PS-Adobe-2.0 EPSF-1.2", 0, &uncertain);
125   expected = g_content_type_from_mime_type ("application/x-zerosize");
126   g_assert_content_type_equals (expected, res);
127   g_assert_false (uncertain);
128   g_free (res);
129   g_free (expected);
130 #endif /* G_OS_WIN32 */
131 }
132
133 static void
134 test_unknown (void)
135 {
136   gchar *unknown;
137   gchar *str;
138
139   unknown = g_content_type_from_mime_type ("application/octet-stream");
140   g_assert_true (g_content_type_is_unknown (unknown));
141   str = g_content_type_get_mime_type (unknown);
142   g_assert_cmpstr (str, ==, "application/octet-stream");
143   g_free (str);
144   g_free (unknown);
145 }
146
147 static void
148 test_subtype (void)
149 {
150   gchar *plain;
151   gchar *xml;
152
153   plain = g_content_type_from_mime_type ("text/plain");
154   xml = g_content_type_from_mime_type ("application/xml");
155
156   g_assert_true (g_content_type_is_a (xml, plain));
157   g_assert_true (g_content_type_is_mime_type (xml, "text/plain"));
158
159   g_free (plain);
160   g_free (xml);
161 }
162
163 static gint
164 find_mime (gconstpointer a, gconstpointer b)
165 {
166   if (g_content_type_equals (a, b))
167     return 0;
168   return 1;
169 }
170
171 static void
172 test_list (void)
173 {
174   GList *types;
175   gchar *plain;
176   gchar *xml;
177
178 #ifdef __APPLE__
179   g_test_skip ("The OSX backend does not implement g_content_types_get_registered()");
180   return;
181 #endif
182
183   plain = g_content_type_from_mime_type ("text/plain");
184   xml = g_content_type_from_mime_type ("application/xml");
185
186   types = g_content_types_get_registered ();
187
188   g_assert_cmpuint (g_list_length (types), >, 1);
189
190   /* just check that some types are in the list */
191   g_assert_nonnull (g_list_find_custom (types, plain, find_mime));
192   g_assert_nonnull (g_list_find_custom (types, xml, find_mime));
193
194   g_list_free_full (types, g_free);
195
196   g_free (plain);
197   g_free (xml);
198 }
199
200 static void
201 test_executable (void)
202 {
203   gchar *type;
204
205 #ifdef G_OS_WIN32
206   type = g_content_type_from_mime_type ("application/vnd.microsoft.portable-executable");
207   /* FIXME: the MIME is not in the default `MIME\Database\Content Type` registry.
208    * g_assert_true (g_content_type_can_be_executable (type));
209    */
210   g_free (type);
211 #else
212   type = g_content_type_from_mime_type ("application/x-executable");
213   g_assert_true (g_content_type_can_be_executable (type));
214   g_free (type);
215
216   type = g_content_type_from_mime_type ("text/plain");
217   g_assert_true (g_content_type_can_be_executable (type));
218   g_free (type);
219 #endif
220   type = g_content_type_from_mime_type ("image/png");
221   g_assert_false (g_content_type_can_be_executable (type));
222   g_free (type);
223 }
224
225 static void
226 test_description (void)
227 {
228   gchar *type;
229   gchar *desc;
230
231   type = g_content_type_from_mime_type ("text/plain");
232   desc = g_content_type_get_description (type);
233   g_assert_nonnull (desc);
234
235   g_free (desc);
236   g_free (type);
237 }
238
239 static void
240 test_icon (void)
241 {
242   gchar *type;
243   GIcon *icon;
244
245   type = g_content_type_from_mime_type ("text/plain");
246   icon = g_content_type_get_icon (type);
247   g_assert_true (G_IS_ICON (icon));
248   if (G_IS_THEMED_ICON (icon))
249     {
250       const gchar *const *names;
251
252       names = g_themed_icon_get_names (G_THEMED_ICON (icon));
253 #ifdef __APPLE__
254       g_assert_true (g_strv_contains (names, "text-*"));
255 #elif defined(G_OS_WIN32)
256       g_assert_cmpuint (g_strv_length ((GStrv) names), >, 0);
257 #else
258       g_assert_true (g_strv_contains (names, "text-plain"));
259       g_assert_true (g_strv_contains (names, "text-x-generic"));
260 #endif
261     }
262   g_object_unref (icon);
263   g_free (type);
264
265   type = g_content_type_from_mime_type ("application/rtf");
266   icon = g_content_type_get_icon (type);
267   g_assert_true (G_IS_ICON (icon));
268   if (G_IS_THEMED_ICON (icon))
269     {
270       const gchar *const *names;
271
272       names = g_themed_icon_get_names (G_THEMED_ICON (icon));
273 #ifdef G_OS_WIN32
274       g_assert_true (g_strv_contains (names, "text-x-generic"));
275 #else
276       g_assert_true (g_strv_contains (names, "application-rtf"));
277 #ifndef __APPLE__
278       g_assert_true (g_strv_contains (names, "x-office-document"));
279 #endif
280 #endif
281     }
282   g_object_unref (icon);
283   g_free (type);
284 }
285
286 static void
287 test_symbolic_icon (void)
288 {
289 #ifndef G_OS_WIN32
290   gchar *type;
291   GIcon *icon;
292
293   type = g_content_type_from_mime_type ("text/plain");
294   icon = g_content_type_get_symbolic_icon (type);
295   g_assert_true (G_IS_ICON (icon));
296   if (G_IS_THEMED_ICON (icon))
297     {
298       const gchar *const *names;
299
300       names = g_themed_icon_get_names (G_THEMED_ICON (icon));
301 #ifdef __APPLE__
302       g_assert_true (g_strv_contains (names, "text-*-symbolic"));
303       g_assert_true (g_strv_contains (names, "text-*"));
304 #else
305       g_assert_true (g_strv_contains (names, "text-plain-symbolic"));
306       g_assert_true (g_strv_contains (names, "text-x-generic-symbolic"));
307       g_assert_true (g_strv_contains (names, "text-plain"));
308       g_assert_true (g_strv_contains (names, "text-x-generic"));
309 #endif
310     }
311   g_object_unref (icon);
312   g_free (type);
313
314   type = g_content_type_from_mime_type ("application/rtf");
315   icon = g_content_type_get_symbolic_icon (type);
316   g_assert_true (G_IS_ICON (icon));
317   if (G_IS_THEMED_ICON (icon))
318     {
319       const gchar *const *names;
320
321       names = g_themed_icon_get_names (G_THEMED_ICON (icon));
322       g_assert_true (g_strv_contains (names, "application-rtf-symbolic"));
323       g_assert_true (g_strv_contains (names, "application-rtf"));
324 #ifndef __APPLE__
325       g_assert_true (g_strv_contains (names, "x-office-document-symbolic"));
326       g_assert_true (g_strv_contains (names, "x-office-document"));
327 #endif
328     }
329   g_object_unref (icon);
330   g_free (type);
331 #endif
332 }
333
334 static void
335 test_tree (void)
336 {
337   const gchar *tests[] = {
338     "x-content/image-dcf",
339     "x-content/unix-software",
340     "x-content/win32-software"
341   };
342   const gchar *path;
343   GFile *file;
344   gchar **types;
345   gsize i;
346
347 #if defined(__APPLE__) || defined(G_OS_WIN32)
348   g_test_skip ("The OSX & Windows backends do not implement g_content_type_guess_for_tree()");
349   return;
350 #endif
351
352   for (i = 0; i < G_N_ELEMENTS (tests); i++)
353     {
354       path = g_test_get_filename (G_TEST_DIST, tests[i], NULL);
355       file = g_file_new_for_path (path);
356       types = g_content_type_guess_for_tree (file);
357       g_assert_content_type_equals (types[0], tests[i]);
358       g_strfreev (types);
359       g_object_unref (file);
360    }
361 }
362
363 static void
364 test_type_is_a_special_case (void)
365 {
366   gboolean res;
367
368   g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=782311");
369
370   /* Everything but the inode type is application/octet-stream */
371   res = g_content_type_is_a ("inode/directory", "application/octet-stream");
372   g_assert_false (res);
373 #if !defined(__APPLE__) && !defined(G_OS_WIN32)
374   res = g_content_type_is_a ("anything", "application/octet-stream");
375   g_assert_true (res);
376 #endif
377 }
378
379 static void
380 test_guess_svg_from_data (void)
381 {
382   const gchar svgfilecontent[] = "<svg  xmlns=\"http://www.w3.org/2000/svg\"\
383       xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\
384     <rect x=\"10\" y=\"10\" height=\"100\" width=\"100\"\n\
385           style=\"stroke:#ff0000; fill: #0000ff\"/>\n\
386 </svg>\n";
387
388   gboolean uncertain = TRUE;
389   gchar *res = g_content_type_guess (NULL, (guchar *)svgfilecontent,
390                                      sizeof (svgfilecontent) - 1, &uncertain);
391 #ifdef __APPLE__
392   g_assert_cmpstr (res, ==, "public.svg-image");
393 #elif defined(G_OS_WIN32)
394   g_test_skip ("svg type detection from content is not implemented on WIN32");
395 #else
396   g_assert_cmpstr (res, ==, "image/svg+xml");
397 #endif
398   g_assert_false (uncertain);
399   g_free (res);
400 }
401
402 static void
403 test_mime_from_content (void)
404 {
405 #ifdef __APPLE__
406   gchar *mime_type;
407   mime_type = g_content_type_get_mime_type ("com.microsoft.bmp");
408   g_assert_cmpstr (mime_type, ==, "image/bmp");
409   g_free (mime_type);
410   mime_type = g_content_type_get_mime_type ("com.compuserve.gif");
411   g_assert_cmpstr (mime_type, ==, "image/gif");
412   g_free (mime_type);
413   mime_type = g_content_type_get_mime_type ("public.png");
414   g_assert_cmpstr (mime_type, ==, "image/png");
415   g_free (mime_type);
416   mime_type = g_content_type_get_mime_type ("public.text");
417   g_assert_cmpstr (mime_type, ==, "text/*");
418   g_free (mime_type);
419   mime_type = g_content_type_get_mime_type ("public.svg-image");
420   g_assert_cmpstr (mime_type, ==, "image/svg+xml");
421   g_free (mime_type);
422 #elif defined(G_OS_WIN32)
423   g_test_skip ("mime from content type test not implemented on WIN32");
424 #else
425   g_test_skip ("mime from content type test not implemented on UNIX");
426 #endif
427 }
428
429 int
430 main (int argc, char *argv[])
431 {
432   g_test_init (&argc, &argv, NULL);
433
434   g_test_add_func ("/contenttype/guess", test_guess);
435   g_test_add_func ("/contenttype/guess_svg_from_data", test_guess_svg_from_data);
436   g_test_add_func ("/contenttype/mime_from_content", test_mime_from_content);
437   g_test_add_func ("/contenttype/unknown", test_unknown);
438   g_test_add_func ("/contenttype/subtype", test_subtype);
439   g_test_add_func ("/contenttype/list", test_list);
440   g_test_add_func ("/contenttype/executable", test_executable);
441   g_test_add_func ("/contenttype/description", test_description);
442   g_test_add_func ("/contenttype/icon", test_icon);
443   g_test_add_func ("/contenttype/symbolic-icon", test_symbolic_icon);
444   g_test_add_func ("/contenttype/tree", test_tree);
445   g_test_add_func ("/contenttype/test_type_is_a_special_case",
446                    test_type_is_a_special_case);
447
448   return g_test_run ();
449 }