37 lines
1.6 KiB
Diff
37 lines
1.6 KiB
Diff
# UNDF: UNDF-2026-000000231
|
|
Fixes pyramid-0001: RoutesMapper.connect() — list membership test + removal on route replace.
|
|
|
|
--- a/src/pyramid/urldispatch.py
|
|
+++ b/src/pyramid/urldispatch.py
|
|
|
|
@@ DEFECT pyramid-0001: RoutesMapper.connect() lines 57-58
|
|
|
|
class RoutesMapper:
|
|
def __init__(self):
|
|
self.routelist = []
|
|
self.static_routes = []
|
|
self.routes = {}
|
|
+ self._routeset = set() # FIX pyramid-0001: shadow set for O(1) membership
|
|
|
|
def connect(self, name, pattern, factory=None, predicates=(),
|
|
pregenerator=None, static=False):
|
|
if name in self.routes:
|
|
oldroute = self.routes[name]
|
|
- if oldroute in self.routelist: # O(n) linear scan — CWE-407
|
|
- self.routelist.remove(oldroute) # O(n) linear removal — CWE-407
|
|
+ if oldroute in self._routeset: # O(1) set lookup — fixed
|
|
+ self.routelist.remove(oldroute) # O(n) but confirmed to exist; acceptable
|
|
+ self._routeset.discard(oldroute)
|
|
|
|
route = Route(name, pattern, factory, predicates, pregenerator)
|
|
if not static:
|
|
self.routelist.append(route)
|
|
+ self._routeset.add(route) # maintain shadow set
|
|
else:
|
|
self.static_routes.append(route)
|
|
|
|
# NOTE: routelist must stay as a list for ordered route matching. The fix
|
|
# eliminates the O(n²) growth from the `in` check on replacement — the
|
|
# list.remove() itself remains O(n) but fires at most once per connect()
|
|
# call and is now guarded by an O(1) set check.
|
|
# For true O(1) removal: maintain route index dict; see pyramid-0002 pattern.
|