(root)/
glib-2.79.0/
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_tree_invalid_encoding (void)
     365  {
     366    gchar *path;
     367    gchar *name;
     368    GFile *tmpdir;
     369    GFile *file;
     370    gchar **types;
     371    GError *error = NULL;
     372  
     373    g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3168");
     374  
     375  #if defined(__APPLE__) || defined(G_OS_WIN32)
     376    g_test_skip ("The OSX & Windows backends do not implement g_content_type_guess_for_tree()");
     377    return;
     378  #endif
     379  
     380    path = g_dir_make_tmp ("gio-test-tree-invalid-encoding-XXXXXX", &error);
     381    g_assert_no_error (error);
     382    tmpdir = g_file_new_for_path (path);
     383    g_free (path);
     384  
     385    name = g_strdup_printf ("\260");
     386    file = g_file_get_child (tmpdir, name);
     387    g_free (name);
     388  
     389    g_file_replace_contents (file, "", 0, NULL, FALSE, 0, NULL, NULL, &error);
     390    if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT))
     391      {
     392        g_test_skip ("Unable to create testing file with non-ASCII characters.");
     393  
     394        g_object_unref (tmpdir);
     395        g_object_unref (file);
     396        g_clear_error (&error);
     397  
     398        return;
     399      }
     400    g_assert_no_error (error);
     401  
     402    types = g_content_type_guess_for_tree (tmpdir);
     403    g_strfreev (types);
     404  
     405    g_file_delete (file, NULL, &error);
     406    g_assert_no_error (error);
     407    g_object_unref (file);
     408  
     409    g_file_delete (tmpdir, NULL, &error);
     410    g_assert_no_error (error);
     411    g_object_unref (tmpdir);
     412  }
     413  
     414  static void
     415  test_type_is_a_special_case (void)
     416  {
     417    gboolean res;
     418  
     419    g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=782311");
     420  
     421    /* Everything but the inode type is application/octet-stream */
     422    res = g_content_type_is_a ("inode/directory", "application/octet-stream");
     423    g_assert_false (res);
     424  #if !defined(__APPLE__) && !defined(G_OS_WIN32)
     425    res = g_content_type_is_a ("anything", "application/octet-stream");
     426    g_assert_true (res);
     427  #endif
     428  }
     429  
     430  static void
     431  test_guess_svg_from_data (void)
     432  {
     433    const gchar svgfilecontent[] = "<svg  xmlns=\"http://www.w3.org/2000/svg\"\
     434        xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\
     435      <rect x=\"10\" y=\"10\" height=\"100\" width=\"100\"\n\
     436            style=\"stroke:#ff0000; fill: #0000ff\"/>\n\
     437  </svg>\n";
     438  
     439    gboolean uncertain = TRUE;
     440    gchar *res = g_content_type_guess (NULL, (guchar *)svgfilecontent,
     441                                       sizeof (svgfilecontent) - 1, &uncertain);
     442  #ifdef __APPLE__
     443    g_assert_cmpstr (res, ==, "public.svg-image");
     444  #elif defined(G_OS_WIN32)
     445    g_test_skip ("svg type detection from content is not implemented on WIN32");
     446  #else
     447    g_assert_cmpstr (res, ==, "image/svg+xml");
     448  #endif
     449    g_assert_false (uncertain);
     450    g_free (res);
     451  }
     452  
     453  static void
     454  test_mime_from_content (void)
     455  {
     456  #ifdef __APPLE__
     457    gchar *mime_type;
     458    mime_type = g_content_type_get_mime_type ("com.microsoft.bmp");
     459    g_assert_cmpstr (mime_type, ==, "image/bmp");
     460    g_free (mime_type);
     461    mime_type = g_content_type_get_mime_type ("com.compuserve.gif");
     462    g_assert_cmpstr (mime_type, ==, "image/gif");
     463    g_free (mime_type);
     464    mime_type = g_content_type_get_mime_type ("public.png");
     465    g_assert_cmpstr (mime_type, ==, "image/png");
     466    g_free (mime_type);
     467    mime_type = g_content_type_get_mime_type ("public.text");
     468    g_assert_cmpstr (mime_type, ==, "text/*");
     469    g_free (mime_type);
     470    mime_type = g_content_type_get_mime_type ("public.svg-image");
     471    g_assert_cmpstr (mime_type, ==, "image/svg+xml");
     472    g_free (mime_type);
     473  #elif defined(G_OS_WIN32)
     474    g_test_skip ("mime from content type test not implemented on WIN32");
     475  #else
     476    g_test_skip ("mime from content type test not implemented on UNIX");
     477  #endif
     478  }
     479  
     480  int
     481  main (int argc, char *argv[])
     482  {
     483    g_test_init (&argc, &argv, NULL);
     484  
     485    g_test_add_func ("/contenttype/guess", test_guess);
     486    g_test_add_func ("/contenttype/guess_svg_from_data", test_guess_svg_from_data);
     487    g_test_add_func ("/contenttype/mime_from_content", test_mime_from_content);
     488    g_test_add_func ("/contenttype/unknown", test_unknown);
     489    g_test_add_func ("/contenttype/subtype", test_subtype);
     490    g_test_add_func ("/contenttype/list", test_list);
     491    g_test_add_func ("/contenttype/executable", test_executable);
     492    g_test_add_func ("/contenttype/description", test_description);
     493    g_test_add_func ("/contenttype/icon", test_icon);
     494    g_test_add_func ("/contenttype/symbolic-icon", test_symbolic_icon);
     495    g_test_add_func ("/contenttype/tree", test_tree);
     496    g_test_add_func ("/contenttype/tree_invalid_encoding",
     497                     test_tree_invalid_encoding);
     498    g_test_add_func ("/contenttype/test_type_is_a_special_case",
     499                     test_type_is_a_special_case);
     500  
     501    return g_test_run ();
     502  }