gstfunnel: avoid access of freed pad
[platform/upstream/gstreamer.git] / gst / gstplugin.c
index 68c4d2d..a7542fc 100644 (file)
@@ -90,18 +90,17 @@ static char *_gst_plugin_fault_handler_filename = NULL;
  * MIT/X11: http://www.opensource.org/licenses/mit-license.php
  * 3-clause BSD: http://www.opensource.org/licenses/bsd-license.php
  */
-static const gchar *valid_licenses[] = {
-  "LGPL",                       /* GNU Lesser General Public License */
-  "GPL",                        /* GNU General Public License */
-  "QPL",                        /* Trolltech Qt Public License */
-  "GPL/QPL",                    /* Combi-license of GPL + QPL */
-  "MPL",                        /* MPL 1.1 license */
-  "BSD",                        /* 3-clause BSD license */
-  "MIT/X11",                    /* MIT/X11 license */
-  "Proprietary",                /* Proprietary license */
-  GST_LICENSE_UNKNOWN,          /* some other license */
-  NULL
-};
+static const gchar valid_licenses[] = "LGPL\000"        /* GNU Lesser General Public License */
+    "GPL\000"                   /* GNU General Public License */
+    "QPL\000"                   /* Trolltech Qt Public License */
+    "GPL/QPL\000"               /* Combi-license of GPL + QPL */
+    "MPL\000"                   /* MPL 1.1 license */
+    "BSD\000"                   /* 3-clause BSD license */
+    "MIT/X11\000"               /* MIT/X11 license */
+    "Proprietary\000"           /* Proprietary license */
+    GST_LICENSE_UNKNOWN;        /* some other license */
+
+static const guint8 valid_licenses_idx[] = { 0, 5, 9, 13, 21, 25, 29, 37, 49 };
 
 static GstPlugin *gst_plugin_register_func (GstPlugin * plugin,
     const GstPluginDesc * desc, gpointer user_data);
@@ -123,15 +122,20 @@ static void
 gst_plugin_finalize (GObject * object)
 {
   GstPlugin *plugin = GST_PLUGIN_CAST (object);
-  GstRegistry *registry = gst_registry_get_default ();
-  GList *g;
 
   GST_DEBUG ("finalizing plugin %" GST_PTR_FORMAT, plugin);
+
+  /* FIXME: make registry add a weak ref instead */
+#if 0
+  GstRegistry *registry = gst_registry_get ();
+  GList *g;
   for (g = registry->plugins; g; g = g->next) {
     if (g->data == (gpointer) plugin) {
       g_warning ("removing plugin that is still in registry");
     }
   }
+#endif
+
   g_free (plugin->filename);
   g_free (plugin->basename);
 
@@ -221,7 +225,7 @@ gst_plugin_register_static (gint major_version, gint minor_version,
   plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL);
   if (gst_plugin_register_func (plugin, &desc, NULL) != NULL) {
     GST_INFO ("registered static plugin \"%s\"", name);
-    res = gst_default_registry_add_plugin (plugin);
+    res = gst_registry_add_plugin (gst_registry_get (), plugin);
     GST_INFO ("added static plugin \"%s\", result: %d", name, res);
   }
   return res;
@@ -291,14 +295,14 @@ gst_plugin_register_static_full (gint major_version, gint minor_version,
   plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL);
   if (gst_plugin_register_func (plugin, &desc, user_data) != NULL) {
     GST_INFO ("registered static plugin \"%s\"", name);
-    res = gst_default_registry_add_plugin (plugin);
+    res = gst_registry_add_plugin (gst_registry_get (), plugin);
     GST_INFO ("added static plugin \"%s\", result: %d", name, res);
   }
   return res;
 }
 
 void
-_gst_plugin_initialize (void)
+_priv_gst_plugin_initialize (void)
 {
   const gchar *whitelist;
   guint i;
@@ -455,14 +459,11 @@ priv_gst_plugin_loading_get_whitelist_hash (void)
 static gboolean
 gst_plugin_check_license (const gchar * license)
 {
-  const gchar **check_license = valid_licenses;
-
-  g_assert (check_license);
+  gint i;
 
-  while (*check_license) {
-    if (strcmp (license, *check_license) == 0)
+  for (i = 0; i < G_N_ELEMENTS (valid_licenses_idx); ++i) {
+    if (strcmp (license, valid_licenses + valid_licenses_idx[i]) == 0)
       return TRUE;
-    check_license++;
   }
   return FALSE;
 }
@@ -472,7 +473,7 @@ gst_plugin_check_version (gint major, gint minor)
 {
   /* return NULL if the major and minor version numbers are not compatible */
   /* with ours. */
-  if (major != GST_VERSION_MAJOR || minor != GST_VERSION_MINOR)
+  if (major != GST_VERSION_MAJOR || minor > GST_VERSION_MINOR)
     return FALSE;
 
   return TRUE;
@@ -654,7 +655,7 @@ check_release_datetime (const gchar * date_time)
   return (*date_time == '\0');
 }
 
-static GStaticMutex gst_plugin_loading_mutex = G_STATIC_MUTEX_INIT;
+static GMutex gst_plugin_loading_mutex;
 
 #define CHECK_PLUGIN_DESC_FIELD(desc,field,fn)                               \
   if (G_UNLIKELY ((desc)->field == NULL)) {                                  \
@@ -686,14 +687,14 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
 
   g_return_val_if_fail (filename != NULL, NULL);
 
-  registry = gst_registry_get_default ();
-  g_static_mutex_lock (&gst_plugin_loading_mutex);
+  registry = gst_registry_get ();
+  g_mutex_lock (&gst_plugin_loading_mutex);
 
   plugin = gst_registry_lookup (registry, filename);
   if (plugin) {
     if (plugin->module) {
       /* already loaded */
-      g_static_mutex_unlock (&gst_plugin_loading_mutex);
+      g_mutex_unlock (&gst_plugin_loading_mutex);
       return plugin;
     } else {
       /* load plugin and update fields */
@@ -828,17 +829,17 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
 
   if (new_plugin) {
     gst_object_ref (plugin);
-    gst_default_registry_add_plugin (plugin);
+    gst_registry_add_plugin (gst_registry_get (), plugin);
   }
 
-  g_static_mutex_unlock (&gst_plugin_loading_mutex);
+  g_mutex_unlock (&gst_plugin_loading_mutex);
   return plugin;
 
 return_error:
   {
     if (plugin)
       gst_object_unref (plugin);
-    g_static_mutex_unlock (&gst_plugin_loading_mutex);
+    g_mutex_unlock (&gst_plugin_loading_mutex);
     return NULL;
   }
 }
@@ -988,21 +989,26 @@ gst_plugin_get_origin (GstPlugin * plugin)
 }
 
 /**
- * gst_plugin_get_module:
- * @plugin: plugin to query
+ * gst_plugin_get_release_date_string:
+ * @plugin: plugin to get the release date of
+ *
+ * Get the release date (and possibly time) in form of a string, if available.
+ *
+ * For normal GStreamer plugin releases this will usually just be a date in
+ * the form of "YYYY-MM-DD", while pre-releases and builds from git may contain
+ * a time component after the date as well, in which case the string will be
+ * formatted like "YYYY-MM-DDTHH:MMZ" (e.g. "2012-04-30T09:30Z").
  *
- * Gets the #GModule of the plugin. If the plugin isn't loaded yet, NULL is
- * returned.
+ * There may be plugins that do not have a valid release date set on them.
  *
- * Returns: (transfer none): module belonging to the plugin or NULL if the
- *          plugin isn't loaded yet.
+ * Returns: the date string of the plugin, or %NULL if not available.
  */
-GModule *
-gst_plugin_get_module (GstPlugin * plugin)
+const gchar *
+gst_plugin_get_release_date_string (GstPlugin * plugin)
 {
   g_return_val_if_fail (plugin != NULL, NULL);
 
-  return plugin->module;
+  return plugin->desc.release_datetime;
 }
 
 /**
@@ -1149,25 +1155,7 @@ gst_plugin_list_feature_filter (GList * list,
 
   return data.result;
 }
-#endif
-
-/**
- * gst_plugin_name_filter:
- * @plugin: the plugin to check
- * @name: the name of the plugin
- *
- * A standard filter that returns TRUE when the plugin is of the
- * given name.
- *
- * Returns: TRUE if the plugin is of the given name.
- */
-gboolean
-gst_plugin_name_filter (GstPlugin * plugin, const gchar * name)
-{
-  return (plugin->desc.name && !strcmp (plugin->desc.name, name));
-}
 
-#if 0
 /**
  * gst_plugin_find_feature:
  * @plugin: plugin to get the feature from
@@ -1259,7 +1247,7 @@ gst_plugin_load_by_name (const gchar * name)
   GError *error = NULL;
 
   GST_DEBUG ("looking up plugin %s in default registry", name);
-  plugin = gst_registry_find_plugin (gst_registry_get_default (), name);
+  plugin = gst_registry_find_plugin (gst_registry_get (), name);
   if (plugin) {
     GST_DEBUG ("loading plugin %s from file %s", name, plugin->filename);
     newplugin = gst_plugin_load_file (plugin->filename, &error);
@@ -1419,12 +1407,11 @@ _priv_plugin_deps_env_vars_changed (GstPlugin * plugin)
   return FALSE;
 }
 
-static GList *
+static void
 gst_plugin_ext_dep_extract_env_vars_paths (GstPlugin * plugin,
-    GstPluginDep * dep)
+    GstPluginDep * dep, GQueue * paths)
 {
   gchar **evars;
-  GList *paths = NULL;
 
   for (evars = dep->env_vars; evars != NULL && *evars != NULL; ++evars) {
     const gchar *e;
@@ -1471,9 +1458,9 @@ gst_plugin_ext_dep_extract_env_vars_paths (GstPlugin * plugin,
           full_path = g_strdup (arr[i]);
         }
 
-        if (!g_list_find_custom (paths, full_path, (GCompareFunc) strcmp)) {
+        if (!g_queue_find_custom (paths, full_path, (GCompareFunc) strcmp)) {
           GST_LOG_OBJECT (plugin, "path: '%s'", full_path);
-          paths = g_list_prepend (paths, full_path);
+          g_queue_push_tail (paths, full_path);
           full_path = NULL;
         } else {
           GST_LOG_OBJECT (plugin, "path: '%s' (duplicate,ignoring)", full_path);
@@ -1487,10 +1474,7 @@ gst_plugin_ext_dep_extract_env_vars_paths (GstPlugin * plugin,
     g_strfreev (components);
   }
 
-  GST_LOG_OBJECT (plugin, "Extracted %d paths from environment",
-      g_list_length (paths));
-
-  return paths;
+  GST_LOG_OBJECT (plugin, "Extracted %d paths from environment", paths->length);
 }
 
 static guint
@@ -1538,7 +1522,7 @@ gst_plugin_ext_dep_scan_dir_and_match_names (GstPlugin * plugin,
   GDir *dir;
   guint hash = 0;
 
-  recurse_dirs = !!(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
+  recurse_dirs = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
 
   dir = g_dir_open (path, 0, &err);
   if (dir == NULL) {
@@ -1600,8 +1584,8 @@ gst_plugin_ext_dep_scan_path_with_filenames (GstPlugin * plugin,
   if (filenames == NULL || *filenames == NULL)
     filenames = empty_filenames;
 
-  recurse_into_dirs = !!(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
-  partial_names = !!(flags & GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX);
+  recurse_into_dirs = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
+  partial_names = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX);
 
   /* if we can construct the exact paths to check with the data we have, just
    * stat them one by one; this is more efficient than opening the directory
@@ -1636,43 +1620,37 @@ static guint
 gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep)
 {
   gboolean paths_are_default_only;
-  GList *scan_paths;
+  GQueue scan_paths = G_QUEUE_INIT;
   guint scan_hash = 0;
+  gchar *path;
 
   GST_LOG_OBJECT (plugin, "start");
 
   paths_are_default_only =
       dep->flags & GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY;
 
-  scan_paths = gst_plugin_ext_dep_extract_env_vars_paths (plugin, dep);
+  gst_plugin_ext_dep_extract_env_vars_paths (plugin, dep, &scan_paths);
 
-  if (scan_paths == NULL || !paths_are_default_only) {
+  if (g_queue_is_empty (&scan_paths) || !paths_are_default_only) {
     gchar **paths;
 
     for (paths = dep->paths; paths != NULL && *paths != NULL; ++paths) {
       const gchar *path = *paths;
 
-      if (!g_list_find_custom (scan_paths, path, (GCompareFunc) strcmp)) {
+      if (!g_queue_find_custom (&scan_paths, path, (GCompareFunc) strcmp)) {
         GST_LOG_OBJECT (plugin, "path: '%s'", path);
-        scan_paths = g_list_prepend (scan_paths, g_strdup (path));
+        g_queue_push_tail (&scan_paths, g_strdup (path));
       } else {
         GST_LOG_OBJECT (plugin, "path: '%s' (duplicate, ignoring)", path);
       }
     }
   }
 
-  /* not that the order really matters, but it makes debugging easier */
-  scan_paths = g_list_reverse (scan_paths);
-
-  while (scan_paths != NULL) {
-    const gchar *path = scan_paths->data;
-
+  while ((path = g_queue_pop_head (&scan_paths))) {
     scan_hash += gst_plugin_ext_dep_scan_path_with_filenames (plugin, path,
         (const gchar **) dep->names, dep->flags);
     scan_hash = scan_hash << 1;
-
-    g_free (scan_paths->data);
-    scan_paths = g_list_delete_link (scan_paths, scan_paths);
+    g_free (path);
   }
 
   GST_LOG_OBJECT (plugin, "done, scan_hash: %08x", scan_hash);
@@ -1732,7 +1710,7 @@ gst_plugin_ext_dep_equals (GstPluginDep * dep, const gchar ** env_vars,
 /**
  * gst_plugin_add_dependency:
  * @plugin: a #GstPlugin
- * @env_vars: NULL-terminated array of environent variables affecting the
+ * @env_vars: NULL-terminated array of environment variables affecting the
  *     feature set of the plugin (e.g. an environment variable containing
  *     paths where to look for additional modules/plugins of a library),
  *     or NULL. Environment variable names may be followed by a path component
@@ -1805,7 +1783,7 @@ gst_plugin_add_dependency (GstPlugin * plugin, const gchar ** env_vars,
 /**
  * gst_plugin_add_dependency_simple:
  * @plugin: the #GstPlugin
- * @env_vars: one or more environent variables (separated by ':', ';' or ','),
+ * @env_vars: one or more environment variables (separated by ':', ';' or ','),
  *      or NULL. Environment variable names may be followed by a path component
  *      which will be added to the content of the environment variable, e.g.
  *      "HOME/.mystuff/plugins:MYSTUFF_PLUGINS_PATH"