Add 88 new defect entries to HIGH and MEDIUM tables:
HIGH: mysql-0001/0002, mariadb-0001, redis-0001/0002, valkey-0001/0002, openvpn-0001,
vlc-0001, prometheus-0001, otel-collector-0001, cockroachdb-0001..0004,
tidb-0001..0008, kubernetes-0001/0002, go-0001, kotlin-0002, scala-0001,
allegro5-0001, sdl2-0001, grafana-0001, clickhouse-0001, duckdb-0001,
mongodb-0001, envoy-0001, istio-0001, cilium-0001, linkerd2-0001,
linux-0001/0002/0003, tor-0002/0003, curl-0001, julia-0001, lua-0001,
perl5-0001, nats-0001, spring-0003/0004, tomcat-0001, onos-0002, odl-0002
MEDIUM: helm-0001, mariadb-0002, openssl-0001/0002, memcached-0001,
cassandra-0001..0004, flink-0001, storm-0001/0002, zookeeper-0001..0003,
pip-0001, gradle-0001, nginx-0001, haproxy-0001, caddy-0001, varnish-0001,
ffmpeg-0001, gstreamer-0001, raylib-0001, love2d-0001, php-0001/0002,
r-source-0001, cpython-0002, ruby-0001, rabbitmq-0003/0004, activemq-0001,
ovs-0001, onos-0003, odl-0002, jetty-0001
PDF: 976K
88 lines
3.4 KiB
Diff
88 lines
3.4 KiB
Diff
--- 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 50–500 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 (≈1–5).
|
||
+ */
|
||
+
|
||
+ 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;
|
||
}
|