import java.util.*; /** * CWE-407 simulation tests for Apache Superset defects. * * superset-0001: SecurityManager._get_pvms_from_builtin_role pvm dedup O(Regex*PVMs*R) * superset-0002: DashboardDAO.update_native_filters_config filter dedup O(M*U) * superset-0003: import_datasource metric/column dedup O(N^2) list rebuild */ public class SupersetTest { // ---- superset-0001: builtin role PVM dedup ---- static List getBuiltinRolePvmsBefore(int numRegex, int numPvms) { // Simulates: for pvm_regex in regexes: for pvm in all_pvms: if pvm not in result_list List result = new ArrayList<>(); for (int r = 0; r < numRegex; r++) { for (int p = 0; p < numPvms; p++) { // Simulate regex match (every other one matches) if ((r + p) % 2 == 0) { if (!result.contains(p)) { // O(N) list scan result.add(p); } } } } return result; } static List getBuiltinRolePvmsAfter(int numRegex, int numPvms) { List result = new ArrayList<>(); Set seen = new HashSet<>(); for (int r = 0; r < numRegex; r++) { for (int p = 0; p < numPvms; p++) { if ((r + p) % 2 == 0) { if (seen.add(p)) { // O(1) set lookup result.add(p); } } } } return result; } static boolean testSuperset0001() { int numRegex = 20, numPvms = 2000; long t0 = System.nanoTime(); List before = getBuiltinRolePvmsBefore(numRegex, numPvms); long tBefore = System.nanoTime() - t0; t0 = System.nanoTime(); List after = getBuiltinRolePvmsAfter(numRegex, numPvms); long tAfter = System.nanoTime() - t0; boolean sameResult = before.equals(after); double ratio = (double) tBefore / tAfter; System.out.printf("superset-0001: before=%,dns after=%,dns ratio=%.1fx match=%b%n", tBefore, tAfter, ratio, sameResult); return sameResult && ratio > 2.0; } // ---- superset-0002: dashboard filter dedup ---- static List filterDedupBefore(List existing, List modified) { List> updated = new ArrayList<>(); for (String id : existing) { Map m = new HashMap<>(); m.put("id", id); updated.add(m); } for (String newId : modified) { // Rebuild list comprehension every iteration: O(M*U) List updatedIds = new ArrayList<>(); for (Map f : updated) { updatedIds.add(f.get("id")); } if (!updatedIds.contains(newId)) { Map m = new HashMap<>(); m.put("id", newId); updated.add(m); } } List result = new ArrayList<>(); for (Map f : updated) result.add(f.get("id")); return result; } static List filterDedupAfter(List existing, List modified) { List> updated = new ArrayList<>(); Set updatedIds = new HashSet<>(); for (String id : existing) { Map m = new HashMap<>(); m.put("id", id); updated.add(m); updatedIds.add(id); } for (String newId : modified) { if (!updatedIds.contains(newId)) { // O(1) Map m = new HashMap<>(); m.put("id", newId); updated.add(m); updatedIds.add(newId); } } List result = new ArrayList<>(); for (Map f : updated) result.add(f.get("id")); return result; } static boolean testSuperset0002() { int N = 2000; List existing = new ArrayList<>(); List modified = new ArrayList<>(); for (int i = 0; i < N; i++) { existing.add("filter-" + i); modified.add("filter-" + (N + i)); // all new } long t0 = System.nanoTime(); List before = filterDedupBefore(existing, modified); long tBefore = System.nanoTime() - t0; t0 = System.nanoTime(); List after = filterDedupAfter(existing, modified); long tAfter = System.nanoTime() - t0; boolean sameSize = before.size() == after.size(); double ratio = (double) tBefore / tAfter; System.out.printf("superset-0002: before=%,dns after=%,dns ratio=%.1fx match=%b%n", tBefore, tAfter, ratio, sameSize); return sameSize && ratio > 2.0; } // ---- superset-0003: dataset import metric/column dedup ---- static List importDedupBefore(List importNames) { List datasourceNames = new ArrayList<>(); for (String name : importNames) { // Rebuild list every iteration: O(N^2) List existing = new ArrayList<>(datasourceNames); if (!existing.contains(name)) { datasourceNames.add(name); } } return datasourceNames; } static List importDedupAfter(List importNames) { List datasourceNames = new ArrayList<>(); Set seen = new HashSet<>(); for (String name : importNames) { if (seen.add(name)) { // O(1) datasourceNames.add(name); } } return datasourceNames; } static boolean testSuperset0003() { int N = 5000; List importNames = new ArrayList<>(); for (int i = 0; i < N; i++) { importNames.add("metric-" + i); } long t0 = System.nanoTime(); List before = importDedupBefore(importNames); long tBefore = System.nanoTime() - t0; t0 = System.nanoTime(); List after = importDedupAfter(importNames); long tAfter = System.nanoTime() - t0; boolean sameResult = before.equals(after); double ratio = (double) tBefore / tAfter; System.out.printf("superset-0003: before=%,dns after=%,dns ratio=%.1fx match=%b%n", tBefore, tAfter, ratio, sameResult); return sameResult && ratio > 2.0; } public static void main(String[] args) { // Warmup for (int i = 0; i < 3; i++) { getBuiltinRolePvmsBefore(5, 100); getBuiltinRolePvmsAfter(5, 100); filterDedupBefore(List.of("a"), List.of("b")); filterDedupAfter(List.of("a"), List.of("b")); importDedupBefore(List.of("a", "b")); importDedupAfter(List.of("a", "b")); } boolean p1 = testSuperset0001(); boolean p2 = testSuperset0002(); boolean p3 = testSuperset0003(); System.out.println(); System.out.println("superset-0001 (security PVM dedup): " + (p1 ? "PASS" : "FAIL")); System.out.println("superset-0002 (dashboard filter dedup): " + (p2 ? "PASS" : "FAIL")); System.out.println("superset-0003 (dataset import dedup): " + (p3 ? "PASS" : "FAIL")); if (!p1 || !p2 || !p3) System.exit(1); } }