/** * CWE-407 simulation: Deluge TorrentManager list.index()+pop() inside loop. * * Simulates get_torrent_list() with the defective O(T^2) list.index()+pop() * pattern vs the fixed O(T) list comprehension approach. * * deluge-0002: torrentmanager list.index()+pop() in loop */ import java.util.*; public class DelugeTorrentManagerTest { /** DEFECTIVE: list.index()+pop() inside loop — O(T^2) */ static List getTorrentListDefective(List allIds, Set ownedIds) { List ids = new ArrayList<>(allIds); for (String tid : new ArrayList<>(ids)) { if (!ownedIds.contains(tid)) { int idx = ids.indexOf(tid); // O(N) scan if (idx >= 0) { ids.remove(idx); // O(N) shift } } } return ids; } /** FIXED: list comprehension — O(T) */ static List getTorrentListFixed(List allIds, Set ownedIds) { List result = new ArrayList<>(); for (String tid : allIds) { if (ownedIds.contains(tid)) { result.add(tid); } } return result; } public static void main(String[] args) { int[] sizes = {100, 500, 1000, 2000}; System.out.println("=== Deluge TorrentManager CWE-407 Test (deluge-0002) ==="); System.out.printf("%-8s %12s %12s %8s %s%n", "T", "Defective(ms)", "Fixed(ms)", "Ratio", "Status"); boolean allPass = true; for (int T : sizes) { // Setup: T torrents, 30% owned by current user List allIds = new ArrayList<>(); Set ownedIds = new HashSet<>(); for (int i = 0; i < T; i++) { String id = "torrent-" + i; allIds.add(id); if (i % 3 == 0) { ownedIds.add(id); } } // Warmup for (int w = 0; w < 3; w++) { getTorrentListDefective(allIds, ownedIds); getTorrentListFixed(allIds, ownedIds); } // Benchmark defective int iters = Math.max(10, 50000 / T); long t0 = System.nanoTime(); for (int i = 0; i < iters; i++) { getTorrentListDefective(allIds, ownedIds); } long defectiveNs = System.nanoTime() - t0; // Benchmark fixed t0 = System.nanoTime(); for (int i = 0; i < iters; i++) { getTorrentListFixed(allIds, ownedIds); } long fixedNs = System.nanoTime() - t0; double ratio = (double) defectiveNs / fixedNs; boolean pass = ratio > 2.0; allPass &= pass; // Correctness check List dResult = getTorrentListDefective(allIds, ownedIds); List fResult = getTorrentListFixed(allIds, ownedIds); boolean correct = dResult.equals(fResult); allPass &= correct; System.out.printf("%-8d %12.2f %12.2f %8.1fx %s%s%n", T, defectiveNs / 1e6 / iters, fixedNs / 1e6 / iters, ratio, pass ? "PASS" : "FAIL", correct ? "" : " MISMATCH"); } System.out.println("\nOverall: " + (allPass ? "PASS" : "FAIL")); System.exit(allPass ? 0 : 1); } }