Restructure openscad-0001 (was in wrong dir, Java test) into proper openscad-0001/ with TICKET.md and Python test. New openscad-0002 patches PolySetBuilder::endPolygon + appendPolySet std::find on colors_ vector -> unordered_map; Color4f already has std::hash. New openscad-0003 patches OctoPrint::requestApiKey and getJsonData to stop logging API responses verbatim (app_token + api responses exposed under --debug). MOADs 0002/0003/0005 CLEAN.
1.3 KiB
openscad-0002 — CWE-407 PolySetBuilder color dedup O(F*C) linear scan
MOAD: 0001 (CWE-407 Sedimentary Defect) Severity: MEDIUM Ratio: ~250x at F=1000, C=50 UNDF: (pending)
Location
src/geometry/PolySetBuilder.cc — endPolygon() and appendPolySet()
Pattern
PolySetBuilder maintains a std::vector<Color4f> colors_ for per-face color
deduplication. Two hot paths scan this vector with std::find:
-
endPolygon(color)— called once per polygon face. Scanscolors_to find the color index. O(C) per face. Total O(F*C) for F faces with C unique colors. -
appendPolySet(ps)— merges colors from another PolySet. IteratesnColorssource colors, scanningcolors_for each. O(nC * C).
For a colored model merging 50 source colors into a 1,000-face scene, this performs
~50,000 comparisons per appendPolySet call instead of 50.
Color4f already has std::hash<Color4f> defined in src/geometry/linalg.h.
No new infrastructure is needed — just use it.
Fix
Add a parallel std::unordered_map<Color4f, size_t> color_index_ in
PolySetBuilder to map each unique color to its index in colors_. Both
endPolygon and appendPolySet consult the map instead of scanning the vector.
Lookup drops from O(C) to O(1).
Patch
patch/openscad-0002-polysetbuilder-color-dedup.patch