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 |
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 (str: "/etc/" ); |
41 | #endif |
42 | |
43 | res = g_content_type_guess (filename: existing_directory, NULL, data_size: 0, result_uncertain: &uncertain); |
44 | g_free (mem: existing_directory); |
45 | expected = g_content_type_from_mime_type (mime_type: "inode/directory" ); |
46 | g_assert_content_type_equals (expected, res); |
47 | g_assert_true (uncertain); |
48 | g_free (mem: res); |
49 | g_free (mem: expected); |
50 | |
51 | res = g_content_type_guess (filename: "foo.txt" , NULL, data_size: 0, result_uncertain: &uncertain); |
52 | expected = g_content_type_from_mime_type (mime_type: "text/plain" ); |
53 | g_assert_content_type_equals (expected, res); |
54 | g_free (mem: res); |
55 | g_free (mem: expected); |
56 | |
57 | res = g_content_type_guess (filename: "foo.txt" , data, data_size: sizeof (data) - 1, result_uncertain: &uncertain); |
58 | expected = g_content_type_from_mime_type (mime_type: "text/plain" ); |
59 | g_assert_content_type_equals (expected, res); |
60 | g_assert_false (uncertain); |
61 | g_free (mem: res); |
62 | g_free (mem: 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 (filename: "foo" , data, data_size: sizeof (data) - 1, result_uncertain: &uncertain); |
67 | expected = g_content_type_from_mime_type (mime_type: "text/plain" ); |
68 | g_assert_content_type_equals (expected, res); |
69 | g_assert_false (uncertain); |
70 | g_free (mem: res); |
71 | g_free (mem: expected); |
72 | |
73 | res = g_content_type_guess (filename: "foo.desktop" , data, data_size: sizeof (data) - 1, result_uncertain: &uncertain); |
74 | expected = g_content_type_from_mime_type (mime_type: "application/x-desktop" ); |
75 | g_assert_content_type_equals (expected, res); |
76 | g_assert_false (uncertain); |
77 | g_free (mem: res); |
78 | g_free (mem: expected); |
79 | |
80 | res = g_content_type_guess (NULL, data, data_size: sizeof (data) - 1, result_uncertain: &uncertain); |
81 | expected = g_content_type_from_mime_type (mime_type: "application/x-desktop" ); |
82 | g_assert_content_type_equals (expected, res); |
83 | g_assert_false (uncertain); |
84 | g_free (mem: res); |
85 | g_free (mem: 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 (filename: "test.pot" , data: (guchar *)"ABC abc" , data_size: 7, result_uncertain: &uncertain); |
90 | expected = g_content_type_from_mime_type (mime_type: "text/x-gettext-translation-template" ); |
91 | g_assert_content_type_equals (expected, res); |
92 | g_assert_false (uncertain); |
93 | g_free (mem: res); |
94 | g_free (mem: expected); |
95 | |
96 | res = g_content_type_guess (filename: "test.pot" , data: (guchar *)"msgid \"" , data_size: 7, result_uncertain: &uncertain); |
97 | expected = g_content_type_from_mime_type (mime_type: "text/x-gettext-translation-template" ); |
98 | g_assert_content_type_equals (expected, res); |
99 | g_assert_false (uncertain); |
100 | g_free (mem: res); |
101 | g_free (mem: expected); |
102 | |
103 | res = g_content_type_guess (filename: "test.pot" , data: (guchar *)"\xCF\xD0\xE0\x11" , data_size: 4, result_uncertain: &uncertain); |
104 | expected = g_content_type_from_mime_type (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 (mem: res); |
110 | g_free (mem: expected); |
111 | |
112 | res = g_content_type_guess (filename: "test.otf" , data: (guchar *)"OTTO" , data_size: 4, result_uncertain: &uncertain); |
113 | expected = g_content_type_from_mime_type (mime_type: "application/x-font-otf" ); |
114 | g_assert_content_type_equals (expected, res); |
115 | g_assert_false (uncertain); |
116 | g_free (mem: res); |
117 | g_free (mem: expected); |
118 | #endif |
119 | |
120 | res = g_content_type_guess (NULL, data: (guchar *)"%!PS-Adobe-2.0 EPSF-1.2" , data_size: 23, result_uncertain: &uncertain); |
121 | expected = g_content_type_from_mime_type (mime_type: "image/x-eps" ); |
122 | g_assert_content_type_equals (expected, res); |
123 | g_assert_false (uncertain); |
124 | g_free (mem: res); |
125 | g_free (mem: 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, data: (guchar *)"%!PS-Adobe-2.0 EPSF-1.2" , data_size: 0, result_uncertain: &uncertain); |
129 | expected = g_content_type_from_mime_type (mime_type: "application/x-zerosize" ); |
130 | g_assert_content_type_equals (expected, res); |
131 | g_assert_false (uncertain); |
132 | g_free (mem: res); |
133 | g_free (mem: expected); |
134 | #endif |
135 | } |
136 | |
137 | static 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 (mime_type: "application/octet-stream" ); |
147 | g_assert_true (g_content_type_is_unknown (unknown)); |
148 | str = g_content_type_get_mime_type (type: unknown); |
149 | g_assert_cmpstr (str, ==, "application/octet-stream" ); |
150 | g_free (mem: str); |
151 | g_free (mem: unknown); |
152 | #endif |
153 | } |
154 | |
155 | static 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 (mime_type: "text/plain" ); |
165 | xml = g_content_type_from_mime_type (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 (mem: plain); |
171 | g_free (mem: xml); |
172 | #endif |
173 | } |
174 | |
175 | static gint |
176 | find_mime (gconstpointer a, gconstpointer b) |
177 | { |
178 | if (g_content_type_equals (type1: a, type2: b)) |
179 | return 0; |
180 | return 1; |
181 | } |
182 | |
183 | static 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 (mime_type: "text/plain" ); |
200 | xml = g_content_type_from_mime_type (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 (list: types, free_func: g_free); |
211 | |
212 | g_free (mem: plain); |
213 | g_free (mem: xml); |
214 | #endif |
215 | } |
216 | |
217 | static 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 (mime_type: "application/x-executable" ); |
226 | g_assert_true (g_content_type_can_be_executable (type)); |
227 | g_free (mem: type); |
228 | |
229 | type = g_content_type_from_mime_type (mime_type: "text/plain" ); |
230 | g_assert_true (g_content_type_can_be_executable (type)); |
231 | g_free (mem: type); |
232 | |
233 | type = g_content_type_from_mime_type (mime_type: "image/png" ); |
234 | g_assert_false (g_content_type_can_be_executable (type)); |
235 | g_free (mem: type); |
236 | #endif |
237 | } |
238 | |
239 | static 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 (mime_type: "text/plain" ); |
249 | desc = g_content_type_get_description (type); |
250 | g_assert_nonnull (desc); |
251 | |
252 | g_free (mem: desc); |
253 | g_free (mem: type); |
254 | #endif |
255 | } |
256 | |
257 | static 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 (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 (object: icon); |
282 | g_free (mem: type); |
283 | |
284 | type = g_content_type_from_mime_type (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 (object: icon); |
298 | g_free (mem: type); |
299 | #endif |
300 | } |
301 | |
302 | static 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 (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 (object: icon); |
330 | g_free (mem: type); |
331 | |
332 | type = g_content_type_from_mime_type (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 (object: icon); |
348 | g_free (mem: type); |
349 | #endif |
350 | } |
351 | |
352 | static 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 (file_type: G_TEST_DIST, first_path: tests[i], NULL); |
376 | file = g_file_new_for_path (path); |
377 | types = g_content_type_guess_for_tree (root: file); |
378 | g_assert_content_type_equals (types[0], tests[i]); |
379 | g_strfreev (str_array: types); |
380 | g_object_unref (object: file); |
381 | } |
382 | #endif |
383 | } |
384 | |
385 | static 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 (bug_uri_snippet: "782311" ); |
394 | |
395 | /* Everything but the inode type is application/octet-stream */ |
396 | res = g_content_type_is_a (type: "inode/directory" , supertype: "application/octet-stream" ); |
397 | g_assert_false (res); |
398 | #ifndef __APPLE__ |
399 | res = g_content_type_is_a (type: "anything" , supertype: "application/octet-stream" ); |
400 | g_assert_true (res); |
401 | #endif |
402 | #endif |
403 | } |
404 | |
405 | static 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, data: (guchar *)svgfilecontent, |
419 | data_size: sizeof (svgfilecontent) - 1, result_uncertain: &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 (mem: res); |
429 | #endif |
430 | } |
431 | |
432 | static 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 (msg: "mime from content type test not implemented on UNIX" ); |
458 | #endif |
459 | } |
460 | |
461 | int |
462 | main (int argc, char *argv[]) |
463 | { |
464 | g_test_init (argc: &argc, argv: &argv, NULL); |
465 | |
466 | g_test_bug_base (uri_pattern: "http://bugzilla.gnome.org/" ); |
467 | |
468 | g_test_add_func (testpath: "/contenttype/guess" , test_func: test_guess); |
469 | g_test_add_func (testpath: "/contenttype/guess_svg_from_data" , test_func: test_guess_svg_from_data); |
470 | g_test_add_func (testpath: "/contenttype/mime_from_content" , test_func: test_mime_from_content); |
471 | g_test_add_func (testpath: "/contenttype/unknown" , test_func: test_unknown); |
472 | g_test_add_func (testpath: "/contenttype/subtype" , test_func: test_subtype); |
473 | g_test_add_func (testpath: "/contenttype/list" , test_func: test_list); |
474 | g_test_add_func (testpath: "/contenttype/executable" , test_func: test_executable); |
475 | g_test_add_func (testpath: "/contenttype/description" , test_func: test_description); |
476 | g_test_add_func (testpath: "/contenttype/icon" , test_func: test_icon); |
477 | g_test_add_func (testpath: "/contenttype/symbolic-icon" , test_func: test_symbolic_icon); |
478 | g_test_add_func (testpath: "/contenttype/tree" , test_func: test_tree); |
479 | g_test_add_func (testpath: "/contenttype/test_type_is_a_special_case" , |
480 | test_func: test_type_is_a_special_case); |
481 | |
482 | return g_test_run (); |
483 | } |
484 | |