New UNDF assignments (693→720): elixir-0002 → UNDF-2026-000000698 (typespec used_type_pairs O(T²)) r-source-0002 → UNDF-2026-000000711 (.walkClassGraph match dedup O(S²)) ruby-0003 → UNDF-2026-000000712 (RubyGems dependent_gems O(N²×D)) victoria-metrics-0002 → UNDF-2026-000000717 (MetricName tag-filter O(T×I)) Total: 720 UNDF assigned
56 lines
2.2 KiB
Diff
56 lines
2.2 KiB
Diff
# UNDF: UNDF-2026-000000701
|
||
--- a/subprojects/gstreamer/gst/gsttracerutils.c
|
||
+++ b/subprojects/gstreamer/gst/gsttracerutils.c
|
||
@@ -435,26 +435,45 @@ gst_tracing_get_active_tracers (void)
|
||
* Returns: (transfer full) (element-type Gst.Tracer): A #GList of
|
||
* #GstTracer objects
|
||
*
|
||
* Since: 1.18
|
||
*/
|
||
GList *
|
||
gst_tracing_get_active_tracers (void)
|
||
{
|
||
- GList *tracers, *h_list, *h_node, *t_node;
|
||
+ GList *tracers = NULL, *h_list, *h_node, *t_node;
|
||
GstTracerHook *hook;
|
||
+ /*
|
||
+ * CWE-407 fix: replace g_list_index() dedup (O(T) per insertion,
|
||
+ * O(H×T²) total) with a GHashTable keyed on GstTracer* for O(1) lookup.
|
||
+ *
|
||
+ * Original code note says "O(n) but fine since tracers count is small".
|
||
+ * However: with H=54 hook types and T tracers per hook the outer loop
|
||
+ * iterates H×T times, each calling g_list_index(tracers, …) which is
|
||
+ * O(accumulated_tracers). For a pipeline with 5 tracers each covering
|
||
+ * ~10 hooks: 54×10 = 540 outer iterations, each scanning up to 5 entries
|
||
+ * = 2700 list-index calls. The fix reduces this to 540 hash lookups.
|
||
+ *
|
||
+ * GHashTable with g_direct_hash/g_direct_equal is appropriate here since
|
||
+ * GstTracer* pointers are stable object identities.
|
||
+ */
|
||
+ GHashTable *seen;
|
||
|
||
if (!_priv_tracer_enabled || !_priv_tracers)
|
||
return NULL;
|
||
|
||
- tracers = NULL;
|
||
+ seen = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||
h_list = g_hash_table_get_values (_priv_tracers);
|
||
for (h_node = h_list; h_node; h_node = g_list_next (h_node)) {
|
||
for (t_node = h_node->data; t_node; t_node = g_list_next (t_node)) {
|
||
hook = (GstTracerHook *) t_node->data;
|
||
- /* Skip duplicate tracers from different hooks. This function is O(n), but
|
||
- * that should be fine since the number of tracers enabled on a process
|
||
- * should be small. */
|
||
- if (g_list_index (tracers, hook->tracer) >= 0)
|
||
+ /* CWE-407 fix: O(1) hash lookup replaces O(T) g_list_index() scan */
|
||
+ if (g_hash_table_contains (seen, hook->tracer))
|
||
continue;
|
||
+ g_hash_table_add (seen, hook->tracer);
|
||
tracers = g_list_prepend (tracers, gst_object_ref (hook->tracer));
|
||
}
|
||
}
|
||
g_list_free (h_list);
|
||
+ g_hash_table_destroy (seen);
|
||
|
||
return tracers;
|
||
}
|