136 lines
4.9 KiB
Java
136 lines
4.9 KiB
Java
/**
|
|
* CWE-407 simulation tests for Audacity defects.
|
|
*
|
|
* Each test simulates the defective O(N^2) pattern and the fixed O(N) pattern,
|
|
* measuring operation counts to confirm the quadratic vs linear behavior.
|
|
*/
|
|
import java.util.*;
|
|
|
|
public class AudacityTest {
|
|
|
|
static int ops;
|
|
|
|
// ========================================================================
|
|
// audacity-0001: TrackeditActionsController selectedTracks O(T*S)
|
|
// ========================================================================
|
|
|
|
/** Defective: for each track, linear scan of selectedTracks */
|
|
static List<Integer> filterTracksDefective(List<Integer> allTracks, List<Integer> selectedTracks) {
|
|
ops = 0;
|
|
List<Integer> result = new ArrayList<>();
|
|
for (int trackId : allTracks) {
|
|
boolean found = false;
|
|
for (int sel : selectedTracks) {
|
|
ops++;
|
|
if (sel == trackId) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (found) {
|
|
result.add(trackId);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/** Fixed: HashSet for O(1) membership */
|
|
static List<Integer> filterTracksFixed(List<Integer> allTracks, List<Integer> selectedTracks) {
|
|
ops = 0;
|
|
Set<Integer> selectedSet = new HashSet<>(selectedTracks);
|
|
List<Integer> result = new ArrayList<>();
|
|
for (int trackId : allTracks) {
|
|
ops++;
|
|
if (selectedSet.contains(trackId)) {
|
|
result.add(trackId);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static void testSelectedTracksFilter() {
|
|
int T = 500, S = 100;
|
|
List<Integer> allTracks = new ArrayList<>();
|
|
List<Integer> selectedTracks = new ArrayList<>();
|
|
for (int i = 0; i < T; i++) allTracks.add(i);
|
|
// Selected tracks are the last S tracks — worst case for linear scan
|
|
for (int i = T - S; i < T; i++) selectedTracks.add(i);
|
|
|
|
List<Integer> r1 = filterTracksDefective(allTracks, selectedTracks);
|
|
int defectOps = ops;
|
|
|
|
List<Integer> r2 = filterTracksFixed(allTracks, selectedTracks);
|
|
int fixedOps = ops;
|
|
|
|
assert r1.size() == r2.size() : "Results must match";
|
|
double ratio = (double) defectOps / fixedOps;
|
|
System.out.printf("audacity-0001 selectedTracks filter T=%d S=%d defect=%d fixed=%d ratio=%.1fx%n",
|
|
T, S, defectOps, fixedOps, ratio);
|
|
assert ratio > 10 : "Expected >10x ratio, got " + ratio;
|
|
}
|
|
|
|
// ========================================================================
|
|
// audacity-0002: WaveTrack::CanOffsetClips() O(I*M) moving clip scan
|
|
// ========================================================================
|
|
|
|
/** Defective: for each interval, linear scan of movingClips */
|
|
static boolean canOffsetClipsDefective(int[] intervals, int[] movingClips, double amount) {
|
|
ops = 0;
|
|
for (int interval : intervals) {
|
|
// Check if this interval is in movingClips
|
|
boolean isMoving = false;
|
|
for (int mc : movingClips) {
|
|
ops++;
|
|
if (mc == interval) {
|
|
isMoving = true;
|
|
break;
|
|
}
|
|
}
|
|
if (isMoving) continue;
|
|
// Would check overlap with moving clips here
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/** Fixed: HashSet for O(1) membership */
|
|
static boolean canOffsetClipsFixed(int[] intervals, int[] movingClips, double amount) {
|
|
ops = 0;
|
|
Set<Integer> movingSet = new HashSet<>();
|
|
for (int mc : movingClips) movingSet.add(mc);
|
|
for (int interval : intervals) {
|
|
ops++;
|
|
if (movingSet.contains(interval)) continue;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void testCanOffsetClips() {
|
|
int I = 500, M = 100;
|
|
// All unique intervals, none are moving — worst case
|
|
int[] intervals = new int[I];
|
|
int[] movingClips = new int[M];
|
|
for (int i = 0; i < I; i++) intervals[i] = i;
|
|
for (int i = 0; i < M; i++) movingClips[i] = I + i; // none match
|
|
|
|
canOffsetClipsDefective(intervals, movingClips, 1.0);
|
|
int defectOps = ops;
|
|
|
|
canOffsetClipsFixed(intervals, movingClips, 1.0);
|
|
int fixedOps = ops;
|
|
|
|
double ratio = (double) defectOps / fixedOps;
|
|
System.out.printf("audacity-0002 CanOffsetClips I=%d M=%d defect=%d fixed=%d ratio=%.1fx%n",
|
|
I, M, defectOps, fixedOps, ratio);
|
|
assert ratio > 10 : "Expected >10x ratio, got " + ratio;
|
|
}
|
|
|
|
// ========================================================================
|
|
// Main
|
|
// ========================================================================
|
|
|
|
public static void main(String[] args) {
|
|
testSelectedTracksFilter();
|
|
testCanOffsetClips();
|
|
System.out.println("ALL 2 TESTS PASSED");
|
|
}
|
|
}
|