java-topology/defects/gstreamer/patch/gstreamer-0001.patch

89 lines
3.4 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000094
--- a/gst/gstelementfactory.c
+++ b/gst/gstelementfactory.c
@@ -1183,6 +1183,73 @@ gst_element_factory_list_filter (GList * list,
const GstCaps * caps, GstPadDirection direction, gboolean subsetonly)
{
GQueue results = G_QUEUE_INIT;
+ GHashTable *caps_index;
+ GList *indexed_candidates;
+
+ /*
+ * CWE-407 fix: build a temporary media-type → factory hash for this filter
+ * call. The outer list (already pre-filtered by type via list_get_elements)
+ * is typically 50500 entries. Without indexing, every entry requires
+ * gst_caps_can_intersect() which itself is O(S1 × S2).
+ *
+ * Strategy: extract the media type (first structure name) from each factory's
+ * pad templates during a single O(N) pass to build a hash. Then look up only
+ * the query caps media type. Factories with ANY/empty caps are kept in a
+ * fallback list examined after the hash hits.
+ *
+ * This reduces the inner loop from O(N × M × S²) to O(k × M × S²) where
+ * k is the number of factories that handle the specific media type (≈15).
+ */
+
+ if (!list || !caps || GST_CAPS_IS_ANY (caps) || GST_CAPS_IS_EMPTY (caps))
+ goto slow_path;
+
+ caps_index = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) g_list_free);
+
+ {
+ GList *fallback = NULL;
+ for (GList *l = list; l; l = l->next) {
+ GstElementFactory *factory = (GstElementFactory *) l->data;
+ const GList *templates =
+ gst_element_factory_get_static_pad_templates (factory);
+ gboolean has_any = FALSE;
+ for (const GList *t = templates; t; t = g_list_next (t)) {
+ GstStaticPadTemplate *tmpl = t->data;
+ if (tmpl->direction != direction) continue;
+ const gchar *tmpl_str = tmpl->static_caps.string;
+ if (!tmpl_str || g_str_has_prefix (tmpl_str, "ANY") ||
+ g_str_has_prefix (tmpl_str, "EMPTY")) {
+ has_any = TRUE;
+ continue;
+ }
+ /* Extract media type: everything up to first ',' or ' ' */
+ const gchar *comma = strpbrk (tmpl_str, ", ");
+ gchar *mtype = comma
+ ? g_strndup (tmpl_str, (gsize)(comma - tmpl_str))
+ : g_strdup (tmpl_str);
+ GList *bucket = g_hash_table_lookup (caps_index, mtype);
+ g_hash_table_insert (caps_index, mtype,
+ g_list_prepend (bucket, factory));
+ }
+ if (has_any)
+ fallback = g_list_prepend (fallback, factory);
+ }
+ /* Merge hash hits + fallback into candidate list */
+ indexed_candidates = g_list_copy (fallback);
+ g_list_free (fallback);
+ for (guint i = 0; i < gst_caps_get_size (caps); i++) {
+ GstStructure *s = gst_caps_get_structure (caps, i);
+ const gchar *mtype = gst_structure_get_name (s);
+ GList *bucket = g_hash_table_lookup (caps_index, mtype);
+ for (GList *b = bucket; b; b = b->next)
+ if (!g_list_find (indexed_candidates, b->data))
+ indexed_candidates = g_list_prepend (indexed_candidates, b->data);
+ }
+ g_hash_table_destroy (caps_index);
+ /* Run the actual caps check only on the candidate set */
+ list = indexed_candidates;
+ }
+
+slow_path:
GST_DEBUG ("finding factories");
/* loop over all the factories */
@@ -1224,6 +1291,12 @@ gst_element_factory_list_filter (GList * list,
}
}
}
+
+ if (list == indexed_candidates)
+ g_list_free (indexed_candidates);
+
return results.head;
}