java-topology/defects/celery/patch/cel-0001-canvas-append-list-option-membership.patch

52 lines
2.3 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-000000025
From: agent-blackops <blackops@unturf.com>
Date: Fri, 27 Mar 2026 00:00:00 +0000
Subject: [PATCH] canvas: replace list membership test in append_to_list_option with set mirror
CWE-407: Algorithmic complexity via O(L) linear membership test inside chain
build loops. append_to_list_option() uses `value not in items` where items
is a plain list, and this method is called inside O(T) task loops and O(E)
errback loops during Chain construction, producing O(T×E×L) total comparisons.
Fix: store a parallel set alongside each list option for O(1) average membership
test. The list is preserved for ordering; the set is used only for deduplication
guard. Uses a dict-based shadow store keyed by the option key name.
Defect-Id: CEL-001
Severity: MEDIUM
CWE: CWE-407 (Inefficient Algorithmic Complexity)
---
celery/canvas.py | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/celery/canvas.py b/celery/canvas.py
index xxxxxxx..yyyyyyy 100644
--- a/celery/canvas.py
+++ b/celery/canvas.py
@@ -685,10 +685,18 @@ class Signature(dict):
def _with_list_option(self, key):
items = self.options.setdefault(key, [])
if not isinstance(items, MutableSequence):
items = self.options[key] = [items]
return items
+ def _with_list_option_set(self, key):
+ """Returns (list, set) pair; set mirrors list for O(1) membership."""
+ items = self._with_list_option(key)
+ shadow_key = f"__set_{key}"
+ items_set = self.options.setdefault(shadow_key, set())
+ if len(items_set) != len(items): # CWE-407 fix: sync if needed
+ items_set.clear()
+ items_set.update(id(v) for v in items)
+ return items, items_set
+
def append_to_list_option(self, key, value):
"""Appends the given value to the list at the given key in self.options."""
- items = self._with_list_option(key)
- if value not in items: # CWE-407: O(L) linear scan
+ items, items_set = self._with_list_option_set(key)
+ value_id = id(value)
+ if value_id not in items_set: # CWE-407 fix: O(1) average
items.append(value)
+ items_set.add(value_id)
return value