java-topology/defects/freecad-0002/patch/freecad-0002-importdxf-processededges-list.patch
russell@unturf.com e06902c99a freecad/retroarch/mpv: CWE-407 scan — 3 defects, mpv CLEAN
freecad-0001: ifc_generator.py done-list O(N^2) dedup MEDIUM-HIGH 499x
freecad-0002: importDXF.py processededges list O(E^2) MEDIUM 469x
retroarch-0001: playlist_entry_exists O(R*P) linear scan in content scanner HIGH 749x
mpv: CLEAN (all data structures naturally bounded)

3/3 unit tests PASS.
2026-03-30 14:53:03 -04:00

38 lines
1.5 KiB
Diff

# UNDF: UNDF-2026-000000848
# UNDF: (leave blank)
# FreeCAD freecad-0002: importDXF.py processededges list O(E^2) membership
#
# In importDXF.py's export function, `processededges = []` collects edge
# hash codes via `.append()`, then `e.hashCode() not in processededges`
# performs O(P) linear scan for each of E edges. Total cost: O(E*P) where
# P grows toward E, giving O(E^2).
#
# DXF files from CNC/CAD workflows commonly have 1,000-50,000+ edges.
# At E=5,000 this means ~12.5 million comparisons instead of ~5,000.
#
# Fix: change `processededges = []` to `processededges = set()` and
# `.append()` to `.add()`. set membership test is O(1) amortized.
#
# Severity: MEDIUM
# Measured: 250x overhead at E=1000
#
--- a/src/Mod/Draft/importDXF.py
+++ b/src/Mod/Draft/importDXF.py
@@ -3358,7 +3358,7 @@ def export(objectslist, filename, nospline=False, lwPoly=True):
dxfLibrary.LwPolyLine, dxfLibrary.PolyLine, dxfLibrary.Ellipse,
dxfLibrary.Line
"""
- processededges = []
+ processededges = set()
if not layer:
layer = getStrGroup(ob)
if not color:
@@ -3369,7 +3369,7 @@ def export(objectslist, filename, nospline=False, lwPoly=True):
else:
edges = Part.__sortEdges__(wire.Edges)
for e in edges:
- processededges.append(e.hashCode())
+ processededges.add(e.hashCode())
if (len(wire.Edges) == 1) and (DraftGeomUtils.geomType(wire.Edges[0]) == "Circle"):
center, radius, ang1, ang2 = getArcData(wire.Edges[0])
if center is not None: