diff --git a/UNDF-REGISTRY.json b/UNDF-REGISTRY.json index c62a69596..9e88c4d3e 100644 --- a/UNDF-REGISTRY.json +++ b/UNDF-REGISTRY.json @@ -895,5 +895,14 @@ "proton-0002": "UNDF-2026-000000894", "forgejo-0001-0001": "UNDF-2026-000000895", "snort3-0001-0001": "UNDF-2026-000000896", - "tryton-0001-0001": "UNDF-2026-000000897" + "tryton-0001-0001": "UNDF-2026-000000897", + "dosbox-x-0001": "UNDF-2026-000000898", + "dosbox-x-0002": "UNDF-2026-000000899", + "openfoam-0001-0001": "UNDF-2026-000000900", + "ppsspp-0001": "UNDF-2026-000000901", + "ppsspp-0002": "UNDF-2026-000000902", + "ppsspp-0003": "UNDF-2026-000000903", + "rpcs3-0001": "UNDF-2026-000000904", + "rpcs3-0002": "UNDF-2026-000000905", + "rpcs3-0003": "UNDF-2026-000000906" } diff --git a/defects/dosbox-x/patch/dosbox-x-0001-overlay-DOSnames-cache-vector-dedup.patch b/defects/dosbox-x/patch/dosbox-x-0001-overlay-DOSnames-cache-vector-dedup.patch index ad722bd9c..9006a613e 100644 --- a/defects/dosbox-x/patch/dosbox-x-0001-overlay-DOSnames-cache-vector-dedup.patch +++ b/defects/dosbox-x/patch/dosbox-x-0001-overlay-DOSnames-cache-vector-dedup.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000898 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1350 +1350 @@ diff --git a/defects/dosbox-x/patch/dosbox-x-0002-overlay-deleted-files-vector-scan.patch b/defects/dosbox-x/patch/dosbox-x-0002-overlay-deleted-files-vector-scan.patch index 27895563c..15870c326 100644 --- a/defects/dosbox-x/patch/dosbox-x-0002-overlay-deleted-files-vector-scan.patch +++ b/defects/dosbox-x/patch/dosbox-x-0002-overlay-deleted-files-vector-scan.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000899 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -1331 +1331 @@ diff --git a/defects/dosbox-x/test/DosboxXOverlayCacheTest.class b/defects/dosbox-x/test/DosboxXOverlayCacheTest.class new file mode 100644 index 000000000..ea6287ba5 Binary files /dev/null and b/defects/dosbox-x/test/DosboxXOverlayCacheTest.class differ diff --git a/defects/openfoam-0001/patch/openfoam-0001.patch b/defects/openfoam-0001/patch/openfoam-0001.patch new file mode 100644 index 000000000..f7de1b144 --- /dev/null +++ b/defects/openfoam-0001/patch/openfoam-0001.patch @@ -0,0 +1,82 @@ +# UNDF: UNDF-2026-000000900 +--- a/src/lagrangian/molecularDynamics/moleculeCloud/moleculeCloud.C ++++ b/src/lagrangian/molecularDynamics/moleculeCloud/moleculeCloud.C +@@ -274,7 +274,9 @@ + + { +- DynamicList molsToDelete; ++ // CWE-407: molsToDelete was a DynamicList scanned by findIndex() O(N) ++ // for each molecule pair, yielding O(pairs * D) where D = deletions. ++ // Fix: use HashSet for O(1) membership checks. ++ HashSet molsToDeleteSet; + + const labelListList& dil(il_.dil()); + +@@ -304,13 +306,13 @@ + || findIndex(pot_.removalOrder(), idJ) + < findIndex(pot_.removalOrder(), idI) + ) + { +- if (findIndex(molsToDelete, molJ) == -1) ++ if (!molsToDeleteSet.found(molJ)) + { +- molsToDelete.append(molJ); ++ molsToDeleteSet.insert(molJ); + } + } +- else if (findIndex(molsToDelete, molI) == -1) ++ else if (!molsToDeleteSet.found(molI)) + { +- molsToDelete.append(molI); ++ molsToDeleteSet.insert(molI); + } + } +@@ -336,13 +338,13 @@ + || findIndex(pot_.removalOrder(), idJ) + < findIndex(pot_.removalOrder(), idI) + ) + { +- if (findIndex(molsToDelete, molJ) == -1) ++ if (!molsToDeleteSet.found(molJ)) + { +- molsToDelete.append(molJ); ++ molsToDeleteSet.insert(molJ); + } + } +- else if (findIndex(molsToDelete, molI) == -1) ++ else if (!molsToDeleteSet.found(molI)) + { +- molsToDelete.append(molI); ++ molsToDeleteSet.insert(molI); + } + } +@@ -353,10 +355,10 @@ + +- forAll(molsToDelete, mTD) ++ forAllConstIter(HashSet, molsToDeleteSet, iter) + { +- deleteParticle(*(molsToDelete[mTD])); ++ deleteParticle(*iter.key()); + } + } + +@@ -419,9 +421,9 @@ + { +- if (findIndex(molsToDelete, molI) == -1) ++ if (!molsToDeleteSet.found(molI)) + { +- molsToDelete.append(molI); ++ molsToDeleteSet.insert(molI); + } + } + else if +@@ -437,9 +439,9 @@ + if (molI->origId() > molJ->origId()) + { +- if (findIndex(molsToDelete, molI) == -1) ++ if (!molsToDeleteSet.found(molI)) + { +- molsToDelete.append(molI); ++ molsToDeleteSet.insert(molI); + } + } diff --git a/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest$Molecule.class b/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest$Molecule.class new file mode 100644 index 000000000..0943e618c Binary files /dev/null and b/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest$Molecule.class differ diff --git a/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest.class b/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest.class new file mode 100644 index 000000000..3d8ec37de Binary files /dev/null and b/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest.class differ diff --git a/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest.java b/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest.java new file mode 100644 index 000000000..b16d41a38 --- /dev/null +++ b/defects/openfoam-0001/test/OpenFOAMMolsToDeleteDedupTest.java @@ -0,0 +1,110 @@ +/** + * CWE-407 unit test for OpenFOAM moleculeCloud.C molsToDelete dedup defect. + * + * Defect: moleculeCloud::removeHighEnergyOverlaps() uses + * DynamicList molsToDelete with findIndex() O(N) membership + * check inside a nested molecule-pair loop, yielding O(pairs * D) + * complexity where D = number of deletions. + * + * Fix: Replace DynamicList + findIndex with HashSet for O(1) membership. + * + * This test models the defect pattern in Java: + * - Defective: ArrayList + contains() for dedup in nested loop + * - Fixed: HashSet for O(1) dedup + */ +import java.util.*; + +public class OpenFOAMMolsToDeleteDedupTest { + + /** Simulate molecule with an id and origId */ + static class Molecule { + final int id; + final int origId; + Molecule(int id, int origId) { this.id = id; this.origId = origId; } + @Override public int hashCode() { return origId; } + @Override public boolean equals(Object o) { + return o instanceof Molecule && ((Molecule) o).origId == this.origId; + } + } + + /** Defective: ArrayList + contains() O(N) per check => O(pairs * D) */ + static int defective(List cellI, List cellJ, + List removalOrder) { + List molsToDelete = new ArrayList<>(); + long ops = 0; + for (Molecule molI : cellI) { + for (Molecule molJ : cellJ) { + ops++; + int idxI = removalOrder.indexOf(molI.id); + int idxJ = removalOrder.indexOf(molJ.id); + if (molI.id == molJ.id || idxJ < idxI) { + // findIndex(molsToDelete, molJ) == -1 + ops += molsToDelete.size(); + if (!molsToDelete.contains(molJ)) { + molsToDelete.add(molJ); + } + } else { + ops += molsToDelete.size(); + if (!molsToDelete.contains(molI)) { + molsToDelete.add(molI); + } + } + } + } + return (int) ops; + } + + /** Fixed: HashSet for O(1) membership => O(pairs) */ + static int fixed(List cellI, List cellJ, + List removalOrder) { + Set molsToDeleteSet = new HashSet<>(); + long ops = 0; + for (Molecule molI : cellI) { + for (Molecule molJ : cellJ) { + ops++; + int idxI = removalOrder.indexOf(molI.id); + int idxJ = removalOrder.indexOf(molJ.id); + if (molI.id == molJ.id || idxJ < idxI) { + ops++; // O(1) HashSet lookup + molsToDeleteSet.add(molJ); + } else { + ops++; + molsToDeleteSet.add(molI); + } + } + } + return (int) ops; + } + + public static void main(String[] args) { + // Simulate: 500 molecules in each cell, 3 molecule types + int N = 500; + List removalOrder = Arrays.asList(0, 1, 2); + Random rng = new Random(42); + + List cellI = new ArrayList<>(); + List cellJ = new ArrayList<>(); + for (int i = 0; i < N; i++) { + cellI.add(new Molecule(rng.nextInt(3), i)); + cellJ.add(new Molecule(rng.nextInt(3), N + i)); + } + + int defOps = defective(cellI, cellJ, removalOrder); + int fixOps = fixed(cellI, cellJ, removalOrder); + + double ratio = (double) defOps / fixOps; + + System.out.println("=== OpenFOAM moleculeCloud molsToDelete Dedup Test ==="); + System.out.println("Molecules per cell: " + N); + System.out.println("Defective ops: " + defOps); + System.out.println("Fixed ops: " + fixOps); + System.out.printf("Ratio (defective/fixed): %.1fx%n", ratio); + + // Verify: defective should be significantly more expensive + boolean pass = ratio >= 5.0; + System.out.println("RESULT: " + (pass ? "PASS" : "FAIL") + + " (ratio >= 5.0 required)"); + + if (!pass) System.exit(1); + } +} diff --git a/defects/ppsspp/patch/ppsspp-0001-kernel-thread-waitingThreads-dedup.patch b/defects/ppsspp/patch/ppsspp-0001-kernel-thread-waitingThreads-dedup.patch index e5f9fc0f6..95e216dbe 100644 --- a/defects/ppsspp/patch/ppsspp-0001-kernel-thread-waitingThreads-dedup.patch +++ b/defects/ppsspp/patch/ppsspp-0001-kernel-thread-waitingThreads-dedup.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000901 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2544 +2544 @@ diff --git a/defects/ppsspp/patch/ppsspp-0002-kernel-semaphore-waitingThreads-dedup.patch b/defects/ppsspp/patch/ppsspp-0002-kernel-semaphore-waitingThreads-dedup.patch index de223e1bb..64bd94b39 100644 --- a/defects/ppsspp/patch/ppsspp-0002-kernel-semaphore-waitingThreads-dedup.patch +++ b/defects/ppsspp/patch/ppsspp-0002-kernel-semaphore-waitingThreads-dedup.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000902 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -370 +370 @@ diff --git a/defects/ppsspp/patch/ppsspp-0003-irjit-bypage-block-removal.patch b/defects/ppsspp/patch/ppsspp-0003-irjit-bypage-block-removal.patch index 36c2177d5..fefb3450b 100644 --- a/defects/ppsspp/patch/ppsspp-0003-irjit-bypage-block-removal.patch +++ b/defects/ppsspp/patch/ppsspp-0003-irjit-bypage-block-removal.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000903 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -363,4 +363,5 @@ diff --git a/defects/ppsspp/test/PpssppKernelDedup.class b/defects/ppsspp/test/PpssppKernelDedup.class new file mode 100644 index 000000000..40191d5d2 Binary files /dev/null and b/defects/ppsspp/test/PpssppKernelDedup.class differ diff --git a/defects/rpcs3/patch/rpcs3-0001-spu-recompiler-preds-vector-dedup.patch b/defects/rpcs3/patch/rpcs3-0001-spu-recompiler-preds-vector-dedup.patch index 0b5defe92..16fc5e301 100644 --- a/defects/rpcs3/patch/rpcs3-0001-spu-recompiler-preds-vector-dedup.patch +++ b/defects/rpcs3/patch/rpcs3-0001-spu-recompiler-preds-vector-dedup.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000904 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -2899,4 +2899,5 @@ diff --git a/defects/rpcs3/patch/rpcs3-0002-spu-recompiler-calls-vector-dedup.patch b/defects/rpcs3/patch/rpcs3-0002-spu-recompiler-calls-vector-dedup.patch index cebe543ef..f044f7754 100644 --- a/defects/rpcs3/patch/rpcs3-0002-spu-recompiler-calls-vector-dedup.patch +++ b/defects/rpcs3/patch/rpcs3-0002-spu-recompiler-calls-vector-dedup.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000905 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -4842,4 +4842,5 @@ diff --git a/defects/rpcs3/patch/rpcs3-0003-savedata-blist-vector-find-in-sort.patch b/defects/rpcs3/patch/rpcs3-0003-savedata-blist-vector-find-in-sort.patch index 39767a96d..c383d2910 100644 --- a/defects/rpcs3/patch/rpcs3-0003-savedata-blist-vector-find-in-sort.patch +++ b/defects/rpcs3/patch/rpcs3-0003-savedata-blist-vector-find-in-sort.patch @@ -1,3 +1,4 @@ +# UNDF: UNDF-2026-000000906 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -1553,8 +1553,11 @@ diff --git a/defects/rpcs3/test/Rpcs3SpuRecompilerTest.class b/defects/rpcs3/test/Rpcs3SpuRecompilerTest.class new file mode 100644 index 000000000..6ca1c2409 Binary files /dev/null and b/defects/rpcs3/test/Rpcs3SpuRecompilerTest.class differ diff --git a/defects/tryton-0001/test/TrytonChangedValuesTest.class b/defects/tryton-0001/test/TrytonChangedValuesTest.class deleted file mode 100644 index c17a61358..000000000 Binary files a/defects/tryton-0001/test/TrytonChangedValuesTest.class and /dev/null differ