darktable+scribus: CWE-407 scan — 6 defects (3 darktable, 3 scribus)
darktable-0001: map_locations image diff g_list_find O(N*M) MEDIUM 375x darktable-0002: tags _tag_add_tags_to_list g_list_find O(T*L) MEDIUM 375x darktable-0003: map view clustering g_list_find(sel_imgs) O(I²×S) HIGH 160x scribus-0001: getSortedStyleList retList.contains O(N²) MEDIUM 167x (×4 copies) scribus-0002: getUsedPatterns results.contains O(I×R) MEDIUM 98x scribus-0003: Selection::addItems m_SelList.contains O(N×M) MEDIUM 2100x
This commit is contained in:
parent
f4593ef84a
commit
13db08af50
10 changed files with 776 additions and 0 deletions
162
defects/darktable/unit/DarktableTest.java
Normal file
162
defects/darktable/unit/DarktableTest.java
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* CWE-407 simulation tests for darktable defects.
|
||||
*
|
||||
* darktable-0001: map_locations image diff via g_list_find O(N*M)
|
||||
* darktable-0002: _tag_add_tags_to_list dedup via g_list_find O(T*L)
|
||||
* darktable-0003: map view clustering sel_imgs g_list_find inside O(I*J) loop
|
||||
*/
|
||||
public class DarktableTest {
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// darktable-0001: map_locations symmetric diff O(N*M) vs O(N+M)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/** Defective: g_list_find inside loop — O(N*M) */
|
||||
static int mapLocationDiffDefective(List<Integer> oldImgs, List<Integer> newImgs) {
|
||||
int ops = 0;
|
||||
// detach old not in new
|
||||
for (int id : oldImgs) {
|
||||
for (int nid : newImgs) { ops++; if (nid == id) break; }
|
||||
}
|
||||
// attach new not in old
|
||||
for (int id : newImgs) {
|
||||
for (int oid : oldImgs) { ops++; if (oid == id) break; }
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/** Fixed: GHashTable for O(1) lookup — O(N+M) */
|
||||
static int mapLocationDiffFixed(List<Integer> oldImgs, List<Integer> newImgs) {
|
||||
int ops = 0;
|
||||
Set<Integer> newSet = new HashSet<>(newImgs); ops += newImgs.size();
|
||||
for (int id : oldImgs) { newSet.contains(id); ops++; }
|
||||
Set<Integer> oldSet = new HashSet<>(oldImgs); ops += oldImgs.size();
|
||||
for (int id : newImgs) { oldSet.contains(id); ops++; }
|
||||
return ops;
|
||||
}
|
||||
|
||||
static void testMapLocationDiff() {
|
||||
int N = 1000;
|
||||
List<Integer> oldImgs = new ArrayList<>();
|
||||
List<Integer> newImgs = new ArrayList<>();
|
||||
for (int i = 0; i < N; i++) { oldImgs.add(i); newImgs.add(i + N / 2); }
|
||||
|
||||
int defectOps = mapLocationDiffDefective(oldImgs, newImgs);
|
||||
int fixedOps = mapLocationDiffFixed(oldImgs, newImgs);
|
||||
double ratio = (double) defectOps / fixedOps;
|
||||
|
||||
System.out.printf("darktable-0001 map_locations diff: defect=%d fixed=%d ratio=%.1fx%n",
|
||||
defectOps, fixedOps, ratio);
|
||||
assert ratio > 10 : "Expected >10x ratio, got " + ratio;
|
||||
System.out.println(" PASS");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// darktable-0002: tag dedup via g_list_find O(T*L) ≈ O(N²)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/** Defective: linear scan dedup */
|
||||
static int tagAddToListDefective(List<Integer> existingTags, List<Integer> newTags) {
|
||||
int ops = 0;
|
||||
List<Integer> list = new ArrayList<>(existingTags);
|
||||
for (int tag : newTags) {
|
||||
boolean found = false;
|
||||
for (int t : list) { ops++; if (t == tag) { found = true; break; } }
|
||||
if (!found) list.add(tag);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/** Fixed: HashSet companion */
|
||||
static int tagAddToListFixed(List<Integer> existingTags, List<Integer> newTags) {
|
||||
int ops = 0;
|
||||
Set<Integer> seen = new HashSet<>(existingTags); ops += existingTags.size();
|
||||
for (int tag : newTags) {
|
||||
ops++;
|
||||
if (!seen.contains(tag)) { seen.add(tag); }
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static void testTagAddToList() {
|
||||
int N = 500;
|
||||
List<Integer> existing = new ArrayList<>();
|
||||
List<Integer> toAdd = new ArrayList<>();
|
||||
// all unique — worst case for dedup
|
||||
for (int i = 0; i < N; i++) existing.add(i);
|
||||
for (int i = N; i < 2 * N; i++) toAdd.add(i);
|
||||
|
||||
int defectOps = tagAddToListDefective(existing, toAdd);
|
||||
int fixedOps = tagAddToListFixed(existing, toAdd);
|
||||
double ratio = (double) defectOps / fixedOps;
|
||||
|
||||
System.out.printf("darktable-0002 tag dedup: defect=%d fixed=%d ratio=%.1fx%n",
|
||||
defectOps, fixedOps, ratio);
|
||||
assert ratio > 50 : "Expected >50x ratio, got " + ratio;
|
||||
System.out.println(" PASS");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// darktable-0003: map view sel_imgs inside O(I*J) clustering loop
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/** Defective: g_list_find(sel_imgs, imgid) inside nested I×J loop — O(I²×S) */
|
||||
static long mapViewClusterDefective(int imgCount, List<Integer> selImgs, int[] clusterIds) {
|
||||
long ops = 0;
|
||||
for (int i = 0; i < imgCount; i++) {
|
||||
int group = clusterIds[i];
|
||||
for (int j = 0; j < imgCount; j++) {
|
||||
if (clusterIds[j] == group) {
|
||||
// linear scan of sel_imgs
|
||||
for (int s : selImgs) { ops++; if (s == j) break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/** Fixed: HashSet for O(1) selection check — O(I²+S) */
|
||||
static long mapViewClusterFixed(int imgCount, List<Integer> selImgs, int[] clusterIds) {
|
||||
long ops = 0;
|
||||
Set<Integer> selSet = new HashSet<>(selImgs); ops += selImgs.size();
|
||||
for (int i = 0; i < imgCount; i++) {
|
||||
int group = clusterIds[i];
|
||||
for (int j = 0; j < imgCount; j++) {
|
||||
if (clusterIds[j] == group) {
|
||||
selSet.contains(j); ops++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static void testMapViewCluster() {
|
||||
int I = 500;
|
||||
int S = 200;
|
||||
List<Integer> selImgs = new ArrayList<>();
|
||||
for (int i = 0; i < S; i++) selImgs.add(i);
|
||||
// All in one cluster — worst case
|
||||
int[] clusterIds = new int[I];
|
||||
Arrays.fill(clusterIds, 1);
|
||||
|
||||
long defectOps = mapViewClusterDefective(I, selImgs, clusterIds);
|
||||
long fixedOps = mapViewClusterFixed(I, selImgs, clusterIds);
|
||||
double ratio = (double) defectOps / fixedOps;
|
||||
|
||||
System.out.printf("darktable-0003 map view cluster sel: defect=%d fixed=%d ratio=%.1fx%n",
|
||||
defectOps, fixedOps, ratio);
|
||||
assert ratio > 10 : "Expected >10x ratio, got " + ratio;
|
||||
System.out.println(" PASS");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
public static void main(String[] args) {
|
||||
testMapLocationDiff();
|
||||
testTagAddToList();
|
||||
testMapViewCluster();
|
||||
System.out.println("\nAll 3 darktable CWE-407 tests PASSED.");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue