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