/** * CWE-407 unit test for WeeChat gui-nicklist.c nick dedup defect. * * Defect: gui_nicklist_add_nick() calls gui_nicklist_search_nick() which * performs O(N) linear scan through the nick linked list for each add. * When bulk-adding N nicks (e.g., joining a large IRC channel with * thousands of users), this yields O(N^2) total work. * * Fix: Maintain a hash table (name -> nick) per buffer for O(1) dedup. * * This test models the defect pattern in Java: * - Defective: LinkedList + contains() for dedup on each add * - Fixed: HashSet for O(1) dedup */ import java.util.*; public class WeechatNicklistDedupTest { /** Defective: linear scan through existing nicks for dedup */ static long defective(String[] nicks) { LinkedList nicklist = new LinkedList<>(); long ops = 0; for (String nick : nicks) { // gui_nicklist_search_nick_name: linear scan O(N) ops += nicklist.size(); if (!nicklist.contains(nick)) { nicklist.add(nick); } } return ops; } /** Fixed: hash set for O(1) dedup */ static long fixed(String[] nicks) { HashSet nickSet = new HashSet<>(); LinkedList nicklist = new LinkedList<>(); long ops = 0; for (String nick : nicks) { ops++; // O(1) hash lookup if (nickSet.add(nick)) { nicklist.add(nick); } } return ops; } public static void main(String[] args) { // Simulate joining a large IRC channel with 2000 unique users int N = 2000; String[] nicks = new String[N]; for (int i = 0; i < N; i++) { nicks[i] = "user_" + i; } long defOps = defective(nicks); long fixOps = fixed(nicks); double ratio = (double) defOps / fixOps; System.out.println("=== WeeChat gui-nicklist.c Nick Dedup Test ==="); System.out.println("Nicks added: " + N); System.out.println("Defective ops: " + defOps); System.out.println("Fixed ops: " + fixOps); System.out.printf("Ratio (defective/fixed): %.1fx%n", ratio); // Verify: defective should be significantly more expensive boolean pass = ratio >= 5.0; System.out.println("RESULT: " + (pass ? "PASS" : "FAIL") + " (ratio >= 5.0 required)"); if (!pass) System.exit(1); } }