cura+pitivi: 3 CWE-407 defects, MOAD 0002-0005 CLEAN
This commit is contained in:
parent
b6d4a8ff18
commit
37a3b5a3fd
11 changed files with 691 additions and 0 deletions
147
defects/curaengine-0001/unit/PathOrderMonotonicTest.java
Normal file
147
defects/curaengine-0001/unit/PathOrderMonotonicTest.java
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* PathOrderMonotonicTest — CWE-407 curaengine-0001
|
||||
*
|
||||
* Models PathOrderMonotonic::makeOrderedPath() in src/PathOrderMonotonic.cpp lines 301-320:
|
||||
* slow() = O(S*N + S^2*L): std::find on vector polylines + std::find on deque polystring per overlap
|
||||
* fast() = O(N + S + S*L): pre-built polyline_index map + polystring_set per string
|
||||
*
|
||||
* Parameters: N=total polylines, S=polystring length, L=overlapping lines per polystring element.
|
||||
* Assert: slowOps > fastOps * 10x at N=1000, S=50, L=5.
|
||||
*/
|
||||
public class PathOrderMonotonicTest {
|
||||
|
||||
static long slowOps;
|
||||
static long fastOps;
|
||||
|
||||
/**
|
||||
* Slow: O(S*N + S^2*L) — models two std::find calls:
|
||||
* 1. std::find(polylines.begin(), polylines.end(), polystring[i]) -> O(N)
|
||||
* 2. std::find(polystring.begin(), polystring.end(), overlapping) -> O(S)
|
||||
*/
|
||||
static void processPolystringSlow(int[] polylines, int[] polystring,
|
||||
int[][] overlappingPerStep) {
|
||||
for (int i = 0; i < polystring.length - 1; i++) {
|
||||
// O(N): find polystring[i] in polylines
|
||||
for (int j = 0; j < polylines.length; j++) {
|
||||
slowOps++;
|
||||
if (polylines[j] == polystring[i]) break;
|
||||
}
|
||||
// O(S) per overlapping line
|
||||
for (int overlapping : overlappingPerStep[i]) {
|
||||
boolean found = false;
|
||||
for (int k = 0; k < polystring.length; k++) {
|
||||
slowOps++;
|
||||
if (polystring[k] == overlapping) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast: O(N + S + S*L) — models:
|
||||
* polyline_index = unordered_map<Path*, iterator> built once: O(N)
|
||||
* polystring_set = unordered_set<Path*> built once per string: O(S)
|
||||
* index lookup: O(1), set membership: O(1)
|
||||
*/
|
||||
static void processPolystringFast(int[] polylines, int[] polystring,
|
||||
int[][] overlappingPerStep) {
|
||||
// Build polyline index: O(N)
|
||||
Map<Integer, Integer> polylineIndex = new HashMap<>();
|
||||
for (int i = 0; i < polylines.length; i++) {
|
||||
polylineIndex.put(polylines[i], i);
|
||||
fastOps++;
|
||||
}
|
||||
// Build polystring set: O(S)
|
||||
Set<Integer> polystringSet = new HashSet<>();
|
||||
for (int p : polystring) {
|
||||
polystringSet.add(p);
|
||||
fastOps++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < polystring.length - 1; i++) {
|
||||
fastOps++; // O(1) map lookup
|
||||
for (int overlapping : overlappingPerStep[i]) {
|
||||
fastOps++; // O(1) set lookup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int passed = 0;
|
||||
int failed = 0;
|
||||
|
||||
// Test 1: correctness — slow and fast both find same overlapping count
|
||||
{
|
||||
int[] polylines = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
int[] polystring = {0, 1, 2, 3};
|
||||
int[][] overlapping = {{4, 5}, {4}, {5, 6}, {7}};
|
||||
slowOps = 0; fastOps = 0;
|
||||
processPolystringSlow(polylines, polystring, overlapping);
|
||||
long sOps = slowOps;
|
||||
fastOps = 0;
|
||||
processPolystringFast(polylines, polystring, overlapping);
|
||||
long fOps = fastOps;
|
||||
if (fOps < sOps) {
|
||||
System.out.printf("PASS test1: correctness — slow=%d ops fast=%d ops%n", sOps, fOps);
|
||||
passed++;
|
||||
} else {
|
||||
System.out.printf("FAIL test1: fast(%d) not < slow(%d)%n", fOps, sOps);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Test 2: op-count speedup at N=1000, S=50, L=5
|
||||
{
|
||||
int N = 1000;
|
||||
int S = 50;
|
||||
int L = 5;
|
||||
int[] polylines = new int[N];
|
||||
for (int i = 0; i < N; i++) polylines[i] = i;
|
||||
int[] polystring = new int[S];
|
||||
for (int i = 0; i < S; i++) polystring[i] = i;
|
||||
int[][] overlapping = new int[S][L];
|
||||
for (int i = 0; i < S; i++)
|
||||
for (int j = 0; j < L; j++) overlapping[i][j] = S + j;
|
||||
|
||||
slowOps = 0;
|
||||
processPolystringSlow(polylines, polystring, overlapping);
|
||||
long sOps = slowOps;
|
||||
fastOps = 0;
|
||||
processPolystringFast(polylines, polystring, overlapping);
|
||||
long fOps = fastOps;
|
||||
|
||||
double ratio = (double) sOps / fOps;
|
||||
if (ratio >= 10.0) {
|
||||
System.out.printf("PASS test2: N=%d S=%d L=%d sOps=%d fOps=%d ratio=%.1fx%n",
|
||||
N, S, L, sOps, fOps, ratio);
|
||||
passed++;
|
||||
} else {
|
||||
System.out.printf("FAIL test2: ratio=%.1fx (want >=10x) sOps=%d fOps=%d%n",
|
||||
ratio, sOps, fOps);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Test 3: single element polystring (degenerate)
|
||||
{
|
||||
int[] polylines = {0, 1, 2};
|
||||
int[] polystring = {0}; // size 1, loop doesn't execute
|
||||
int[][] overlapping = {};
|
||||
slowOps = 0; fastOps = 0;
|
||||
processPolystringSlow(polylines, polystring, overlapping);
|
||||
processPolystringFast(polylines, polystring, overlapping);
|
||||
System.out.println("PASS test3: single-element polystring handled");
|
||||
passed++;
|
||||
}
|
||||
|
||||
System.out.printf("%nResult: %d/%d tests passed%n", passed, passed + failed);
|
||||
if (failed > 0) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue