diff --git a/gst/gst_private.h b/gst/gst_private.h index 7ca941001c..36e03efe29 100644 --- a/gst/gst_private.h +++ b/gst/gst_private.h @@ -75,6 +75,8 @@ struct _GstPluginPrivate { gboolean priv_gst_plugin_loading_have_whitelist (void); +guint32 priv_gst_plugin_loading_get_whitelist_hash (void); + gboolean priv_gst_plugin_desc_is_whitelisted (GstPluginDesc * desc, const gchar * filename); diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 8a5b196857..c8215bde16 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -463,6 +463,21 @@ priv_gst_plugin_loading_have_whitelist (void) return (_plugin_loading_whitelist != NULL); } +guint32 +priv_gst_plugin_loading_get_whitelist_hash (void) +{ + guint32 hash = 0; + + if (_plugin_loading_whitelist != NULL) { + gchar **w; + + for (w = _plugin_loading_whitelist; *w != NULL; ++w) + hash = (hash << 1) ^ g_str_hash (*w); + } + + return hash; +} + /* this function could be extended to check if the plugin license matches the * applications license (would require the app to register its license somehow). * We'll wait for someone who's interested in it to code it :) diff --git a/gst/gstregistrybinary.c b/gst/gstregistrybinary.c index bef0c429f8..d680ebc165 100644 --- a/gst/gstregistrybinary.c +++ b/gst/gstregistrybinary.c @@ -377,6 +377,9 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location) } } + _priv_gst_registry_chunks_save_global_header (&to_write, registry, + priv_gst_plugin_loading_get_whitelist_hash ()); + GST_INFO ("Writing binary registry cache"); cache = gst_registry_binary_cache_init (registry, location); @@ -495,6 +498,7 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location) gsize size; GError *err = NULL; gboolean res = FALSE; + guint32 filter_env_hash = 0; gint check_magic_result; #ifndef GST_DISABLE_GST_DEBUG GTimer *timer = NULL; @@ -554,6 +558,18 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location) goto Error; } + if (!_priv_gst_registry_chunks_load_global_header (registry, &in, + contents + size, &filter_env_hash)) { + GST_ERROR ("Couldn't read global header chunk"); + goto Error; + } + + if (filter_env_hash != priv_gst_plugin_loading_get_whitelist_hash ()) { + GST_INFO_OBJECT (registry, "Plugin loading filter environment changed, " + "ignoring plugin cache to force update with new filter environment"); + goto done; + } + /* check if there are plugins in the file */ if (G_UNLIKELY (!(((gsize) in + sizeof (GstRegistryChunkPluginElement)) < (gsize) contents + size))) { @@ -575,6 +591,8 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location) } } +done: + #ifndef GST_DISABLE_GST_DEBUG g_timer_stop (timer); seconds = g_timer_elapsed (timer, NULL); diff --git a/gst/gstregistrybinary.h b/gst/gstregistrybinary.h index 1d9dae6244..65ed5649f9 100644 --- a/gst/gstregistrybinary.h +++ b/gst/gstregistrybinary.h @@ -55,7 +55,7 @@ G_BEGIN_DECLS * This _must_ be updated whenever the registry format changes, * we currently use the core version where this change happened. */ -#define GST_MAGIC_BINARY_VERSION_STR ("0.10.23.1") +#define GST_MAGIC_BINARY_VERSION_STR ("0.10.29.1") /* * GST_MAGIC_BINARY_VERSION_LEN: diff --git a/gst/gstregistrychunks.c b/gst/gstregistrychunks.c index 018e59ef83..7dd3ba23eb 100644 --- a/gst/gstregistrychunks.c +++ b/gst/gstregistrychunks.c @@ -837,3 +837,39 @@ fail: GST_INFO ("Reading plugin failed after %u bytes", (guint) (end - start)); return FALSE; } + +void +_priv_gst_registry_chunks_save_global_header (GList ** list, + GstRegistry * registry, guint32 filter_env_hash) +{ + GstRegistryChunkGlobalHeader *hdr; + GstRegistryChunk *chk; + + hdr = g_slice_new (GstRegistryChunkGlobalHeader); + chk = gst_registry_chunks_make_data (hdr, + sizeof (GstRegistryChunkGlobalHeader)); + + hdr->filter_env_hash = filter_env_hash; + + *list = g_list_prepend (*list, chk); + + GST_LOG ("Saved global header (filter_env_hash=0x%08x)", filter_env_hash); +} + +gboolean +_priv_gst_registry_chunks_load_global_header (GstRegistry * registry, + gchar ** in, gchar * end, guint32 * filter_env_hash) +{ + GstRegistryChunkGlobalHeader *hdr; + + align (*in); + GST_LOG ("Reading/casting for GstRegistryChunkGlobalHeader at %p", *in); + unpack_element (*in, hdr, GstRegistryChunkGlobalHeader, end, fail); + *filter_env_hash = hdr->filter_env_hash; + return TRUE; + + /* Errors */ +fail: + GST_WARNING ("Reading global header failed"); + return FALSE; +} diff --git a/gst/gstregistrychunks.h b/gst/gstregistrychunks.h index 3c7057c110..fdbac5ec86 100644 --- a/gst/gstregistrychunks.h +++ b/gst/gstregistrychunks.h @@ -50,6 +50,11 @@ typedef struct _GstRegistryChunk gboolean align; } GstRegistryChunk; +typedef struct _GstRegistryChunkGlobalHeader +{ + guint32 filter_env_hash; +} GstRegistryChunkGlobalHeader; + /* * GstRegistryChunkPluginElement: * @@ -147,6 +152,14 @@ gboolean _priv_gst_registry_chunks_load_plugin (GstRegistry * registry, gchar ** in, gchar *end, GstPlugin **out_plugin); +void +_priv_gst_registry_chunks_save_global_header (GList ** list, + GstRegistry * registry, guint32 filter_env_hash); + +gboolean +_priv_gst_registry_chunks_load_global_header (GstRegistry * registry, + gchar ** in, gchar *end, guint32 * filter_env_hash); + void _priv_gst_registry_chunk_free (GstRegistryChunk *chunk);