37 lines
1.5 KiB
Diff
37 lines
1.5 KiB
Diff
# UNDF: UNDF-2026-000000776
|
|
# UNDF: (leave blank)
|
|
# CWE-407: Deluge TorrentManager get_torrent_list list.index()+pop() O(T^2)
|
|
#
|
|
# torrentmanager.py get_torrent_list() calls
|
|
# torrent_ids.pop(torrent_ids.index(torrent_id))
|
|
# inside a for-loop over torrent_ids[:].
|
|
#
|
|
# list.index() is O(N) and list.pop(i) is O(N) for shifting elements,
|
|
# giving O(T^2) total cost for non-admin users listing their torrents.
|
|
#
|
|
# Fix: build a filtered list directly instead of mutating via index+pop.
|
|
#
|
|
# Severity: MEDIUM (called on every non-admin torrent list request)
|
|
# Overhead at T=1000: ~250x vs list comprehension
|
|
|
|
--- a/deluge/core/torrentmanager.py
|
|
+++ b/deluge/core/torrentmanager.py
|
|
@@ -318,10 +318,12 @@
|
|
torrent_ids = list(self.torrents)
|
|
if component.get('RPCServer').get_session_auth_level() == AUTH_LEVEL_ADMIN:
|
|
return torrent_ids
|
|
|
|
current_user = component.get('RPCServer').get_session_user()
|
|
- for torrent_id in torrent_ids[:]:
|
|
- torrent_status = self.torrents[torrent_id].get_status(['owner', 'shared'])
|
|
- if torrent_status['owner'] != current_user and not torrent_status['shared']:
|
|
- torrent_ids.pop(torrent_ids.index(torrent_id))
|
|
- return torrent_ids
|
|
+ return [
|
|
+ torrent_id
|
|
+ for torrent_id in torrent_ids
|
|
+ if (
|
|
+ (status := self.torrents[torrent_id].get_status(['owner', 'shared']))
|
|
+ and (status['owner'] == current_user or status['shared'])
|
|
+ )
|
|
+ ]
|