gimp/inkscape: 2 new CWE-407 defects + all 5 MOADs scanned
gimp-0003: xcf_save_layer_props layer_sets O(L×S×I) MEDIUM 166.7x
- xcf_save_layer_props() called per layer rebuilds+scans each named
layer set item list on every XCF save
- Fix: pre-build GHashTable per set before layer loop
inkscape-0004: LayerManager::_rebuild() std::find O(L²×D) HIGH 166.7x
- Per layer, per ancestor: std::find on full layers vector
- Runs on every document load, every layer add/remove, every undo/redo
- Fix: unordered_set built once at start of _rebuild()
MOADs 0002/0003/0004/0005: CLEAN for both GIMP and Inkscape.
All 3/4 unit tests PASS respectively.
This commit is contained in:
parent
3e88e64a6a
commit
89de6df1d4
8 changed files with 264 additions and 5 deletions
|
|
@ -195,6 +195,47 @@ public class InkscapeTest {
|
|||
return ratio > 2.0;
|
||||
}
|
||||
|
||||
// ========== inkscape-0004: LayerManager::_rebuild() std::find O(L² × D) ==========
|
||||
|
||||
/** Defective: std::find(layers, curr) per ancestor per layer — O(L² × D) */
|
||||
static long layerManagerRebuildDefective(int numLayers, int depth) {
|
||||
long ops = 0;
|
||||
for (int l = 0; l < numLayers; l++) {
|
||||
for (int d = 0; d < depth; d++) {
|
||||
// std::find on vector: O(L) per ancestor check
|
||||
for (int k = 0; k < numLayers; k++) {
|
||||
ops++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/** Fixed: unordered_set built once; O(1) per ancestor check — O(L × D) */
|
||||
static long layerManagerRebuildFixed(int numLayers, int depth) {
|
||||
long ops = 0;
|
||||
// Build hash set: O(L)
|
||||
ops += numLayers;
|
||||
// Per layer, per ancestor: O(1) lookup
|
||||
for (int l = 0; l < numLayers; l++) {
|
||||
ops += depth;
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static boolean testLayerManagerRebuild() {
|
||||
int L = 200; // layers
|
||||
int D = 5; // nesting depth
|
||||
|
||||
long defect = layerManagerRebuildDefective(L, D);
|
||||
long fixed = layerManagerRebuildFixed(L, D);
|
||||
double ratio = (double) defect / fixed;
|
||||
|
||||
System.out.printf(" inkscape-0004 LayerManager::_rebuild: defect_ops=%d fixed_ops=%d ratio=%.1fx%n",
|
||||
defect, fixed, ratio);
|
||||
return ratio > 20.0;
|
||||
}
|
||||
|
||||
// ========== Main ==========
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
|
@ -204,15 +245,17 @@ public class InkscapeTest {
|
|||
boolean p1 = testGetLinkedRecursive();
|
||||
boolean p2 = testRaiseLower();
|
||||
boolean p3 = testGetAllItemsExclude();
|
||||
boolean p4 = testLayerManagerRebuild();
|
||||
|
||||
System.out.println();
|
||||
System.out.printf("inkscape-0001 getLinkedRecursive: %s%n", p1 ? "PASS" : "FAIL");
|
||||
System.out.printf("inkscape-0002 raise/lower: %s%n", p2 ? "PASS" : "FAIL");
|
||||
System.out.printf("inkscape-0003 getAllItems exclude: %s%n", p3 ? "PASS" : "FAIL");
|
||||
System.out.printf("inkscape-0001 getLinkedRecursive: %s%n", p1 ? "PASS" : "FAIL");
|
||||
System.out.printf("inkscape-0002 raise/lower: %s%n", p2 ? "PASS" : "FAIL");
|
||||
System.out.printf("inkscape-0003 getAllItems exclude: %s%n", p3 ? "PASS" : "FAIL");
|
||||
System.out.printf("inkscape-0004 LayerManager::_rebuild: %s%n", p4 ? "PASS" : "FAIL");
|
||||
|
||||
if (!p1 || !p2 || !p3) {
|
||||
if (!p1 || !p2 || !p3 || !p4) {
|
||||
System.exit(1);
|
||||
}
|
||||
System.out.println("\nAll 3 tests PASS");
|
||||
System.out.println("\nAll 4 tests PASS");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue