Compare commits

..
4 Commits
Author SHA1 Message Date
Clifford Yapp 6f2c488631 Integrate main command changes with buopt schemas 2026-09-29 17:58:27 -04:00
Clifford Yapp 45ca158a23 Add cmd survey 2026-09-29 17:12:23 -04:00
Clifford Yapp 986a660a14 stash docs 2026-09-29 17:12:23 -04:00
Clifford Yapp d59f9fb5ac Improve command option handling and tab completion
Also autogenerate command help messages rather than hard coding
2026-09-29 17:12:23 -04:00
1499 changed files with 91722 additions and 98923 deletions
+2 -2
View File
@@ -384,7 +384,7 @@ jobs:
osx:
name: macOS Clang
needs: [linux]
runs-on: macos-15
runs-on: macos-14
strategy:
fail-fast: true
steps:
@@ -403,7 +403,7 @@ jobs:
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: macos-15-${{ runner.arch }}-release
platform-channel: macos-14-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
+1 -1
View File
@@ -177,7 +177,7 @@ jobs:
osx_bext:
name: macOS - BRL-CAD bext build
needs: [linux_bext]
runs-on: macos-15
runs-on: macos-14
strategy:
fail-fast: true
if: ${{ !cancelled() }}
+1 -1
View File
@@ -231,7 +231,7 @@ set(CMAKE_FIND_USE_PACKAGE_REGISTRY FALSE)
# Prepare to manage and build BRL-CAD's external dependencies. Specifies a
# specific commit hash to use in the 'bext' repository.
include(BRLCAD_ExternalDeps)
brlcad_bext_init(f8245e0bb31c5f96b17d8d32a988b9a7679fe4b9)
brlcad_bext_init(0682795bcfe34644c17e5a4bdd0225c76f6bdc98)
#---------------------------------------------------------------------
# Define various utilities.
+49 -83
View File
@@ -10,106 +10,80 @@ descriptive text that emphasizes or further describes significant
changes made. See document footer for additional details.
----------------------------------------------------------------------
--- 2026-10-0X Release 7.46.0 ---
--- 20XX-XX-XX Release 7.46.0 ---
----------------------------------------------------------------------
This release expands geometry conversion and improves modeling
reliability. STEP support adds AP203e2, AP214, and AP242
import/export, native CSG round trips, and AP242 product and
manufacturing information (PMI) import. IGES and JT conversion is
expanded, and new OpenSCAD CSG import/export tools are available.
Facetization is more reliable, NMG solid ray tracing is 10-20 times
faster, CSG ray tracing is faster, and BoT, DSP, and point-cloud ray
intersections are corrected. MGED gains numerous fixes to primitive,
sketch, and combination editing, drawing, dialogs, and preferences.
New tools support object nesting with arrange, building generation
with mkbuilding, annotation editing, and primitive repair. Geometry
analysis, image utilities, Windows support, documentation, and bundled
dependencies also receive substantial updates.
* fixed inside BoT rays, DSP surface normals, PNTS bounds - Cliff Yapp
* improved mged fallback HTML manual viewer - Cliff Yapp
* fixed gqa undefined densities and exit status - Chris McGregor
* added ARBN support to the mged inside command - Cliff Yapp
* improved HYP neck-ratio labels and BoT face selection - Cliff Yapp
* fixed mged view panning, edit rotation, & ray queries - Cliff Yapp
* preserved ARB, CLINE, TGC, & extrusion geometry edits - Cliff Yapp
* restored mged command prompt focus at GUI startup - Cliff Yapp
* improved pixscale & bwscale scaling and image piping - Sean Morrison
* restored pixdiff behavior on .pix, added -b for .bw - Sean Morrison
* improved facetize fallback methods and reliability - Cliff Yapp
* updated mged and Archer for Tcl 8.6.18 and Itcl/Itk 4 - Cliff Yapp
* updated MGED and Archer for Tcl 8.6.18 and Itcl/Itk 4 - Cliff Yapp
* fixed writes to fileless geometry databases - Cliff Yapp
* fixed nastran-g handling of large property IDs - Rupesh, Cliff Yapp
* fixed dxf-g invalid polyface idx crash - Meghna45-code, Cliff Yapp
* fixed dxf-g invalid polyface index crashes - Meghna45-code, Cliff Yapp
* fixed Archer primitive editors under Itcl 4 - Cliff Yapp
* fixed Archer shutdown menu cleanup errors - Cliff Yapp
* fixed MGED Build Pattern dialog under Itcl 4 - Cliff Yapp
* fixed TclCAD framebuffer listing and deletion - Cliff Yapp
* fixed mged Build Pattern progress updates - Cliff Yapp
* fixed mged search -exec reentry and Ctrl-C crashes - Cliff Yapp
* fixed mged asynchronous commands and clone progress - Cliff Yapp
* accelerated large and repeated mged path drawing - Cliff Yapp
* fixed MGED Build Pattern progress updates - Cliff Yapp
* fixed MGED search -exec reentry and Ctrl-C crashes - Cliff Yapp
* fixed MGED asynchronous commands and clone progress - Cliff Yapp
* accelerated large and repeated MGED path drawing - Cliff Yapp
* fixed ARB7 inside solid construction - Cliff Yapp
* fixed direct ARB face and edge-direction editing - Cliff Yapp
* fixed rtwizard startup with framebuffer contention - Cliff Yapp
* fixed Archer annotation line display updates - Cliff Yapp
* fixed Archer sketch scale drift in non-mm databases - Cliff Yapp
* fixed toggle arrow callbacks during setup - Cliff Yapp
* fixed Tcl dialogs with multi-word titles and msgs - Cliff Yapp
* fixed Tcl dialogs with multi-word titles and messages - Cliff Yapp
* fixed Archer Tank Wizard gun generation - Cliff Yapp
* fixed mged and Archer sketch arc tangency editing - Cliff Yapp
* fixed MGED and Archer sketch arc tangency editing - Cliff Yapp
* fixed Archer ARB4 point 3 editing - Cliff Yapp
* fixed ARB4 storage from make and mk_arb4 - Cliff Yapp
* fixed ARB4 and ARB6 center point calculations - Cliff Yapp
* fixed concurrent mged and rtwizard framebuffer use - Cliff Yapp
* fixed mged ShotVis editing and reload failures - Cliff Yapp
* fixed concurrent MGED and rtwizard framebuffer use - Cliff Yapp
* fixed MGED ShotVis editing and reload failures - Cliff Yapp
* fixed Tcl widget geometry and selection defects - Cliff Yapp
* fixed mged BoT editor property handling - Cliff Yapp
* fixed mged LOD dialog and adaptive BoT wireframes - Cliff Yapp
* fixed mged Plot, PostScript, and manual launch tools - Cliff Yapp
* fixed mged Overlap Tool multi-object result handling - Cliff Yapp
* fixed MGED BoT editor property handling - Cliff Yapp
* fixed MGED LOD dialog and adaptive BoT wireframes - Cliff Yapp
* fixed MGED Plot, PostScript, and manual launch tools - Cliff Yapp
* fixed MGED Overlap Tool multi-object result handling - Cliff Yapp
* eliminated 16-fold redundant gchecker grid analysis - Cliff Yapp
* fixed submodel transforms & relative database paths - Sean Morrison
* fixed Archer tree handling for names with spaces - Cliff Yapp
* fixed Archer tree handling for object names with spaces - Cliff Yapp
* fixed RtWizard multi-object edge occlusion handling - Cliff Yapp
* fixed RtWizard title, About, and preference handling - Cliff Yapp
* fixed mged startup file false legacy-syntax warnings - Cliff Yapp
* fixed mged saved-view deletion and collaboration sync - Cliff Yapp
* fixed mged font preferences apply and persistence - Cliff Yapp
* fixed MGED startup file false legacy-syntax warnings - Cliff Yapp
* fixed MGED saved-view deletion and collaboration sync - Cliff Yapp
* fixed MGED font preferences apply and persistence - Cliff Yapp
* fixed Archer combination edits changing Boolean trees - Cliff Yapp
* fixed Archer command-line help startup crash - Cliff Yapp
* fixed mged Geometry Browser menu and close behavior - Cliff Yapp
* fixed mged collaboration view unshare crash - Cliff Yapp
* added override for Archer's preference file location - Cliff Yapp
* fixed MGED Geometry Browser menu and close behavior - Cliff Yapp
* fixed MGED collaboration view unshare crash - Cliff Yapp
* added an override for Archer's preference file location - Cliff Yapp
* fixed embedded Archer display and mode menus - Cliff Yapp
* added Archer -h and --help command-line options - Cliff Yapp
* fixed Archer Help opening the documentation menu - Sean Morrison
* added arrange nest command for packing db objects - Sean Morrison
* added mkbuilding for parametric/OSM/CityJSON models - Sean Morrison
* added arrange nest command for packing database objects - Sean Morrison
* new mkbuilding tool for parametric/OSM/CityJSON models - Sean Morrison
* cross-platform BINUNIF and DSP byte-order handling - Sean Morrison
* improved several cv default behaviors (s,32,64,n) - Sean Morrison
* improved several cv default behaviors (s, 32, 64, n) - Sean Morrison
* fixed invalid bot handling bug applying matrices - Sean Morrison
* improved glTF import robustness via gcv - Sean Morrison
* fixed bot dump glTF/GLB export; -F is now rejected - Cliff Yapp
* faster NMG solid ray tracing (10-20x faster) - Sean Morrison
* preserved prim colors in shaded BoT and B-Rep drawing - Cliff Yapp
* preserved B-Rep attrs through in-place geometry edits - Cliff Yapp
* fixed gcv filter arguments w/ one-character values - Cliff Yapp
* preserved primitive colors in shaded BoT and B-Rep drawing - Cliff Yapp
* preserved B-Rep attributes through in-place geometry edits - Cliff Yapp
* fixed gcv filter arguments containing one-character values - Cliff Yapp
* improved iges-g importer robustness - Cliff Yapp
* expanded g-iges native CSG and B-Rep export support - Cliff Yapp
* added IGES import and export support to gcv - Cliff Yapp
* rt -b query option now supports a single value idx - Sean Morrison
* rt -b query option now supports a single value index - Sean Morrison
* fixed .dpix file format portability and icv support - Sean Morrison
* expanded pixscale support for piped image data - Sean Morrison
* fixed HYP volume and ARBN totals reported by analyze - Cliff Yapp
* fixed VOL data-file lookup and missing-data errors - Chris McGregor
* corrected rtarea sampling/exposed-area calculations - Cliff Yapp
* corrected rtarea sampling and exposed-area calculations - Cliff Yapp
* bot split now groups results and preserves mesh data - Cliff Yapp
* bot decimate now preserves nrmls, UVs, and plate data - Cliff Yapp
* bot decimate now preserves normals, UVs, and plate data - Cliff Yapp
* added raytracing support for annotation objects - Cliff Yapp
* fixed Windows subprocess quoting and empty arguments - Cliff Yapp
* fixed mged X embedded framebuffer display manager crash - Cliff Yapp
* fixed Windows drive-letter path handling - Cliff Yapp
* fixed MGED X embedded framebuffer display manager crash - Cliff Yapp
* added annotate command for managing annotation objects - Cliff Yapp
* added repair command for supported invalid primitives - Cliff Yapp
* changed default new-region material code from 1 to 0 - Keith Bowman
@@ -131,34 +105,26 @@ dependencies also receive substantial updates.
* added option validation to image & framebuffer tools - Sean Morrison
* added contributor, API, command, & raytracing guides - Sean Morrison
* added and updated command and library manual pages - Sean Morrison
* added pnts write -f xyz export option - Chris McGregor
* fixed mged ARB5 point editing - Cliff Yapp
* fixed mged gqa and rtcheck stale overlap plots - Cliff Yapp
* fixed procedural tree generator crashes - Sean Morrison, Cliff Yapp
* added gaia Earth models with day/dusk/night textures - Sean Morrison
* fixed fbcolor ramps & Windows input - Cliff Yapp, Sean Morrison
* added parashot gravity trajectory path generator - Sean Morrison
* added metaball pnt scaling (via metaball_move_pnt) - Sean Morrison
* added metaball point scaling (via metaball_move_pnt) - Sean Morrison
* all raytracing apps now report object prep failures - Sean Morrison
* improved fast4-g robustness and error reporting - Cliff Yapp
* improved robustness of g-vrml plate mode handling - Cliff Yapp
* added support for tick drawing on mged model axis - Cliff Yapp
* fixed MGED ARB5 point, pipe, and sketch editing - Cliff Yapp
* added pnts write -f xyz export option - Chris McGregor
* added support for tick drawing on MGED model axis - Cliff Yapp
* added naca456 left and paired wing generation - Cliff Yapp
* added patch-g -j option, specify object thicknesses - Sean Morrison
* corrected bwstat median and input error handling - Sean Morrison
* fixed fbcolor color ramp bug drawing the last color - Sean Morrison
* fixed gist -Q quick preview option - Sean Morrison
* rt preserves eye_pt setting in command scripts - Sean Morrison
* removed trailing whitespace from nirt output - Sean Morrison
* rt -l8 heat graphs now measure CPU time - Sean Morrison
* documented gqa centroid & moments of inertia options - Sean Morrison
* pixdiff now calculates pixel differences on bw files - Sean Morrison
* fixed bwcrop single-axis crops & pixembed edge fill - Sean Morrison
* fixed bwcrop single-axis crops and pixembed edge fill - Sean Morrison
* fixed isize in non-mm databases - Josh Baker
* fixed metaball adjust clearing points on errors - Sean Morrison
* fixed benchmark+pixcmp correctness validation bug - Sean Morrison
* fixed mged gqa option and value parsing - Sean Morrison
* improved gist hierarchy overflow rendering - Chris McGregor
* fixed rtxray -o grayscale/BW output - Sean Morrison
* fbhelp writes help to stdout and rest to stderr - Sean Morrison
* FB now supports /dev/stdout and /dev/stderr devices - Sean Morrison
* fixed mged rt -C + -o background color to file bug - Sean Morrison
@@ -167,7 +133,7 @@ dependencies also receive substantial updates.
* added rtsil -o support for bw output - Sean Morrison
* added cutting plane animation generation to rtwizard - Cliff Yapp
* fixed pixdiff bug on Windows - Sean Morrison
* fixed mged startup window placement on Windows - Chris McGregor
* fixed MGED startup window placement on Windows - Chris McGregor
* fixed pixborder utility right-side edge bug - Sean Morrison
* fixed 'wavelet' image processing tool on Windows - Sean Morrison
* quieted mged killtree spurious lookup failure output - Sean Morrison
@@ -178,16 +144,14 @@ dependencies also receive substantial updates.
* new doc guide, a visual overview of BRL-CAD objects - Sean Morrison
* improved triangle quality produced by bot remesh - Cliff Yapp
* updated numerous manpage command references - Josh Baker
* fixed submodel paths relative to parent databases - Sean Morrison
* improved performance making huge combinations - Sean Morrison
* added PNTS get, adjust, form, & g2asc/asc2g support - Chris McGregor
* fixed ANNOT get, adjust, & g2asc/asc2g support - Chris McGregor
* added make -t primitive type listing - Chris McGregor
* added gcv import conversion support for vrml/wrl 1.0 - Sean Morrison
* fixed gcv appending to existing geometry databases - Sean Morrison
* added CSS names, hex, HSL/HSV to libbu color parsing - Sean Morrison
* improved OpenNURBS B-Rep import and adjustment safety - Cliff Yapp
* improved Debian application menus/MIME associations - Jordi Sayol
* updated Tcl/Tk dependency to v8.6.18 using bundled Itcl - Cliff Yapp
* improved Debian application menus and MIME associations - Jordi Sayol
* updated Clipper2 dependency to v1.5.4 - Cliff Yapp
* updated Eigen dependency to v5.0.1 - Cliff Yapp
* updated GDAL dependency to v3.13.3 - Cliff Yapp
@@ -199,6 +163,7 @@ dependencies also receive substantial updates.
* updated OpenNURBS dependency to v8.34.26223.11001 - Cliff Yapp
* updated PROJ dependency to v9.8.1 - Cliff Yapp
* updated PoissonRecon dependency to v18.75 - Cliff Yapp
* updated Tcl/Tk dependency to v8.6.18, using bundled Itcl - Cliff Yapp
* updated libjpeg-turbo dependency to v3.2.0 - Cliff Yapp
* updated libosmesa dependency to SHA1 bfa90de - Cliff Yapp
* updated libpng dependency to v1.6.58 - Cliff Yapp
@@ -249,6 +214,9 @@ and extensively improving existing docs.
- Cliff Yapp, Sean Morrison
* fixed gqa exactly symmetric volumetric estimates - Sean Morrison
* added support to rtedge for perspective renderings - Sean Morrison
* added bu_cmd_schema for full command grammars, completion, and validation;
bu_opt remains the concise supported option-only API over the same engine
- BRL-CAD
* rt -l8 rendering time heat graphs - Stephen Kennedy, Sean Morrison
* added 'icv anim' for APNG and MJPEG animation files - Clifford Yapp
* added BREP/NURBS import support to gcv x3d importer - Sean Morrison
@@ -307,7 +275,7 @@ and extensively improving existing docs.
* added metadata-aware image diff & nirt analysis - Cliff Yapp
* added basic PNTS point-cloud ray tracing - Sean Morrison
* improved nirt behavior in Windows bash consoles - Cliff Yapp
* added g2asc/asc2g support for DSP and EBM - Sean Morrison
* added g2asc/asc2g support for PNTS, DSP, and EBM - Sean Morrison
* updated gct mesh decimation dependency to mmesh - Cliff Yapp
* added procedural wing, propeller & tree generators - Cliff Yapp
* added ISO tire dimensions & named tread presets - Cliff Yapp
@@ -579,7 +547,6 @@ for more information.
----------------------------------------------------------------------
--- 2023-11-06 Release 7.38.0 ---
----------------------------------------------------------------------
This major release of BRL-CAD introduces significant improvements to
the robustness of the facetize command by leveraging the Manifold
library for boolean evaluation of meshes. Facetization is an operation
@@ -618,7 +585,6 @@ processing high level assemblies in BRL-CAD's example geometry files:
----------------------------------------------------------------------
--- 2023-07-26 Release 7.36.0 ---
----------------------------------------------------------------------
This major release of BRL-CAD introduces significant updates to
geometry conversion support. The update includes modernization for
NURBS importing and interaction, BoT manipulation, and incorporates
+3 -3
View File
@@ -1,6 +1,6 @@
BRL-CAD
Release 7.46.0
http://brlcad.org/
BRL-CAD
Release 7.44.2
http://brlcad.org/
BRL-CAD is a powerful cross-platform open source combinatorial
solid modeling system that includes an interactive 3D solid geometry
-359
View File
@@ -1,359 +0,0 @@
# BRL-CAD RMF/STIG Cat 1 Vulnerability Tracking Ledger
**Last Synchronized:** 2026-09-28 03:00:00 UTC
| Issue ID | File | Lines | Cat 1 Type | Sev | Verification | Fix Status | 1-Sentence Nature of Issue |
|:---|:---|:---:|:---|:---:|:---:|:---:|:---|
| `SEC-0001` | `src/libpkg/pkg.c` | `1876-1923` | Invalid Free / Crasher | 3 | `CONFIRMED` | `FIXED` | pkg_waitfor fails to clear pc->pkc_buf on excess message length, causing subsequent pkg_close to call free on caller stack memory. |
| `SEC-0002` | `src/libpkg/pkg.c` | `1960-1968` | Uninitialized Memory Access | 2 | `CONFIRMED` | `FIXED` | pkg_bwaitfor returns uninitialized heap buffer instead of NULL when network read fails or disconnects prematurely. |
| `SEC-0003` | `src/libpkg/example_qt/server.cpp` | `46-59` | NULL Pointer Dereference / Crasher | 1 | `PENDING` | `UNFIXED` | PKGServer destructor unconditionally dereferences NULL client pointer and frees uninitialized pkc_inbuf. |
| `SEC-0004` | `src/fbserv/server.c` | `432-540` | Heap Out-of-Bounds Read / Crasher | 3 | `CONFIRMED` | `FIXED` | fbserv packet handlers fail to validate packet payload length against pixel count before calling fb_write, causing heap out-of-bounds read. |
| `SEC-0005` | `src/fbserv/server.c` | `476-580` | Integer Overflow / Heap Buffer Overflow | 3 | `CONFIRMED` | `FIXED` | Integer multiplication overflow in width*height in fb_readrect and fb_bwreadrect leads to heap buffer overflow during pixel read. |
| `SEC-0006` | `src/remrt/rtsrv.c` | `891-971` | Integer Signedness / Out-of-Bounds Memory Access | 2 | `CONFIRMED` | `FIXED` | ph_lines fails to validate pixel range bounds, causing signed integer underflow in (b-a+1)*3 to wrap to huge size_t in pkg_2send, triggering out-of-bounds heap reads, and leaks buffer. |
| `SEC-0007` | `src/remrt/remrt.c` | `3803-3806` | Unhandled Input Validation / Denial of Service | 2 | `CONFIRMED` | `FIXED` | ph_pixels parses incoming MSG_PIXELS without checking packet length or magic header, allowing malformed network packets to trigger out-of-bounds reads or terminate remrt via bu_bomb. |
| `SEC-0008` | `src/libbu/parse.c` | `87-118` | Out-of-Bounds Memory Access / Buffer Underflow | 2 | `CONFIRMED` | `FIXED` | bu_struct_wrap_buf and PARSE_CK_GETPUT do not verify buffer length is at least 8 bytes, causing negative index access and out-of-bounds read on buffers with small or zero length. |
| `SEC-0009` | `src/libbu/vls_vprintf.c` | `186-226` | Format String / Type Confusion | 2 | `CONFIRMED` | `FIXED` | vls_vprintf uses bitwise XOR (^=) instead of bitwise AND NOT (&= ~) to clear length modifiers, corrupting flags and causing incorrect type extraction from va_list. |
| `SEC-0010` | `src/libbu/vls.c` | `433-465` | Off-by-One / Buffer Corruption | 2 | `CONFIRMED` | `FIXED` | bu_vls_substr calls bu_vls_putc with NUL, embedding an unwanted NUL byte and off-by-one corrupting vls_len. |
| `SEC-0011` | `src/libbu/malloc.c` | `84-145,375-388` | Integer Overflow / Heap Overflow | 2 | `CONFIRMED` | `FIXED` | alloc() and bu_pool_alloc() lack integer multiplication overflow checks on cnt*size, which can cause undersized memory allocations and subsequent heap buffer overflows. |
| `SEC-0012` | `src/libbu/argv.c` | `97,175,268-295` | Buffer Underflow / Out-of-bounds Pointer | 2 | `CONFIRMED` | `FIXED` | bu_argv_from_string computed pointer at strlen(lp)-1 on potentially empty string causing integer underflow and out-of-bounds pointer arithmetic. |
| `SEC-0013` | `src/libbu/str.c` | `61-75` | Buffer Over-read | 2 | `CONFIRMED` | `FIXED` | bu_strlcatm uses unbounded strlen on dst to detect un-terminated buffers, causing out-of-bounds read. |
| `SEC-0014` | `src/libbu/b64.c` | `216-284` | Null Pointer Dereference / Integer Overflow | 2 | `CONFIRMED` | `FIXED` | bu_b64 encode and decode functions lacked null pointer checks on input/output and cast lengths to signed 32-bit int. |
| `SEC-0015` | `src/libbu/sscanf.c` | `312-320,365-375` | Format String / Scanset Parser Bug | 2 | `CONFIRMED` | `FIXED` | bu_vsscanf omitted literal ] and ^] from partFmt when extracting scanset specifiers, causing malformed format strings and scan failure. |
| `SEC-0016` | `src/libbu/bitv.c` | `95-105,285-295,440-445,625-630` | Null Pointer Dereference / Integer Overflow | 2 | `CONFIRMED` | `FIXED` | bu_hex_to_bitv and bu_binary_to_bitv2 crashed on NULL input, and bu_bitv_shift_vector had integer overflow UB on INT_MIN. |
| `SEC-0017` | `src/libbu/hash.c` | `125-135,180-190,270-280` | Null Pointer Dereference / Memory Safety | 2 | `CONFIRMED` | `FIXED` | bu_hash_get crashed on NULL key in _nhash_keycmp, and bu_hash_create/bu_hash_set lacked allocation failure handling. |
| `SEC-0018` | `include/bu/ptbl.h, src/libbu/ptbl.c` | `105,119-120; 63,99,214,240,266,290` | Memory Access Violation / Buffer Overflow / Out-of-bounds Pointer | 3 | `CONFIRMED` | `FIXED` | BU_PTBL_FOR macro and BU_PTBL_LASTADDR cause out-of-bounds pointer calculation and segfault on empty tables with NULL buffers, and table reallocations lack integer multiplication overflow checks. |
| `SEC-0019` | `src/libbu/affinity.c` | `74,90-104,108` | Out-of-bounds Bit Array Access / Resource Leak / Undefined Behavior | 2 | `CONFIRMED` | `FIXED` | parallel_set_affinity permitted negative cpu indexing into CPU_SET and negative bitshift on Windows, leaked Mach thread port rights, and passed wrong policy type for Mach thread affinity. |
| `SEC-0020` | `src/libbu/backtrace.c` | `324,596,659-661,742` | NULL Pointer Dereference / Process Signal Safety | 2 | `CONFIRMED` | `FIXED` | bu_backtrace_app called bu_strlcpy on potentially NULL gdb_path, used negative file descriptors in write, and reaped arbitrary child processes via wait(NULL). |
| `SEC-0021` | `src/libbu/cmd.c` | `50-66` | NULL Pointer Dereference / Buffer Underflow / Crasher | 2 | `CONFIRMED` | `FIXED` | bu_cmd lacked null checks on cmds, argv, and argv[cmd_index], allowed negative cmd_index causing buffer underflow, and executed unverified function pointers. |
| `SEC-0022` | `src/libbu/damlevlim.cpp` | `68-159` | Integer Multiplication Overflow / Crasher | 2 | `CONFIRMED` | `FIXED` | bu_editdist computed buffer allocation size as (n+1)*(m+1) using signed 32-bit int, causing signed integer multiplication overflow, out-of-bounds access, and std::length_error crash on large strings. |
| `SEC-0023` | `src/libbu/dirent.c, src/libbu/datetime.cpp` | `36-88; 173-197` | Heap Buffer Overflow / NULL Pointer Dereference / TOCTOU | 2 | `CONFIRMED` | `FIXED` | bu_file_list called opendir(NULL) when path is NULL and suffered from heap buffer overflow if directory entries were added concurrently between passes; bu_utctime crashed on NULL vls_gmtime. |
| `SEC-0024` | `src/libbu/dir.c` | `69-75, 108, 169, 186, 248, 254, 395-405, 480-535, 656-665, 684-740` | Buffer Overflow / Underflow / NULL Pointer Dereference / Infinite Loop | 2 | `CONFIRMED` | `FIXED` | dir routines passed caller buffer len to fixed stack arrays risking stack buffer overflow, permitted underflow pointer reads in _bu_dir_join_path, crashed on NULL result in vdir, and risked infinite loop or crash in bu_mkdir/bu_dirclear on invalid paths. |
| `SEC-0025` | `src/libbu/dylib.c` | `38-40, 70-87, 105-120` | Heap Use-After-Free / Double-Free / Thread Safety | 3 | `CONFIRMED` | `FIXED` | bu_dlunload freed the global handles table without resetting handles to NULL or max_handles to 0, leading to dangling pointer use-after-free heap writes on subsequent bu_dlclose calls and double-free on subsequent bu_dlunload calls; routines lacked thread synchronization. |
| `SEC-0026` | `src/libbu/fchmod.cpp` | `62-75` | Invalid File Descriptor / Parameter Validation | 1 | `CONFIRMED` | `FIXED` | bu_fchmod passed unvalidated negative file descriptors to OS handles routines triggering CRT parameter validation errors or unexpected failures. |
| `SEC-0027` | `src/libbu/file.cpp` | `79-110, 126-166, 193, 227-240, 360, 603-640` | Memory Leak / Resource Leak / NULL Pointer Dereference / Logic Flaw | 2 | `CONFIRMED` | `FIXED` | bu_file_same leaked allocated realpath strings on match and crashed on NULL paths, file_compare_info had an assignment instead of comparison operator bug, bu_file_exists leaked file descriptors, and stream seek/tell functions crashed on NULL streams. |
| `SEC-0028` | `src/libbu/fnmatch.c` | `308-311` | NULL Pointer Dereference / Crasher | 2 | `CONFIRMED` | `FIXED` | bu_path_match immediately dereferenced pattern and string without NULL pointer checks, causing immediate SIGSEGV crashes on NULL inputs. |
| `SEC-0029` | `src/libbu/gethostname.c` | `49, 81-84, 89` | Invalid Pointer Cast / NULL Pointer Dereference / Buffer Overflow | 2 | `CONFIRMED` | `FIXED` | bu_gethostname passed constant (LPDWORD)MAXPATHLEN as pointer to GetComputerName causing invalid pointer crash, left procfs file pointer unchecked causing null stream crash, and lacked entry bounds validation. |
| `SEC-0030` | `src/libbu/getopt.c` | `34-39, 48-56, 65-72, 84, 98` | NULL Pointer Dereference / Buffer Over-read / Logic Flaw | 2 | `CONFIRMED` | `FIXED` | bu_getopt dereferenced NULL nargv elements and NULL *nargv in tell macro, read out of bounds on '\0' matched in ostr via strchr, and misidentified bare '-' as an option. |
| `SEC-0031` | `src/libbu/glob.c` | `63, 84, 110, 161, 195, 240, 259, 286` | NULL Pointer Dereference / Crasher | 2 | `CONFIRMED` | `FIXED` | bu_glob internal helpers and callbacks dereferenced NULL pattern, path, directory entry, or stat buffer pointers without checking for NULL. |
| `SEC-0032` | `src/libbu/heap.c` | `136, 200-216, 255` | Out-of-bounds Array Access / Integer Underflow | 2 | `CONFIRMED` | `FIXED` | bu_heap_get bypassed allocation size range check when DEBUG was not defined causing out-of-bounds heap bin indexing and underflow to SIZE_MAX when sz == 0, and lacked cpu id bounds clamping. |
| `SEC-0033` | `src/libbu/hist.c` | `52, 82-100, 117-128` | Out-of-bounds Memory Write / NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bu_hist_range permitted negative or out-of-bounds 'a' indexing on NaN inputs causing heap write access violation, and bu_hist_init/bu_hist_pr crashed on NULL inputs. |
| `SEC-0034` | `src/libbu/interrupt.c` | `78-83, 100-116, 137-163` | Signal Handler Leak / Out-of-bounds Array Access / Logic Flaw | 2 | `CONFIRMED` | `FIXED` | interrupt_restore_signal never restored signal handlers when no signal was received leaving temporary handler active indefinitely, checked wrong handler pointer, and lacked bounds check on signum. |
| `SEC-0035` | `src/libbu/num.c` | `35-58, 87-90, 106` | Buffer Underflow / Integer Overflow UB / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | bu_num_print read out-of-bounds at tbl_start[-1] due to reversed condition ordering in trailing newline scan and crashed on empty strings; char_length had signed integer overflow UB on INT64_MIN and truncated 64-bit int to long. |
| `SEC-0036` | `src/libbu/log.c` | `148, 156, 204, 222, 335` | NULL Pointer Dereference / Integer Overflow | 2 | `CONFIRMED` | `FIXED` | bu_flog lacked null pointer and empty string checks on fmt and fp, causing NULL pointer dereference crashes in fwrite, and bu_log helper routines lacked null pointer guards. |
| `SEC-0037` | `src/libbu/mappedfile.c` | `360, 544-550, 577` | NULL Pointer Dereference / Integer Underflow | 2 | `CONFIRMED` | `FIXED` | bu_open_mapped_file_with_path crashed with SIGSEGV on NULL name or path, bu_free_mapped_files suffered from unsigned integer underflow on index removal, and bu_open_mapped_file allowed invalid file sizes. |
| `SEC-0038` | `src/libbu/observer.c` | `36, 58, 110, 168, 194, 215` | NULL Pointer Dereference / Memory Safety | 2 | `CONFIRMED` | `FIXED` | bu_observer_cmd and helper routines dereferenced NULL argv or NULL observer lists without validation, and bu_observer_free left dangling pointers in the observer list. |
| `SEC-0039` | `src/libbu/lex.c` | `42, 131, 155, 257, 268` | Integer Underflow / NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | lex_getone allowed negative *used integer underflow on number fallback, and bu_lex crashed on NULL token, rtstr, or NULL key strings. |
| `SEC-0040` | `src/libbu/path_normalize.c` | `47, 86-88, 95` | Buffer Underflow / Concurrency Hazard / Integer Bounds | 2 | `CONFIRMED` | `FIXED` | bu_path_normalize used non-thread-safe static buffer, lacked lower-bound check in backward component scan allowing pointer underflow before resolved buffer, and used unchecked signed pointer arithmetic for MAXPATHLEN bounds check. |
| `SEC-0041` | `src/libbu/printb.c` | `36, 40-52` | NULL Pointer Dereference / Undefined Bitshift / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | bu_vls_printb dereferenced NULL vls and bits strings, shifted signed 1L by negative or out-of-range bit numbers causing undefined behavior, and read out-of-bounds on strings ending after bit numbers. |
| `SEC-0042` | `src/libbu/path.c` | `177-180, 211-218, 242-258` | NULL Pointer Dereference / Path Truncation Flaw | 2 | `CONFIRMED` | `FIXED` | bu_path_to_argv dereferenced NULL ac pointer causing crash, and bu_path_component corrupted file paths by stripping directories when a dot appeared in directory names under BU_PATH_EXTLESS and BU_PATH_EXT. |
| `SEC-0043` | `src/libbu/parallel_cpp11thread.cpp` | `28-51` | Crash / Unhandled Exception / NULL Function Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | parallel_cpp11thread crashed on NULL func callback and caused std::terminate() aborts if thread creation threw an exception while previous threads remained joinable. |
| `SEC-0044` | `src/libbu/progname.c` | `74-79, 140-143, 155-190` | Concurrency Hazard / Unchecked Buffer Overflow | 2 | `CONFIRMED` | `FIXED` | bu_argv0_full_path and bu_getprogname returned static non-thread-safe buffers and accessed bu_progname unsynchronized with concurrent bu_setprogname writes, and bu_argv0_full_path unchecked bu_getcwd return and appended with potential buffer overflow. |
| `SEC-0045` | `src/libbu/realpath.c` | `38-66` | NULL Pointer Dereference / Crash | 2 | `CONFIRMED` | `FIXED` | bu_file_realpath dereferenced NULL path pointer into realpath, GetFullPathName, and bu_strlcpy fallback causing immediate SIGSEGV crashes. |
| `SEC-0046` | `src/libbu/scan.c` | `38, 58-60, 68-73, 89-93` | Format String Flaw / Uninitialized Variable Memory Corruption | 2 | `CONFIRMED` | `FIXED` | bu_scan_fastf_t constructed dynamic scanf format strings from user delimiter allowing format string injection, and read uninitialized stack variable 'len' into offset when sscanf failed to reach %n specifier. |
| `SEC-0047` | `src/libbu/semaphore.c` | `260-286, 298-301, 340-343` | Out-of-bounds Array Access / Concurrency Race Condition | 2 | `CONFIRMED` | `FIXED` | bu_semaphore_acquire and bu_semaphore_release lacked upper bounds checks on semaphore index causing out-of-bounds array access and integer overflow on UINT_MAX, and bu_semaphore_free destroyed mutexes without synchronizing on bu_init_lock. |
| `SEC-0048` | `src/libbu/sha1.c` | `53, 110, 126, 150` | NULL Pointer Dereference / Memory Safety | 2 | `CONFIRMED` | `FIXED` | SHA1Transform, SHA1Init, SHA1Update, and SHA1Final lacked NULL pointer validation on context, data, digest, state, and buffer pointers causing SIGSEGV crashes. |
| `SEC-0049` | `src/libbu/snooze.cpp` | `35-42` | Integer Overflow UB / Logic Flaw | 1 | `CONFIRMED` | `FIXED` | bu_snooze lacked upper bound clamping on 64-bit useconds causing integer overflow when converted to nanoseconds internally in std::chrono durations. |
| `SEC-0050` | `src/libbu/sort.c` | `156-189, 381-402` | Memory Access Flaw / Divide by Zero | 2 | `CONFIRMED` | `FIXED` | bu_sort lacked checks for NULL a, NULL cmp, zero element size es == 0 (causing division by zero in introsort), and min(a, b) macro lacked parameter parentheses. |
| `SEC-0051` | `src/libbu/tbl.c` | `381-432` | Buffer Underflow / Pointer Overflow | 2 | `CONFIRMED` | `FIXED` | bu_tbl_printf suffered from backward scan buffer underflow dereferencing buf[-1] and unbounded runaway pointer increment last += 2 over-reading memory. |
| `SEC-0052` | `src/libbu/tc.c` | `33-200, 428-456` | Null Pointer Dereference / Memory Management | 2 | `CONFIRMED` | `FIXED` | bu_thrd_create dereferenced NULL thr pointer and lacked guard on NULL func; mutex and condition variable routines lacked NULL checks; used raw malloc/free. |
| `SEC-0053` | `src/libbu/tcllist.c` | `538, 554-565` | Buffer Over-read / Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bu_argv_from_tcl_list crashed on NULL arguments; _bu_tcl_copy_collapse passed strlen(src) instead of remaining count to _bu_tcl_parse_backslash, allowing read out of bounds past list element. |
| `SEC-0054` | `src/libbu/temp.c` | `85-151, 155-175` | Uninitialized Memory / Heap Corruption / Concurrency | 3 | `CONFIRMED` | `FIXED` | temp_add_to_list failed to copy initial_temp_files when reallocating from 8 to 16 elements, reading uninitialized memory and calling close() on garbage file descriptors at exit; global temp list lacked thread synchronization. |
| `SEC-0055` | `src/libbu/units.c` | `237-244, 256-270, 390-440` | Buffer Underflow / Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | units_name_matches underflowed bu_vls_strlen - 1 to SIZE_MAX on empty strings/whitespace, causing out-of-bounds heap read; bu_units_conversion, bu_mm_value, and bu_mm_cvt crashed on NULL pointers. |
| `SEC-0056` | `src/libbu/units_dehumanize.c` | `80-92, 131-137` | Null Pointer Dereference / Integer Overflow UB | 1 | `CONFIRMED` | `FIXED` | bu_dehumanize_number crashed on NULL str or size and performed signed multiplication without pre-overflow bounds check. |
| `SEC-0057` | `src/libbu/units_humanize.c` | `74-82, 128-133` | Null Pointer Dereference / Integer Overflow UB | 2 | `CONFIRMED` | `FIXED` | bu_humanize_number dereferenced buf[0] before validating buf != NULL, causing crash when called with a NULL buffer; negation of INT64_MIN caused signed integer overflow UB. |
| `SEC-0058` | `src/libbu/uuid.c` | `56, 89, 118-124, 134-161` | Buffer Overflow / Null Pointer Dereference / Logic Flaw | 2 | `CONFIRMED` | `FIXED` | bu_uuid_decode suffered critical 16-byte buffer overflow writing 32 bytes to a 16-byte array on non-adjacent hex strings; bu_uuid_create crashed on NULL uuid and corrupted UUIDv5 bits with 0x5F instead of 0x50; bu_uuid_encode crashed on NULL pointers. |
| `SEC-0059` | `src/libbu/vfont.c` | `42, 60-100, 140-150, 184-196, 201-207` | File Descriptor Leak / Uninitialized Data / Null Dereference | 2 | `CONFIRMED` | `FIXED` | vfont_get passed potential NULL from bu_dir() to snprintf %s, left 256th dispatch entry uninitialized (i < 255), leaked file descriptors on read failures in get_font, and vfont_free crashed on NULL pointer. |
| `SEC-0060` | `src/libbu/vlb.c` | `34-160` | Integer Overflow / Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bu_vlb_write lacked integer overflow protection on capacity addition and crashed when given NULL start; bu_vlb_init, bu_vlb_initialize, bu_vlb_free, and bu_vlb_print crashed on NULL pointers. |
| `SEC-0061` | `src/libbu/cache.cpp` | `110-140, 220-250, 480-510` | Undefined Behavior / Memory Leak / Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bu_cache_close freed bu_cache_impl containing std::mutex with BU_PUT instead of delete causing destructor bypass and undefined behavior; bu_cache_keys leaked keystr memory; bu_cache_write_commit underflowed mv_size on negative lengths; NULL txn crashed transactions. |
| `SEC-0062` | `src/libbu/color.cpp` | `52-95, 120-160` | Null Pointer Dereference / Float Validity | 2 | `CONFIRMED` | `FIXED` | bu_color_from_str, bu_rgb_to_hsv, and bu_hsv_to_rgb dereferenced NULL pointers unconditionally without validation; bu_color_from_rgb_floats lacked bounds and finite checks. |
| `SEC-0063` | `src/libbu/convert.c` | `120-160, 200-240` | Buffer Overflow / Unsigned Underflow | 2 | `CONFIRMED` | `FIXED` | bu_cv_fmt_cookie decremented buflen below zero on small buffers (1-2 bytes), wrapping to SIZE_MAX and writing out of bounds; bu_cv_w_cookie and byte swap routines crashed on NULL or empty input. |
| `SEC-0064` | `src/libbu/crashreport.c` | `110-140, 210-230` | File Descriptor Leak / Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bu_crashreport leaked file descriptor when ferror(fp) was true, and formatted potential NULL return from ctime(). |
| `SEC-0065` | `src/libbu/env.c` | `140-190, 240-270` | Memory Leak / Null Pointer Dereference / Unchecked Input | 2 | `CONFIRMED` | `FIXED` | editor_not_compatible leaked component vls and dereferenced NULL candidate; editor_file_check lacked NULL checks; bu_setenv lacked POSIX environment variable name validation. |
| `SEC-0066` | `src/libbu/opt.c` | `215-260, 480-520` | Null Pointer Dereference / Buffer Over-read / Type Mismatch | 2 | `CONFIRMED` | `FIXED` | opt_describe_internal_ascii crashed when arg_helpstr or help_string was NULL; docbook describe had curr vs d typo; opt_process over-read empty candidate; bu_opt_color had unsigned char type mismatch. |
| `SEC-0067` | `src/libbu/parallel.c` | `280-310` | Out-of-Bounds Memory Access | 2 | `CONFIRMED` | `FIXED` | PARALLEL_PUT accessed mapping[id] without validating 0 <= id < MAX_PSW*MAX_PSW, causing out-of-bounds memory corruption. |
| `SEC-0068` | `src/libbu/process.c` | `350-380, 520-560, 1220-1250` | Null Pointer Dereference / Memory Leak / Buffer Overflow | 2 | `CONFIRMED` | `FIXED` | bu_process_read unconditionally dereferenced *count = ... even if caller passed NULL; bu_process_exec leaked heap av on every execution; bu_interactive passed unchecked fd to FD_SET causing buffer overflow. |
| `SEC-0069` | `src/libbu/uce-dirent.h` | `348-354, 578-583, 608-612` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | opendir, rewinddir, and _initdir relied solely on assert() in debug mode, crashing with NULL pointer dereference in release builds when given NULL dirname or DIR stream. |
| `SEC-0070` | `src/libbu/vls_incr.cpp` | `136-155, 180-188` | Unhandled Exception / Denial of Service Crash | 2 | `CONFIRMED` | `FIXED` | bu_vls_incr accessed ivar.str(1) and nvar.str(1) without verifying match group count, throwing std::out_of_range which bypassed catch (const std::regex_error&) and crashed the application. |
| `SEC-0071` | `src/libbu/whereami.c` | `95-135` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | _bu_getExecutablePath dereferenced pname[0] without checking if _bu_progname_raw() returned NULL, and copied memory into out when out == NULL. |
| `SEC-0072` | `src/libbu/whereis.c` | `135-155` | Infinite Loop / Denial of Service | 2 | `CONFIRMED` | `FIXED` | bu_whereis bypassed pointer advancement on dirlen > MAXPATHLEN-2 with continue;, causing an infinite loop hanging the process at 100% CPU. |
| `SEC-0073` | `src/libbu/which.c` | `91-115` | Infinite Loop / Memory Leak | 2 | `CONFIRMED` | `FIXED` | which_path suffered infinite loop on oversized directories and empty matches, and leaked initial_path every time an executable was not found. |
| `SEC-0074` | `src/libbu/xdr.c` | `31-88` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bu_pshort, bu_gshort, bu_plong, bu_glong, and bu_plonglong dereferenced msgp without validating msgp != NULL, causing immediate segmentation fault. |
| `SEC-0075` | `src/libbu/tests/dylib/dylib.c` | `35-85` | Memory Leak / Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bu_file_list allocated filenames and bu_vls plugin_pattern allocated memory which was never freed; dylib_close_plugins dereferenced NULL pointer when called with plugins == NULL. |
| `SEC-0076` | `src/libbu/tests/dylib/plugin_1.cpp` | `22-28` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | calc dereferenced *result without checking if *result == NULL, causing crash on NULL buffer pointer. |
| `SEC-0077` | `src/libbu/tests/dylib/plugin_2.cpp` | `22-28` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | calc dereferenced *result without checking if *result == NULL, causing crash on NULL buffer pointer. |
| `SEC-0078` | `src/libbu/tests/test_dirname.c` | `58-82` | Stack Buffer Overflow / Format String UB | 2 | `CONFIRMED` | `FIXED` | bu_strlcpy used strlen(input)+1 instead of destination buffer size, causing stack buffer overflow on strings exceeding 1000 bytes; passed NULL to printf format string. |
| `SEC-0079` | `src/libbu/tests/test_encode.c` | `70-90` | Undefined Behavior / Crash | 1 | `CONFIRMED` | `FIXED` | Passed NULL str directly to %*s and %s in printf when testing test_encode(NULL), causing undefined behavior and potential crash. |
| `SEC-0080` | `src/libbu/tests/test_datetime.c` | `243-345` | Memory Leak / Unchecked Return | 1 | `CONFIRMED` | `FIXED` | result VLS was allocated and never freed across multiple date/time tests, leaking memory; sscanf return value was unvalidated. |
| `SEC-0081` | `src/libbu/tests/test_basename.c` | `55-65, 130-140` | Null Pointer Dereference / Crash | 2 | `CONFIRMED` | `FIXED` | get_system_output(NULL) called basename(NULL) which causes segmentation fault on glibc implementations; passed NULL input to bu_log format strings. |
| `SEC-0082` | `src/libbu/tests/test_progname.c` | `63-71, 107-115, 149-157, 189-197` | Heap Buffer Overflow / Off-by-one | 2 | `CONFIRMED` | `FIXED` | Allocated strlen(path) bytes via bu_calloc without space for null terminator before calling bu_strlcpy, causing buffer overflow; leaked allocated buffer. |
| `SEC-0083` | `src/libbu/tests/test_mappedfile.c` | `70-74, 385-397` | Use-After-Free / Memory Leak / Float Comparison | 2 | `CONFIRMED` | `FIXED` | Accessed mfp->buf after closing mapped file via bu_close_mapped_file, performed raw float equality on double num, and leaked fname VLS. |
| `SEC-0084` | `src/libbu/tests/test_process.c` | `172-184, 521-536, 680-705` | Process Resource Leak / NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | Failed to wait on or close process handles on error paths leaking processes, and attempted to close/read NULL file handles when fopen failed. |
| `SEC-0085` | `src/libbu/tests/test_parallel.c` | `70-80, 115-125` | Array Out-of-Bounds / Crash | 2 | `CONFIRMED` | `FIXED` | Indexed counter array with cpu ID up to ncpu in tally without bound check, and omitted NULL data check in parallel recursion callback. |
| `SEC-0086` | `src/libbu/tests/test_opt.c` | `58-64, 492-498` | Out-of-Bounds Memory Read / Pointer Type-Punning | 2 | `CONFIRMED` | `FIXED` | Read av[-1] when av was decremented without checking bounds, and type-punned unsigned int array to unsigned char pointer violating strict aliasing. |
| `SEC-0087` | `src/libbu/tests/test_hook.c` | `45-55, 120-145` | NULL Pointer Dereference / Memory Leak | 2 | `CONFIRMED` | `FIXED` | Callback dereferenced clientdata pointer without NULL check and hook list structures were allocated and never freed across tests. |
| `SEC-0088` | `src/libbu/tests/test_glob.c` | `95-110, 195-205` | Out-of-Bounds Read / NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | Read buffer out of bounds when checking trailing slash on short paths and called glob operations without validating NULL context pointers. |
| `SEC-0089` | `src/libbu/tests/test_env.c` | `80-92, 128-135` | Resource Leak / Unchecked Return Value | 1 | `CONFIRMED` | `FIXED` | Did not check fopen return value before writing and failed to validate bu_strdup return value leaking memory on error. |
| `SEC-0090` | `src/libbu/tests/test_escape.c` | `72-85, 140-150` | NULL Pointer Dereference / Format Flaw | 1 | `CONFIRMED` | `FIXED` | Passed unverified pointer to %s format specifier in printf calls and omitted explicit return code in test helper. |
| `SEC-0091` | `src/libbu/tests/test_path_component.c` | `62-75` | Format String Flaw / NULL Dereference | 1 | `CONFIRMED` | `FIXED` | Passed NULL pointer to %24s in bu_log formatting calls, which crashes strict C runtime environments. |
| `SEC-0092` | `src/libbu/tests/test_humanize_number.c` | `115-135` | Memory Leak | 1 | `CONFIRMED` | `FIXED` | Allocated string representations of flags and scale inside loop iterations without freeing them, causing repeated memory leaks. |
| `SEC-0093` | `src/libbu/tests/test_file.c` | `70-75, 233-241` | Memory Leak / NULL Pointer Dereference | 1 | `CONFIRMED` | `FIXED` | cleanup() function leaked fname VLS allocation on return, and realpath test did not check if rpath was NULL before comparing. |
| `SEC-0094` | `src/libbu/tests/test_file_mime.c` | `45-56` | Unchecked Return Value / Array Bounds | 1 | `CONFIRMED` | `FIXED` | Did not check sscanf return count allowing uninitialized integer use, and allowed negative context index causing out-of-bounds array access. |
| `SEC-0095` | `src/libbu/tests/test_observer.c` | `45-55` | NULL Pointer Dereference | 1 | `CONFIRMED` | `FIXED` | Missing NULL check on observer callback event structure pointer before dereferencing. |
| `SEC-0096` | `src/libbu/tests/test_parallel_concurrency.cpp` | `40-48` | NULL Pointer Dereference | 1 | `CONFIRMED` | `FIXED` | Thread worker function dereferenced user data pointer without checking for NULL. |
| `SEC-0097` | `src/libbu/tests/test_path_match.cpp` | `38-52` | Resource Leak / Empty String Check | 1 | `CONFIRMED` | `FIXED` | ifstream remained open without explicit close and empty lines were parsed without validation. |
| `SEC-0098` | `src/libbu/realpath.c` | `20-27` | POSIX/Darwin API Resolution / Failure to Canonicalize | 2 | `CONFIRMED` | `FIXED` | Under strict POSIX/XOPEN flags on macOS without _DARWIN_C_SOURCE, realpath bound to legacy conformance symbol which failed with EPERM, breaking path canonicalization across libbu. |
| `SEC-0099` | `src/libbu/tests/test_realpath.c` | `47-79` | Memory Management / Resource Leak | 2 | `CONFIRMED` | `FIXED` | Heap memory leak of allocated path string, unchecked sscanf return value, and potential NULL printf argument in test_realpath.c. |
| `SEC-0100` | `src/libbu/tests/test_semaphore.c` | `48-62` | Memory Access / NULL Pointer Dereference | 1 | `CONFIRMED` | `FIXED` | Unchecked callback argument pargs in multi-threaded function increment_thread could lead to NULL pointer dereference. |
| `SEC-0101` | `src/libbu/tests/test_semaphore_registry.cpp` | `60-63` | Memory Access / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0102` | `src/libbu/tests/test_semchk.cpp` | `40-75` | Error Handling / Logic Error | 2 | `CONFIRMED` | `FIXED` | Undeclared identifier av[0] passed to bu_setprogname, unhandled file stream failure in process_file, and unguarded argv dereference. |
| `SEC-0103` | `src/libbu/tests/test_snooze.c` | `44-48` | Memory Access / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0104` | `src/libbu/tests/test_sort.c` | `45-95` | Integer Wraparound / Underflow | 1 | `CONFIRMED` | `FIXED` | Integer subtraction bug in comparison function comp_1 (*(unsigned int *)num1 - *(unsigned int *)num2) caused unsigned underflow and reversed sort order; comp_4 lacked NULL pointer checks; sscanf return was unchecked. |
| `SEC-0105` | `src/libbu/tests/test_static_init.cpp` | `44-48` | Memory Access / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0106` | `src/libbu/tests/test_str.c` | `115-180` | Memory Management / Resource Leak | 2 | `CONFIRMED` | `FIXED` | Memory leaks of allocated dst buffer across test_bu_strlcatm, test_bu_strlcpym, and test_bu_strdupm, unchecked sscanf, and negative integer cast to size_t. |
| `SEC-0107` | `src/libbu/tests/test_str_isprint.c` | `70-98` | Format String / NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | Passing NULL string pointer to %10s format specifier in bu_log caused undefined behavior / crash; unchecked sscanf. |
| `SEC-0108` | `src/libbu/tests/test_subprocess.cpp` | `45-55` | Uninitialized Memory Access | 2 | `CONFIRMED` | `FIXED` | Stack buffer char line[25] was uninitialized before std::cin.get(line, 25), leading to uninitialized memory read if stream was empty or in error state. |
| `SEC-0109` | `src/libbu/tests/test_temp_filename.c` | `45-78` | Concurrency / Out-of-bounds Memory Access | 1 | `CONFIRMED` | `FIXED` | Passed &names (char ***) instead of names (char **) to bu_parallel, causing worker threads with cpu > 1 to read and write invalid stack memory outside the array; names[cpu - 1] caused underflow on cpu = 0; off-by-one heap allocation len + 1 caused string truncation. |
| `SEC-0110` | `src/libbu/tests/test_units.c` | `48-58` | Memory Access / NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | Missing NULL pointer validation for csv and token in helper function units_csv_has_token. |
| `SEC-0111` | `src/libbu/tests/test_uuid.c` | `55-90` | Logic Error / False-Pass Test Suite Flaw | 2 | `CONFIRMED` | `FIXED` | Typo in expected UUID string paired with inverted condition !bu_strcmp caused test suite to return 0 (PASS) on mismatch while returning 1 (FAIL) if it matched; missing error logging. |
| `SEC-0112` | `src/libbu/tests/test_version.c` | `35-48` | Memory Access / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | Missing common.h include and unguarded av[0] dereference passed to bu_setprogname. |
| `SEC-0113` | `src/libbu/tests/test_vlb.c` | `42-46` | Memory Access / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0114` | `src/libbu/tests/test_vls.c` | `115-680` | Memory Management / Resource Leak | 2 | `CONFIRMED` | `FIXED` | Heap memory leaks across 13 test functions using bu_vls_strdup solely for comparison without freeing the returned string; out-of-bounds argv access in test_bu_vls_substr; unchecked sscanf. |
| `SEC-0115` | `src/libbu/tests/test_vls_incr.c` | `58-85` | Input Validation / Integer Parsing | 2 | `CONFIRMED` | `FIXED` | Unguarded argv dereference and unvalidated strtol conversion where invalid characters or out-of-range counts were unhandled. |
| `SEC-0116` | `src/libbu/tests/test_vls_incr_uniq.cpp` | `50-93` | Memory Management / Resource Leak | 2 | `CONFIRMED` | `FIXED` | Memory leak of struct bu_vls name on exit; heap allocation leak of std::set on early exit; potential NULL pointer dereference in StrCmp. |
| `SEC-0117` | `src/libbu/tests/test_vls_simplify.c` | `56-85` | Memory Access / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | Unguarded argv dereference before bu_setprogname, potential NULL pointer dereference in bu_log format string. |
| `SEC-0118` | `src/libbu/tests/test_vls_vprintf.c` | `55-175` | Buffer Overflow / Stack Vulnerability | 1 | `CONFIRMED` | `FIXED` | Unbounded vsprintf into fixed 1024-byte stack buffer buffer[1024] created an unconstrained stack buffer overflow vulnerability; unchecked sscanf and unguarded argv. |
| `SEC-0119` | `src/libbn/anim.c` | `304-332` | Numerical Stability / NaN Generation | 1 | `CONFIRMED` | `FIXED` | anim_mat2quat negative square root NaN generation caused by floating-point rounding when testing !ZERO(square); passed minute negative numbers into sqrt() resulting in NaN quaternion components. |
| `SEC-0120` | `src/libbn/anim.c` | `153-176` | Buffer Overflow | 1 | `CONFIRMED` | `FIXED` | anim_mat_printf stack buffer overflow risk with fixed 128-byte character buffer when formatting 16 double-precision float values with custom prefix strings. |
| `SEC-0121` | `src/libbn/anim.c` | `180-680` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | Missing NULL pointer checks across anim_mat_print, anim_dir2mat, anim_dirn2mat, anim_steer_mat, anim_v_permute, anim_v_unpermute, anim_tran, anim_mat2zyx, and anim_mat2ypr. |
| `SEC-0122` | `src/libbn/complex.c` | `54-85` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bn_cx_div and bn_cx_sqrt dereferenced destination and operand pointers without validating against NULL. |
| `SEC-0123` | `src/libbn/mat.c` | `1544-1578` | Stack Buffer Overflow | 1 | `CONFIRMED` | `FIXED` | bn_opt_mat looped up to argc when argc > 15, writing into fixed 16-element stack array fastf_t mtmp[16], overflowing the stack frame on excess arguments. |
| `SEC-0124` | `src/libbn/mat.c` | `1500-1540` | Out-of-bounds Read | 1 | `CONFIRMED` | `FIXED` | bn_opt_mat out-of-bounds read when checking trailing closing brace with bu_vls_addr(&str)[bu_vls_strlen(&str)-1] without verifying bu_vls_strlen > 0. |
| `SEC-0125` | `src/libbn/mat.c` | `80-140` | Buffer Overflow | 1 | `CONFIRMED` | `FIXED` | bn_mat_print_guts wrote into fixed obuf array without checking remaining capacity against bu_vls length, leading to potential buffer overflow. |
| `SEC-0126` | `src/libbn/mat.c` | `1000-1060` | Concurrency Data Race / Logic Bug | 1 | `CONFIRMED` | `FIXED` | bn_wrt_point_direc declared transformation matrices as static local variables, causing data corruption across concurrent raytracing threads, and had inverted translation vector origin_to_pt. |
| `SEC-0127` | `src/libbn/mat.c` | `1100-1200` | Division by Zero | 2 | `CONFIRMED` | `FIXED` | persp_mat and deering_persp_mat performed division by near_plane, right-left, and bottom-top without checking for zero denominators. |
| `SEC-0128` | `src/libbn/msr.c` | `120-135` | Memory Access / Use-After-Free Prevention | 2 | `CONFIRMED` | `FIXED` | bn_gauss_free lacked NULL pointer guard and failed to clear magic identifier before freeing heap structure. |
| `SEC-0129` | `src/libbn/mt19937ar.c` | `170-257` | Dead Code | 3 | `CONFIRMED` | `FIXED` | Dead #if 0 code block with test main function embedded within shared library source file. |
| `SEC-0130` | `src/libbn/multipoly.c` | `80-101` | Heap Memory Corruption | 1 | `CONFIRMED` | `FIXED` | bn_multipoly_grow realloc corruption passing outer pointer array P->cf instead of row array P->cf[i] with sizeof(double*) instead of sizeof(double), overwriting row pointers with pointer array address. |
| `SEC-0131` | `src/libbn/multipoly.c` | `80-101` | Out-of-bounds Access | 1 | `CONFIRMED` | `FIXED` | bn_multipoly_grow failed to update P->dgrs and P->dgrt dimensions after growing, leaving stale dimensions that caused subsequent operations to access out of bounds or fail to allocate. |
| `SEC-0132` | `src/libbn/multipoly.c` | `120-132` | Out-of-bounds Read | 1 | `CONFIRMED` | `FIXED` | bn_multipoly_add out-of-bounds read when polynomials had differing degrees, reading beyond allocated row bounds, and dimension calculation typo Max(p1->dgrt, p2->dgrs) instead of p2->dgrt. |
| `SEC-0133` | `src/libbn/multipoly.c` | `140-155` | Logic / Numerical Error | 1 | `CONFIRMED` | `FIXED` | bn_multipoly_mul overwrote accumulated product terms using = instead of +=, destroying earlier polynomial term contributions sharing identical combined powers. |
| `SEC-0134` | `src/libbn/multipoly.c` | `70-75` | Resource Leak | 1 | `CONFIRMED` | `FIXED` | Missing bn_multipoly_free function causing 100% memory leak of all 2D dynamically allocated bivariate polynomial matrices. |
| `SEC-0135` | `src/libbn/noise.c` | `248-430` | Null Pointer Dereference / Dead Code | 2 | `CONFIRMED` | `FIXED` | Missing NULL pointer validation on point and result in bn_noise_perlin, bn_noise_vec, and spectral functions; 22 lines of dead #if 0 code in bn_noise_mf. |
| `SEC-0136` | `src/libbn/noise.c` | `460-545` | Out-of-bounds Access / Allocation Flaw | 1 | `CONFIRMED` | `FIXED` | build_spec_tbl and find_spec_wgt allowed negative or zero octaves, leading to invalid memory allocation size (int)(octaves+1) <= 0 and out-of-bounds weight table indexing. |
| `SEC-0137` | `src/libbn/numgen.c` | `52-72` | Resource Leak / Typo | 1 | `CONFIRMED` | `FIXED` | bn_numgen_create allocated generator on the heap before validating dim > 0 and seed < 0, leaking the allocated structure on early return; nperiodic typo in flag check. |
| `SEC-0138` | `src/libbn/poly.c` | `50-168` | Memory Corruption / Pointer Aliasing | 1 | `CONFIRMED` | `FIXED` | In-place pointer aliasing in bn_poly_mul, bn_poly_add, and bn_poly_sub when destination pointer equaled one of the operand polynomials caused coefficients to be overwritten before being read. |
| `SEC-0139` | `src/libbn/poly.c` | `170-197` | Buffer Overflow / Unsigned Underflow | 1 | `CONFIRMED` | `FIXED` | bn_poly_synthetic_division assigned -1 to unsigned size_t quo->dgr when divisor degree exceeded dividend degree, underflowing to SIZE_MAX and triggering an unbounded loop writing past the 7-element coefficient array. |
| `SEC-0140` | `src/libbn/poly.c` | `200-488` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | Missing NULL pointer checks in bn_poly_quadratic_roots, bn_poly_cubic_roots, bn_poly_quartic_roots, bn_pr_poly, and bn_pr_roots. |
| `SEC-0141` | `src/libbn/qmath.c` | `84-331` | Memory Access Violation / Numerical Robustness | 2 | `CONFIRMED` | `FIXED` | In quat_mat2quat, negative diagonal difference caused NaN and division-by-zero on non-orthogonal matrices; acos() called on unconstrained dot products causing NaN domain errors; missing NULL pointer checks across quaternion math operations. |
| `SEC-0142` | `src/libbn/randsph.c` | `50-120` | Denial of Service / Memory Access Violation | 2 | `CONFIRMED` | `FIXED` | Potential infinite loop in _bn_unit_sph_sample when bn_randmt() yields exactly 0.5; possible NaN from sqrt(1 - S) when S slightly exceeds 1 due to floating-point rounding; unchecked return value from bn_sobol_next in _bn_unit_sph_sample_sobol. |
| `SEC-0143` | `src/libbn/sobol.c` | `148-325` | Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bn_sobol_create did not check the return status of sobol_init, creating partially initialized structures with NULL member pointers when sdim was invalid; rightzero32 had undefined behavior if invoked with 0xffffffffU; _sobol_urand and bn_sobol_next lacked NULL pointer checks. |
| `SEC-0144` | `src/libbn/sphmap.c` | `35-315` | Buffer Overflow / Resource Leak | 1 | `CONFIRMED` | `FIXED` | Heap buffer overflow in bn_spm_pix_load which allocated nx*nx*3 bytes instead of nx*ny*3 while reading nx*ny*3 bytes; permanent memory leak of buffer on fread failure; out-of-bounds array reads and writes in bn_spm_read, bn_spm_write, and bn_spm_get when u or v >= 1.0 or negative; bn_spm_free checked magic number before checking for NULL pointer. |
| `SEC-0145` | `src/libbn/str.c` | `42-177` | Uninitialized Memory Read | 2 | `CONFIRMED` | `FIXED` | bn_decode_mat, bn_decode_quat, and bn_decode_vect copied uninitialized stack memory into destination buffers when sscanf matched fewer items than required or failed; missing NULL pointer checks across decode and encode routines. |
| `SEC-0146` | `src/libbn/tabdata.c` | `35-1215` | Null Pointer Dereference / Resource Leak | 2 | `CONFIRMED` | `FIXED` | Second pass fopen in bn_read_table_and_tabdata was unchecked, causing NULL pointer dereference in bu_fgets if reopening failed; memory leak of allocated table/tabdata on read failure; unsigned integer underflow in bn_table_delete_sample_pnts when i > j; NULL pointer dereference in bn_table_free and bn_tabdata_free. |
| `SEC-0147` | `src/libbn/ulp.c` | `118-204` | Undefined Behavior | 2 | `CONFIRMED` | `FIXED` | Referenced non-existent union member d in union flt_bits (val.d += 1 and minVal.d = 1 << 23); undefined behavior in signed 32-bit shift 1 << 52 when setting 64-bit exponent. |
| `SEC-0148` | `src/libbn/wavelet.c` | `170-625` | Resource Leak | 1 | `CONFIRMED` | `FIXED` | Permanent memory leaks in make_wlt_haar_2d_decompose, make_wlt_haar_2d_reconstruct, and make_wlt_haar_2d_decompose2 when tbuffer/tbuf is NULL because allocated buffers were never freed; missing NULL buffer and zero dimension validation across wavelet routines. |
| `SEC-0149` | `src/libbn/tests/test_util.c` | `48-265` | Null Pointer Dereference | 1 | `CONFIRMED` | `FIXED` | Missing NULL pointer checks in test helper and test dispatch functions (mat_close, vect_close, hvect_close, finite_vec, orthonormal_rotation, normalize_quat, make_table, make_tabdata, bn_api_single, and bn_api_dispatch) when called with NULL pointers or empty argument lists. |
| `SEC-0150` | `src/libbg/pca.cpp` | `55-80` | Out-of-Bounds Read | 1 | `CONFIRMED` | `FIXED` | bg_pca computed Thin U on a 3xnpnts matrix using JacobiSVD. When npnts < 3, Thin U has fewer than 3 columns, causing out-of-bounds column reads and assertions when indexing svd.matrixU()(row, 1) and svd.matrixU()(row, 2). |
| `SEC-0151` | `src/libbg/pointgen.c` | `35-60` | Logic / Format String Flaw | 2 | `CONFIRMED` | `FIXED` | bg_sph_sample referenced undeclared variable sample instead of pnts[i], used %d format specifier for size_t integers in bu_log, checked sample instead of center for translation offset, and lacked defensive NULL pointer validation on pnts. |
| `SEC-0152` | `src/libbg/sat.cpp` | `44-175` | NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bg_sat_line_aabb, bg_sat_line_obb, bg_sat_tri_aabb, bg_sat_tri_obb, bg_sat_aabb_obb, and bg_sat_obb_obb called v3_from_array and axis_and_extent_from_vect without verifying point_t and vect_t pointer arguments, leading to null pointer dereferences. |
| `SEC-0153` | `src/libbg/lseg_lseg.cpp` | `37-45` | NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bg_distsq_lseg3_lseg3 unpacked input point arrays without null pointer validation and lacked extern C linkage in its C++ definition. |
| `SEC-0154` | `src/libbg/lseg_pt.cpp` | `36-45` | NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bg_distsq_lseg3_pt indexed point coordinates without checking for null pointers. |
| `SEC-0155` | `src/libbg/tri_pt.cpp` | `37-60` | NULL Pointer Dereference / Domain Error | 2 | `CONFIRMED` | `FIXED` | bg_tri_closest_pt indexed triangle vertices and sample points without null pointer checks and computed std::sqrt(result.sqrDistance) without non-negative clamping. |
| `SEC-0156` | `src/libbg/tri_ray.cpp` | `43-70` | NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | intersect_triangle and vec3_from_array dereferenced point and vector arguments without checking for null pointers. |
| `SEC-0157` | `src/libbg/util.c` | `50-145` | Divide by Zero / NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | coplanar_2d_coord_sys scaled origin by 1.0/n without verifying n >= 3, leading to division by zero if n <= 0 and undefined behavior for degenerate point sets. coplanar_3d_to_2d and coplanar_2d_to_3d lacked null checks on pointer parameters and count validation. |
| `SEC-0158` | `src/libbg/aabb_ray.c` | `31-143` | NULL Pointer Dereference / Deprecated Keyword | 3 | `CONFIRMED` | `FIXED` | bg_ray_invdir lacked null check on dir; bg_isect_aabb_ray lacked null checks on invdir, aabb_min, aabb_max, and opt; wrote into *r_min and *r_max without verifying destination pointers were non-null; used deprecated register storage class keywords. |
| `SEC-0159` | `src/libbg/obr.cpp` | `95-100` | Validation Flaw | 3 | `CONFIRMED` | `FIXED` | bg_3d_coplanar_obr accepted point count < 3 even though a 3D coplanar coordinate system requires at least 3 points to determine a plane normal. |
| `SEC-0160` | `src/libbg/polygon.c` | `144-205` | Buffer Overflow / Stack Buffer Corruption & Divide by Zero | 1 | `CONFIRMED` | `FIXED` | Operator precedence flaw in bg_3d_polygon_centroid where *cent[1] and *cent[2] evaluate to *(cent[1]) and *(cent[2]), writing 24 and 48 bytes out of bounds past caller's point_t stack/heap memory; uninitialized accumulation; division by zero when polygon is perpendicular to XY or XZ projection planes. |
| `SEC-0161` | `src/libbg/chull.c` | `50-185` | Out-of-bounds Read / Memory Leak | 2 | `CONFIRMED` | `FIXED` | Out-of-bounds read and negative deque index in bg_polyline_2d_chull when vertex count n < 3; permanent memory leaks in bg_3d_coplanar_chull of points_tmp and overwritten hull_2d pointer; missing NULL checks. |
| `SEC-0162` | `src/libbg/chull2.cpp` | `50-230` | Out-of-bounds Read / Memory Leak | 2 | `CONFIRMED` | `FIXED` | Out-of-bounds read and negative deque index in bg_polyline_2d_chull2 for n < 3; permanent memory leak of polyline in bg_2d_chull2; missing NULL parameter checks. |
| `SEC-0163` | `src/libbg/clip.c` | `60-140` | Divide by Zero / Thread-Safety Race Condition | 2 | `CONFIRMED` | `FIXED` | Division by zero in bg_lseg_clip for vertical or horizontal line segments; thread-safety race condition in bg_ray_vclip due to static local variables diff, sv, st, mindist, maxdist causing concurrent raytracing thread conflicts. |
| `SEC-0164` | `src/libbg/polygon_triangulate.cpp` | `873-970` | Memory Leak / Unchecked Return Value | 2 | `CONFIRMED` | `FIXED` | Unchecked return value of fopen in bg_tri_plot_2d causing NULL pointer dereference; permanent memory leaks of holes_array container and tri_out_pts in bg_polygon_triangulate; missing validation on polygon contour points. |
| `SEC-0165` | `src/libbg/tri_tri.c` | `180-715` | NULL Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | bg_tri_tri_isect_with_line unconditionally wrote to *coplanar, *isectpt1, and *isectpt2 without verifying destination pointers were non-null; missing NULL vertex validation across all triangle-triangle intersection routines. |
| `SEC-0166` | `src/libbg/polygon_op.cpp` | `45-470` | NULL Pointer Dereference / Divide by Zero | 2 | `CONFIRMED` | `FIXED` | Unchecked NULL pointer dereferences in bg_find_polygon_area, bg_polygons_overlap, load_polygon, and clipping routines; potential division by zero on zero scale factor. |
| `SEC-0167` | `src/libbg/polygon_point_in.c` | `40-51` | Integer Underflow / Out-of-bounds Read | 2 | `CONFIRMED` | `FIXED` | bg_pnt_in_polygon underflows j = nvert - 1 when nvert == 0 and allows nvert < 3 which is geometrically invalid for polygons; missing NULL pointer checks on pnts and test. |
| `SEC-0168` | `src/libbg/chull3d.cpp` | `115-210` | Out-of-bounds Read / Degenerate Buffer Access | 3 | `CONFIRMED` | `FIXED` | bg_3d_chull and bg_3d_chull2 did not check for empty vertexBuffer or undersized indexBuffer before allocating and indexing; out-of-bounds access in bg_3d_chull2 if face index exceeded vmap size. |
| `SEC-0169` | `src/libbg/vert_tree.c` | `140-180, 260-430` | Spatial Partitioning Stride Corruption / Resource Leak | 3 | `CONFIRMED` | `FIXED` | Stride indexing corruption in bg_vert_tree_add_w_norm where vertex coordinate data was accessed with stride 3 instead of stride 6 (ptr->vleaf.index * 3 vs index * 6), causing spatial partitioning corruption and reading wrong coordinate/normal data; permanent memory leaks in bg_vert_tree_destroy which failed to free the_array when the_tree was NULL and failed to free the bg_vert_tree container structure. |
| `SEC-0170` | `src/libbg/decimate.cpp` | `55-70, 160-175` | Truncated Integer Division / Overflow | 2 | `CONFIRMED` | `FIXED` | Truncated integer division in trimesh_decimate_simple (1/cbin.size()) where 1 / cbin.size() evaluated to integer 0 for any bin with >1 point, collapsing the point accumulator to world origin [0,0,0] instead of the bin centroid; missing n_ifaces integer overflow guard. |
| `SEC-0171` | `src/libbg/delaunator.hpp` | `40-55, 240-305` | Out-of-bounds Read / Unhandled Exception | 2 | `CONFIRMED` | `FIXED` | Out-of-bounds vector read in sum() on empty vector (indexing x[0]); out-of-bounds vector read and crash in Delaunator constructor when n < 3 or when seed points i0 or i1 are uninitialized (accessing coords[2 * INVALID_INDEX]); unhandled exception in bg_polygon_triangulate when Delaunator encounters degenerate collinear input. |
| `SEC-0172` | `src/libbg/ballpivot.cpp` | `30-75` | Unchecked Error Code / Parameter Validation | 2 | `CONFIRMED` | `FIXED` | Unchecked negative return code in bg_3d_ballpivot (if (nfaces == 0) instead of if (nfaces <= 0)), allowing negative face count to be passed into bg_trimesh_3d_gc; missing validation for radii_cnt < 0 or radii_cnt > 0 with NULL radii; missing initial NULL assignment to output pointers. |
| `SEC-0173` | `src/libbg/RTree.h` | `465-480, 1740-1800` | Unchecked File Operation / Null Dereference | 1 | `CONFIRMED` | `FIXED` | Unchecked fopen() return value in RTree::plot() and RTree::plot2d() leading to NULL pointer dereference on file write failure; missing NULL check on filename in RTFileStream::OpenRead and RTFileStream::OpenWrite; unguarded VertexDataSource count on NULL pointer in QuickHull.hpp. |
| `SEC-0174` | `src/libbg/polygon_triangulate.cpp` | `560-585` | Defensive Parameter Validation | 1 | `CONFIRMED` | `FIXED` | Missing parameter validation in bg_detria for faces, num_faces, poly, poly_pnts, pts, holes_array, holes_npts, and steiner, which could cause segmentation faults when called with NULL or undersized inputs. |
| `SEC-0175` | `src/libbg/trimesh.cpp` | `368-379, 458-465, 754, 789` | Pointer Corruption / Memory Leak / Logic Error | 3 | `CONFIRMED` | `FIXED` | In get_unmatched_edges, &unmatched was passed instead of unmatched to bg_trimesh_unmatched_edges with bg_trimesh_edge_gather, corrupting pointer memory; unmatched->count was used uninitialized in bu_calloc; edge_list was leaked permanently. In bg_trimesh_hanging_nodes, unmatched was leaked on all paths and memcpy was undersized (num_edges * 2 bytes instead of num_edges * 2 * sizeof(int)). In bg_trimesh_solid, a false positive solid result occurred when unmatched edges were zero but misoriented or excess edges existed, leaking memory and passing NULL to memcpy. |
| `SEC-0176` | `src/libbg/trimesh.cpp` | `812, 840-848, 876-878` | Out-of-Bounds Memory Access / Buffer Overflow | 2 | `CONFIRMED` | `FIXED` | Missing vertex index bounds validation in bg_trimesh_aabb, bg_trimesh_area, and bg_trimesh_volume allowed out-of-bounds reads into point array p and out-of-bounds writes into visit_vert bitvector when called with corrupted or invalid mesh face data. |
| `SEC-0177` | `src/libbg/trimesh_diff.cpp` | `67-77, 206-255, 313-348` | Logic Error / Inverted Topology Map | 2 | `CONFIRMED` | `FIXED` | In bg_trimesh_diff, ind_map_1 and ind_map_2 inverted the mapping from original to sorted vertex indices (ind_map[i] = orig_ind instead of ind_map[orig_ind] = i), and tri_2 indexed with f1 instead of f2, ignoring mesh 2 face data; bg_trimesh_hash had the same mapping inversion and an early break in its minimum vertex search loop; dbl_clamp could trigger float overflow on non-positive tolerance. |
| `SEC-0178` | `src/libbg/spsr.cpp` | `52-54, 105-178` | Unchecked Exception / Memory Leak / Input Validation | 2 | `CONFIRMED` | `FIXED` | In bg_3d_spsr, missing parameter validation on points, normals, and face pointers allowed NULL pointer dereferences; num_input_pnts < 3 caused solver failures; negative cnt in PtStream caused unsigned overflow; unhandled C++ exceptions escaping the extern C boundary leaked implicit solver memory and aborted the program. |
| `SEC-0179` | `src/libbg/trimesh_isect.cpp` | `56-74, 95-245, trimesh_plot3.cpp:82, 351-372` | Unchecked File Operation / Null Pointer Dereference / Division by Zero | 2 | `CONFIRMED` | `FIXED` | In trimesh_isect.cpp, plot_faces called pl_color on unchecked fopen() return, causing NULL pointer dereference on file write failure; bg_trimesh_isect failed to validate vertex indices in faces_1 and faces_2 against vertex counts, risking OOB access, and never assigned output intersecting faces. In trimesh_plot3.cpp, pntset_2d_plot3 used bitwise OR (!p | !c); polyline_2d_plot3 allowed division by zero on scale <= 0.0 and loop condition i < xy.size() - 1 dropped the last vertex before closing. |
| `SEC-0180` | `src/libbg/trimesh_remesh.cpp` | `82-87, trimesh_repair.cpp:126-131, trimesh_split.cpp:94-192, trimesh_sync.cpp:122` | Input Validation / Integer Overflow / Exception Safety | 1 | `CONFIRMED` | `FIXED` | Missing vertex index validation, integer overflow guards on face counts / allocation sizes, and unhandled C++ exceptions escaping extern C functions in bg_trimesh_remesh, bg_trimesh_repair, bg_trimesh_separate, bg_trimesh_split, and bg_trimesh_sync. |
| `SEC-0181` | `src/libbg/GTE/Mathematics/TriMesh.h` | `208-212, 536-580, 595-650, 715-775` | Undefined Behavior / Data Loss / Out-of-Bounds Memory Access | 1 | `CONFIRMED` | `FIXED` | status(EdgeHandle e) used reinterpret_cast<EdgeStatus&> on std::vector<bool>::operator[] proxy bit-reference yielding undefined behavior; TriMesh::garbage_collection() wiped face connectivity before reading vertices destroying active geometry; multiple handle and iterator methods lacked index bounds validation. |
| `SEC-0182` | `src/libbg/GTE/Mathematics/BotSmooth.h` | `85-115, BotSubdivide.h:48-95, 330-360` | Input Validation / Integer Overflow / Denial of Service | 2 | `CONFIRMED` | `FIXED` | Unchecked face vertex indices allowed out-of-bounds reads into vertex coordinate arrays in gte_bot_smooth and gte_bot_subdivide; unconstrained subdivision recursion levels allowed exponential memory allocation and integer overflow. |
| `SEC-0183` | `src/libbg/GTE/Mathematics/LSCMParameterization.h` | `96-120, 160-220, 275-310` | Input Validation / Division by Zero / Matrix Solvability | 2 | `CONFIRMED` | `FIXED` | Missing vertex index bounds checking on boundaryIndices, interiorIndices, and triangle vertex references when indexing vertices3D in MapBoundaryToCircle and Parameterize; unchecked linear system matrix dimensions could lead to division by zero or invalid memory access in SolveSymmetricCG. |
| `SEC-0184` | `src/libbg/GTE/Mathematics/MeshHoleFilling.h` | `275-320, 520-560, MeshPreprocessing.h:130-155, 225-255` | Out-of-Bounds Memory Access / Input Validation | 2 | `CONFIRMED` | `FIXED` | Unchecked triangle vertex indices allowed out-of-bounds reads in ComputeEarScore3D, ComputeTriangulationArea, TriangulateHoleLSCM, and MeshPreprocessing::ComputeTriangleArea / ComputeSignedVolume / RemoveSmallComponents. |
| `SEC-0185` | `src/libbg/GTE/Mathematics/MeshQuality.h` | `230-236, MeshValidation.h:122-138, 220-250, MeshRepair.h:200-215, 430-495, 600-630, 990-1005` | Null Pointer Dereference / Out-of-Bounds Array Access | 3 | `CONFIRMED` | `FIXED` | MeshQuality::ComputeTriangleRaw lacked null pointer validation for raw vertex pointers; MeshValidation::HasSelfIntersections and TriangleBoxesOverlap lacked empty mesh and vertex index bounds validation; MeshRepair lacked vertex index bounds validation in computeTotalArea, DetectIsolatedVertices, ColocateVertices, RelativeOrientation, Dissociate, and RemoveIsolatedVertices. |
| `SEC-0186` | `src/libbg/tests/polygon_op.c` | `55-80, 240-270` | Unsigned Integer Underflow / Out-of-Bounds Memory Access | 2 | `CONFIRMED` | `FIXED` | In _bg_polygon_diff, offset calculation size_t p2_ind = ((offset + j) >= c1->num_points) ? (j - offset) : (offset + j); produces an unsigned integer underflow when j < offset, wrapping p2_ind to SIZE_MAX and causing an out-of-bounds array access. In addition, unvalidated dcr2 dereferencing could crash on empty polygons, and plot_files contained a contour array dimension mismatch. |
| `SEC-0187` | `src/libbg/tests/bgtester.c` | `85-115, 230-260` | Stack Buffer Overflow / Potential Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | In parse_case, parameter arrays d, l, i, u were fixed 50-element stack buffers populated in a while loop without bounds checking, allowing stack buffer overflows on inputs exceeding 50 parameters. In main, token strings returned by strtok were dereferenced without checking for NULL. |
| `SEC-0188` | `src/libbg/tests/chull.c` | `40-70, obr.c:45-75` | Null Pointer Dereference / Logical Indexing Flaw | 3 | `CONFIRMED` | `FIXED` | In plot2d_chull, plot_chull3d, and plot_obr, fopen results were passed directly to pl_color and fclose without NULL verification, risking null pointer crashes if file creation failed. Additionally, plot2d_chull indexed pnt_array[i][0] when closing the polygon loop instead of pnt_array[0][Y]. |
| `SEC-0189` | `src/libbg/tests/plane_dist.c` | `35-50, lseg_pt.c:45-65, geogram_optimizer.cpp:55-80` | Division by Zero / Unchecked Parsing / Missing Pointer Validation | 3 | `CONFIRMED` | `FIXED` | In plane_dist.c, relative error calculation performed division by expected_return without checking for zero, resulting in division by zero (NaN/Inf). In lseg_pt.c, sscanf return counts were unchecked, allowing uninitialized stack values to be used. In geogram_optimizer.cpp, converged_optimizer was dereferenced without checking for NULL. |
| `SEC-0190` | `src/libbg/tests/poly2tri.c` | `110-180, chull.c:120-170, chull3d.c:70-130` | Resource Leak / Memory Management | 3 | `CONFIRMED` | `FIXED` | Dynamically allocated vertex, face, hole, and output polygon arrays allocated via bu_calloc/bu_malloc in poly2tri.c, chull.c, and chull3d.c were never freed prior to test completion or return, resulting in systematic memory leaks. |
| `SEC-0191` | `src/libbg/tests/polygon_triangulate.c` | `48-62, 134-150, 184-192, 225-237, 269-281, 298-306` | Resource Leak / Null Pointer Dereference | 3 | `CONFIRMED` | `FIXED` | Dynamically allocated face index arrays allocated by bg_poly_triangulate and bg_nested_poly_triangulate across all five test cases were never released via bu_free prior to block exit, causing memory leaks. In addition, _tess_report lacked validation guarding against NULL face and point arrays. |
| `SEC-0192` | `src/libbg/tests/tri_ray_isect.cpp` | `44-64, tri_tri_isect_coplanar.cpp:41-61` | Out-of-Bounds Substring / Unchecked Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | In read_point(), if an empty or whitespace-only argument was supplied, find_first_not_of returned std::string::npos, causing substr(sp, ep-sp+1) to throw an unhandled std::out_of_range exception. Additionally, input pointers p and arg were not validated before use, and sscanf return values in main were unchecked. |
| `SEC-0193` | `src/libbg/tests/tri_tri_isect.c` | `31-66, tri_closest_pt.c:43-53` | Uninitialized Stack Memory / Unchecked Input Parsing | 3 | `CONFIRMED` | `FIXED` | In tri_tri_isect.c, stack variables f1 and f2 were left uninitialized in declaration float f1, f2, f3 = 0.0;, and sscanf return counts were unchecked across all coordinate arguments in tri_tri_isect.c and tri_closest_pt.c, risking calculation using uninitialized stack coordinates upon malformed input. |
| `SEC-0194` | `src/libbg/tests/trimesh_sync.c` | `109-130, tri_area.c:49-53` | Null Pointer Dereference Guard / Code Quality | 3 | `CONFIRMED` | `FIXED` | In trimesh_sync.c, error reporting function parrays() dereferenced ff and ctrl pointers without verifying that they were non-NULL, risking null pointer dereferences during error handling. In tri_area.c, an extraneous duplicate semicolon was cleaned up. |
| `SEC-0195` | `src/libbg/geogram/NL/nl_matrix.c` | `765-780` | Out-of-Bounds Memory Access / Buffer Overflow | 2 | `CONFIRMED` | `FIXED` | In nlSparseMatrixConstruct, the row array was allocated with capacity m (NL_NEW_ARRAY(NLRowColumn, m)), but the row initialization loop mistakenly iterated up to n (for (i=0; i<n; i++)). If the column count n exceeded the row count m, this resulted in an out-of-bounds write past the allocated row buffer; if n < m, rows from n to m-1 remained uninitialized. |
| `SEC-0196` | `src/libbg/geogram/NL/nl_matrix.c` | `132-143` | Logic Error / Broken Comparator | 1 | `CONFIRMED` | `FIXED` | In nlCoeffCompare, the comparator callback returned (((NLCoeff*)(p2))->index < ((NLCoeff*)(p1))->index), returning only 0 or 1. It violated strict weak ordering required by qsort/bu_sort (never returning negative values when p1 < p2), risking non-deterministic sort order or sorting anomalies. |
| `SEC-0197` | `src/libbg/geogram/NL/nl_blas.c` | `1440-1455, 1495-1510` | Format String / Type Mismatch & Division by Zero | 2 | `CONFIRMED` | `FIXED` | In host_blas_show_stats, nlBlasGFlops() returns a double, but was passed to nl_printf using %d format specifier, risking register/stack corruption on 64-bit platforms. Furthermore, nlBlasGFlops() divided by elapsed_time without checking for zero elapsed time. |
| `SEC-0198` | `src/libbg/geogram/NL/nl_api.c, src/libbg/geogram/NL/nl_preconditioners.c` | `nl_api.c:660-675, nl_preconditioners.c:110-130, 215-265` | Divide-by-Zero / Floating Point Exception | 2 | `CONFIRMED` | `FIXED` | In nlNormalizeRow, the normalization divided by vector norm without checking if the norm was zero, leading to division by zero on degenerate rows. In Jacobi and SSOR preconditioners (nlNewJacobiPreconditioner, nlSparseMatrixMultLowerInverse, nlSparseMatrixMultUpperInverse), diagonal entries were divided without guards against zero diagonal entries. |
| `SEC-0199` | `src/libbg/geogram/NL/nl_private.h, src/libbg/geogram/NL/nl_os.c, src/libbg/geogram/NL/nl_amgcl.cpp` | `nl_private.h:288-300, nl_os.c:55-135, nl_amgcl.cpp:178-195` | Macro Hazard / Null Pointer Dereference Guard | 1 | `CONFIRMED` | `FIXED` | NL_DELETE and NL_DELETE_ARRAY macros expanded to multiple unbracketed statements (free(x); x = NULL), creating dangerous syntax and logic errors when used inside unbraced single-line conditionals. Error reporting and assertion handlers in nl_os.c lacked NULL checks on function pointers and format arguments. AMGCL solver interface in nl_amgcl.cpp lacked NULL checks on context, matrices, and vectors. |
| `SEC-0200` | `src/libbg/geogram/basic/attributes.cpp` | `390-405` | Buffer Overflow / Logic Error in Dimension Check | 3 | `CONFIRMED` | `FIXED` | In AttributesManager::copy_attribute, the compatibility check between existing attribute and destination attribute tested if ((store->size() != new_store->size()) && (store->dimension() != new_store->dimension()) && (store->element_size() != new_store->element_size())) using logical AND (&&) instead of logical OR (||). If the attributes had matching dimensions but differing element counts, the condition evaluated to false, allowing memcpy to copy an oversized source buffer into an undersized destination buffer, causing a critical heap buffer overflow. |
| `SEC-0201` | `src/libbg/geogram/basic/thread_sync.h` | `150-227` | Memory Leak / Missing Destructor & Dangling Pointer | 2 | `CONFIRMED` | `FIXED` | BasicSpinLockArray allocated heap memory via new spinlock[size_in], but lacked a destructor (~BasicSpinLockArray()), causing all allocated spinlock arrays to be leaked upon destruction. Furthermore, BasicSpinLockArray::clear() deleted the array without resetting size_ to 0 or spinlocks_ to nullptr, and CompactSpinLockArray::clear() did not reset spinlocks_ to nullptr, leaving dangling pointers. |
| `SEC-0202` | `src/libbg/geogram/basic/packed_arrays.cpp, src/libbg/geogram/basic/packed_arrays.h` | `packed_arrays.cpp:90-185, packed_arrays.h:160-165` | Memory Management Flaw / Out-of-Bounds Read & Write | 2 | `CONFIRMED` | `FIXED` | In PackedArrays, calloc return values were not checked for allocation failure. In resize_array, realloc(ZV_[array_index], 0) was invoked when shrinking to <= Z1_block_size_, risking platform-dependent memory leaks or undefined behavior, and the realloc return was directly assigned without failure handling. Array accessors (get_array, set_array, resize_array, array_size) lacked bounds checks on array_index in release mode. |
| `SEC-0203` | `src/libbg/geogram/basic/parallel.cpp, src/libbg/geogram/basic/permutation.h, src/libbg/geogram/basic/attributes.cpp` | `parallel.cpp:67-85, permutation.h:158-240, attributes.cpp:160-180` | Integer Underflow & Unbounded Stack Allocation | 2 | `CONFIRMED` | `FIXED` | In parallel_for, if from >= to, unsigned integer subtraction to - from underflowed to a massive positive number (~4 billion), causing thread spawning loops with out-of-bounds tasks. In Permutation::apply and AttributeStore::swap_items, BRLCAD_ALLOCA was invoked unconditionally on element sizes, risking stack overflow on large elements. In Permutation::apply(vector<T>&, ...), mismatch between data size and permutation size was not checked, violating documented contract and causing out-of-bounds access. |
| `SEC-0204` | `src/libbg/geogram/basic/assert.h, src/libbg/geogram/basic/memory.h, src/libbg/geogram/basic/geometry_nd.h, src/libbg/geogram/basic/rationalg.h, src/libbg/geogram/basic/vecg.h` | `assert.h:145-215, memory.h:390-485, geometry_nd.h:215-295, rationalg.h:540-550, vecg.h:180-195` | Macro Precedence Hazards & Divide-by-Zero / Floating-Point Exception | 1 | `CONFIRMED` | `FIXED` | Assertions in assert.h were defined with raw braces { ... } rather than do { ... } while(0), causing dangling-else and syntax errors in conditional contexts. geo_aligned_alloca macro parameter was unparenthesized. Memory::aligned_allocator::allocate lacked integer overflow check on size * sizeof(T). triangle_area lacked max(A2, 0.0) guard causing sqrt(negative) NaNs, and triangle_circumcenter divided by determinant without zero check. rationalg::estimate() divided by denominator without zero check. vecng initializer_list constructor lacked bounds check on iteration count. |
| `SEC-0205` | `src/libbg/geogram/mesh/index.h, src/libbg/geogram/mesh/mesh.h, src/libbg/geogram/mesh/mesh.cpp` | `index.h:70-130, mesh.h:200-475, mesh.cpp:115-460` | Out-of-Bounds Memory Access & Integer Overflow | 2 | `CONFIRMED` | `FIXED` | In MeshCells::pop(), cell_ptr_[nb()-1] was accessed unconditionally; simplicial meshes store an empty or single-element cell_ptr_, resulting in heap out-of-bounds reads. In MeshVertices::copy, point_ptr(0) was called when rhs.nb() == 0, accessing beyond empty buffers. In Mesh::get_subelements_by_type and get_subelements_by_index, invalid queries dereferenced null pointers *(MeshSubElementsStore*)nullptr. Index classes left buffer arrays uninitialized in default constructors. create_sub_elements and reserve lacked integer multiplication overflow guards. In connect_tets and connect, corrupt facet/cell vertex indices were not validated against vertices_.nb(). |
| `SEC-0206` | `src/libbg/geogram/mesh/mesh_AABB.h, src/libbg/geogram/mesh/mesh_AABB.cpp` | `mesh_AABB.h:45-1250, mesh_AABB.cpp:35-180` | Divide-by-Zero & Out-of-Bounds Vector Access | 2 | `CONFIRMED` | `FIXED` | In ray_triangle_intersection, 1.0 / det was calculated prior to checking whether fabs(det) >= 1e-20, causing floating-point division by zero and NaN/Inf propagation on rays coplanar to triangle planes. Querying or intersecting AABB trees built on empty meshes (nb() == 0) accessed bboxes_[1] out-of-bounds and caused infinite recursion in max_node_index. |
| `SEC-0207` | `src/libbg/geogram/mesh/mesh_geometry.h, src/libbg/geogram/mesh/mesh_geometry.cpp, src/libbg/geogram/mesh/mesh_halfedges.cpp` | `mesh_geometry.h:210-240, mesh_geometry.cpp:80-160, mesh_halfedges.cpp:60-145` | Divide-by-Zero & Denial of Service / Process Abort | 1 | `CONFIRMED` | `FIXED` | mesh_facet_center and mesh_cell_center divided by corner/vertex counts without checking for empty facets/cells (0 count). In mesh_geometry.cpp, normalize was called on zero vectors, and bounding box functions did not validate null output pointers or zero-vertex meshes. In MeshHalfedges, border and vertex traversals on non-manifold or cyclical meshes aborted the process via geo_assert_not_reached or geo_assert(count < 10000) instead of gracefully failing. |
| `SEC-0208` | `src/libbg/geogram/mesh/mesh_repair.cpp, src/libbg/geogram/mesh/mesh_preprocessing.h, src/libbg/geogram/mesh/mesh_preprocessing.cpp, src/libbg/geogram/mesh/mesh_topology.cpp` | `mesh_repair.cpp:65-175, 490-590, 665-685, 820-840, 920-1010, 1145-1215; mesh_preprocessing.h:77; mesh_preprocessing.cpp:65-135; mesh_topology.cpp:48-105` | Out-of-Bounds Memory Access, Stack Exhaustion & Process Abort | 2 | `CONFIRMED` | `FIXED` | In repair_connect_facets, v2c[v1], c2f[c2], and next_c_around_v[c] were indexed without validating vertex/corner indices against mesh element counts, causing out-of-bounds array reads. facet_is_degenerate and normalize_facet_vertices_order performed unbounded BRLCAD_ALLOCA stack allocations for vertex arrays on arbitrary polygonal facets without heap fallback, causing stack overflow vulnerabilities. find_corner, repair_propagate_orientation, and SimplePriorityQueue::pop aborted the process on malformed topological meshes via geo_assert_not_reached. mesh_colocate_vertices_no_check indexed old2new without bounds checks. In mesh_preprocessing.cpp and mesh_topology.cpp, empty meshes or unbound attributes resulted in out-of-bounds indexing in component traversal and signed volume calculation. |
| `SEC-0209` | `src/libbg/geogram/mesh/mesh_reorder.cpp, src/libbg/geogram/mesh/mesh_remesh.cpp` | `mesh_reorder.cpp:280-295, 430-445, 570-585, 935-945, 1115-1175; mesh_remesh.cpp:75-80, 125-140, 150-165, 205-255, 285-295, 470-505` | Divide-by-Zero & Out-of-Bounds Buffer Indexing | 2 | `CONFIRMED` | `FIXED` | In mesh_reorder.cpp, Base_fcmp::center and Base_ccmp::center computed 1.0 / double(nb_vertices) without checking nb_vertices == 0, causing floating-point division by zero; Base_tcmp accessed 4 cell vertices without validating vertex count. In mesh_remesh.cpp, remesh_smooth and mesh_adjust_surface crashed or had undefined behavior on empty meshes or meshes with dimension < 3; mesh_adjust_surface divided by double(d) on facets with 0 vertices; create_ribbon_on_border called normalize on zero-length normal vectors, causing NaNs. |
| `SEC-0210` | `src/libbg/geogram/mesh/mesh_sampling.h` | `mesh_sampling.h:68-95, 120-165, 215-265, 285-335` | Divide-by-Zero & Buffer Overflow | 2 | `CONFIRMED` | `FIXED` | In mesh_generate_random_samples_on_surface and mesh_generate_random_samples_in_volume, division by total area (Atot) and total volume (Vtot) occurred without checking Atot <= 0.0 or Vtot <= 0.0, resulting in division by zero and NaN sample coordinates on degenerate meshes. mesh_facet_mass and mesh_tetra_mass lacked bounds checking on facet/cell vertex counts and attribute arrays, potentially reading out of bounds. |
| `SEC-0211` | `src/libbg/geogram/delaunay/delaunay.cpp, src/libbg/geogram/delaunay/delaunay.h` | `delaunay.cpp:115-180, 245-290; delaunay.h:200-245` | Out-of-Bounds Memory Access & Assertion Abort | 2 | `CONFIRMED` | `FIXED` | In delaunay.cpp (update_v_to_cell, update_cicl, get_neighbors_internal, save_histogram), missing bounds checks on vertex and cell indices allowed out-of-bounds writes to v_to_cell_ and cicl_ on corrupted mesh topology or NO_INDEX vertices. In save_histogram, an off-by-one check (histogram.size() <= N instead of < N) allowed out-of-bounds array writes. In delaunay.h, geo_assert_not_reached() was called on unlinked cells causing process crashes instead of graceful failure. |
| `SEC-0212` | `src/libbg/geogram/delaunay/delaunay_nn.cpp` | `delaunay_nn.cpp:120-195, 230-310` | Stack Exhaustion & Unbounded Allocation | 2 | `CONFIRMED` | `FIXED` | In delaunay_nn.cpp (enlarge_neighborhood, store_neighbors_CB, get_neighbors_internal), unbounded BRLCAD_ALLOCA was used for neighbor candidate and distance arrays proportional to requested neighbor counts. High neighbor counts or deep recursion could exhaust thread call stacks causing stack overflow crashes. Additionally, float equality comparison against 0.0 triggered compiler warnings. |
| `SEC-0213` | `src/libbg/geogram/points/colocate.cpp` | `colocate.cpp:85-150` | Stack Exhaustion & Unbounded Allocation | 2 | `CONFIRMED` | `FIXED` | In Colocate::find_nearest_neighbors, unbounded BRLCAD_ALLOCA was invoked per point for neighbor query arrays based on requested neighbor counts, creating risk of stack overflow on large neighbor queries. |
| `SEC-0214` | `src/libbg/geogram/points/kd_tree.cpp, src/libbg/geogram/points/kd_tree.h` | `kd_tree.h:110-145; kd_tree.cpp:180-260, 410-480, 520-600` | Uninitialized Memory, Out-of-Bounds Access & Infinite Recursion | 3 | `CONFIRMED` | `FIXED` | In kd_tree.h, KdTree::NearestNeighbors constructor initialized loop condition with nb_neighbors (which was 0) instead of nb_neighbors_max, leaving neighbor index and distance arrays uninitialized and leaking memory to user callers via copy_to_user(). In kd_tree.cpp, AdaptiveKdTree::split_kd_node failed to clamp split point m, resulting in child nodes duplicating parent intervals [b, e) and causing infinite recursion and call stack exhaustion. KdTree::get_nearest_neighbors_leaf used fixed-size stack arrays local_idx[MAX_LEAF_SIZE] without checking e - b <= MAX_LEAF_SIZE. BalancedKdTree::get_node and AdaptiveKdTree::get_node lacked bounds checks on node index n. |
| `SEC-0215` | `src/libbg/geogram/points/nn_search.cpp, src/libbg/geogram/points/nn_search.h` | `nn_search.h:70-90; nn_search.cpp:45-75` | Out-of-Bounds Access & Assertion Abort | 2 | `CONFIRMED` | `FIXED` | In nn_search.cpp (get_nearest_neighbors), query point index q_index was not validated against nb_points(), risking out-of-bounds point access. In nn_search.h (get_nearest_neighbor), geo_assert(result < nb_points()) triggered process abort when no neighbors were found on empty point sets instead of returning NO_INDEX. |
| `SEC-0216` | `src/libbg/geogram/numerics/multi_precision.cpp, src/libbg/geogram/numerics/multi_precision.h` | `multi_precision.h:115-125; multi_precision.cpp:80-145, 595-610` | Memory Corruption & Heap Buffer Under-Allocation | 3 | `CONFIRMED` | `FIXED` | In multi_precision.cpp, Pools::malloc, Pools::free, and Pools::new_chunk assumed item_size was at least sizeof(Memory::pointer), but for item_size < sizeof(void*) on 64-bit systems, casting chunk memory to Memory::pointer* wrote 8 bytes into smaller slots (such as 4-byte expansion headers), causing heap metadata and adjacent block corruption. In Pools::free, null pointer dereferences were not guarded. In Pools::new_chunk, raw allocation without try-catch risked inconsistent pool state on allocation failure. In multi_precision.h, expansion_allocator::bytes(capa) calculated byte requirements using unchecked 32-bit arithmetic, risking integer overflow on large capacities. |
| `SEC-0217` | `src/libbg/geogram/numerics/multi_precision.cpp` | `multi_precision.cpp:215-230, 240-275, 305-330, 680-720` | Out-of-Bounds Memory Access & Integer Underflow | 2 | `CONFIRMED` | `FIXED` | In multi_precision.cpp, compress_expansion performed index arithmetic m - 1 without verifying e.length() > 1. For length 0 or 1, m underflowed to 0xFFFFFFFF, resulting in massive out-of-bounds heap reads and writes. In scale_expansion_zeroelim, fast_expansion_sum_zeroelim, and fast_expansion_diff_zeroelim, expansions were accessed at index 0 without checking for zero-length inputs, reading uninitialized or unallocated heap memory. In assign_sq_dist and assign_dot_at, coordinate dimension dim == 0 caused underflow dim - 1 and unbounded recursion. |
| `SEC-0218` | `src/libbg/geogram/numerics/predicates.cpp, src/libbg/geogram/numerics/PCK.h` | `PCK.h:170-175; predicates.cpp:445-460, 620-635, 960-975, 1130-1145, 1395-1410, 1535-1550` | Assertion Failure Denial-of-Service Crashes | 2 | `CONFIRMED` | `FIXED` | In predicates.cpp, exact predicate implementations asserted that primary determinant minors were non-zero (geo_assert(Delta_sign != ZERO)). When degenerate, collinear, or coplanar input configurations occurred, these assertions aborted the process via SIGABRT instead of gracefully returning ZERO or falling back to symbolic perturbation. In PCK.h, SOS() macro asserted geo_assert_not_reached on invalid SOSMode instead of gracefully returning ZERO. |
| `SEC-0219` | `src/libbg/geogram/numerics/predicates.cpp, src/libbg/geogram/numerics/predicates.h, src/libbg/geogram/numerics/PCK.cpp` | `PCK.cpp:25-35; predicates.h:260-275; predicates.cpp:1640-2260` | Mathematical Logic Flaw & Missing Pointer Validation | 2 | `CONFIRMED` | `FIXED` | In predicates.cpp (PCK::dot_3d), det_3d_filter(p0, p1, p2) was erroneously invoked instead of dot_3d_filter(p0, p1, p2), returning the sign of a 3x3 determinant rather than the dot product whenever the determinant filter succeeded. Across predicates.cpp and predicates.h, geometric predicate functions lacked null pointer checks for double* coordinate arrays, causing segmentation faults on null pointers. In PCK.cpp, percent(a, b) lacked division-by-zero protection when b == 0. |
| `SEC-0220` | `src/libbg/geogram/voronoi/RVD.cpp` | `1754-1775, 1810-1855, 2480-2500, 2535-2587` | Use-After-Free / Dangling Pointer & Missing Null Validation | 3 | `CONFIRMED` | `FIXED` | In prepare_projection(), mesh_vertices_ held a raw pointer to a local vector<double> destroyed upon function return, causing project_points_on_surface() to read through a dangling pointer (use-after-free). In RestrictedVoronoiDiagram::create, delaunay was dereferenced prior to checking for null pointer. |
| `SEC-0221` | `src/libbg/geogram/voronoi/generic_RVD_utils.h, src/libbg/geogram/voronoi/generic_RVD_vertex.h` | `generic_RVD_utils.h:45-55, 275-290, 345-385; generic_RVD_vertex.h:175-195, 240-260, 270-300, 725-770` | Buffer Overflow, Integer Shift Overflow, Unchecked Realloc & Vector Stack Underflow | 2 | `CONFIRMED` | `FIXED` | In generic_RVD_utils.h, VectorStack::pop() called pop_back() on empty vectors causing out-of-bounds underflow; array_capacity computed 1 << (result - 1) with 32-bit signed shift that overflowed on large capacities; and insert() directly reassigned realloc return pointers without failure validation. In generic_RVD_vertex.h, small_set appended past capacity DIM without bounds checks; PointAllocator lacked chunk allocation failure handling and bounds checks. |
| `SEC-0222` | `src/libbg/geogram/voronoi/generic_RVD_cell.cpp, src/libbg/geogram/voronoi/generic_RVD_polygon.cpp, src/libbg/geogram/voronoi/RVD_callback.cpp, src/libbg/geogram/voronoi/RVD.cpp` | `generic_RVD_cell.cpp:635-645, 1020-1040; generic_RVD_polygon.cpp:520-530; RVD_callback.cpp:80-95; RVD.cpp:1620-1695, 2410-2420, 2580-2585` | Denial-of-Service Assertion Aborts & Unchecked Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In side_exact, initialize_from_surface_mesh, triangulate_polygon, run_thread, and RestrictedVoronoiDiagram::create, assertions geo_assert and geo_assert_not_reached were triggered on non-simplex facets, unexpected topology, or unhandled dimensions, terminating the process via SIGABRT. |
| `SEC-0223` | `src/libbg/geogram/voronoi/CVT.cpp, src/libbg/geogram/voronoi/CVT.h` | `CVT.h:120-140, 195-215; CVT.cpp:60-80, 135-155, 175-195, 230-260, 310-340, 360-390` | Out-of-Bounds Access, Missing Null Guards & Zero Division | 2 | `CONFIRMED` | `FIXED` | In CVT.cpp and CVT.h, constructors and member methods accepted Mesh* and double* pointers without null validation, accessed empty embedding vectors, and performed unvalidated indexing and division when dimension_ or point counts were zero. |
| `SEC-0224` | `src/libbg/geogram/third_party/LBFGSpp/include/LBFGS.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSB.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/BFGSMat.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/BKLDLT.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/Cauchy.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/LineSearchBacktracking.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/LineSearchBracketing.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/LineSearchMoreThuente.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/LineSearchNocedalWright.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/Param.h, src/libbg/geogram/third_party/LBFGSpp/include/LBFGSpp/SubspaceMin.h` | `LBFGS.h:170-175, 230-240; LBFGSB.h:205-215; BFGSMat.h:115-125, 270-340, 480-505; BKLDLT.h:80-95, 125-140, 160-175; Cauchy.h:120-145, 175-190; LineSearchMoreThuente.h:34-55, 71-125; LineSearchNocedalWright.h:42-50, 94-98; Param.h:210, 368; SubspaceMin.h:44-58, 134-138` | Division by Zero, Out-of-bounds Vector Access & Dimension Validation | 2 | `CONFIRMED` | `FIXED` | In LBFGSpp optimization routines, missing zero guards on matrix determinants, Hessian eigenvalues, line search denominators, and empty input vector dimensions allowed potential divisions by zero, infinite loops, and out-of-bounds array access on degenerate or singular optimization problems. |
| `SEC-0225` | `src/libbg/geogram/third_party/amgcl/amgcl/adapter/zero_copy.hpp, src/libbg/geogram/third_party/amgcl/amgcl/amg.hpp, src/libbg/geogram/third_party/amgcl/amgcl/backend/builtin.hpp, src/libbg/geogram/third_party/amgcl/amgcl/backend/detail/matrix_ops.hpp, src/libbg/geogram/third_party/amgcl/amgcl/backend/interface.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/detail/galerkin.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/plain_aggregates.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/pointwise_aggregates.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/smoothed_aggr_emin.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/smoothed_aggregation.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/tentative_prolongation.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/inverse.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/qr.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/sort_row.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/spgemm.hpp, src/libbg/geogram/third_party/amgcl/amgcl/make_solver.hpp, src/libbg/geogram/third_party/amgcl/amgcl/preconditioner/dummy.hpp, src/libbg/geogram/third_party/amgcl/amgcl/relaxation/spai0.hpp, src/libbg/geogram/third_party/amgcl/amgcl/reorder/cuthill_mckee.hpp, src/libbg/geogram/third_party/amgcl/amgcl/solver/cg.hpp, src/libbg/geogram/third_party/amgcl/amgcl/solver/skyline_lu.hpp, src/libbg/geogram/third_party/amgcl/amgcl/util.hpp, src/libbg/geogram/third_party/amgcl/amgcl/value_type/interface.hpp` | `zero_copy.hpp:95-105; amg.hpp:145-180, 205-220; builtin.hpp:170-195, 410-440, 520-565; matrix_ops.hpp:75-95; interface.hpp:85-95; galerkin.hpp:60-70; plain_aggregates.hpp:115-130, 160-198; pointwise_aggregates.hpp:80-140, 150-178; smoothed_aggr_emin.hpp:90-100, 170-220, 255-345; smoothed_aggregation.hpp:120-165, 190-220; tentative_prolongation.hpp:50-60, 95-175; inverse.hpp:45-75; qr.hpp:155-205, 385-405, 580-600; sort_row.hpp:35-45; spgemm.hpp:70-125, 425-460; make_solver.hpp:88-100; dummy.hpp:80-105; spai0.hpp:75-115; cuthill_mckee.hpp:80-165; cg.hpp:145-205; skyline_lu.hpp:100-175, 185-255; util.hpp:205-225; interface.hpp:145-155` | Out-of-bounds Array Access, Null Dereference, Division by Zero & Traversal Flaw | 2 | `CONFIRMED` | `FIXED` | In AMGCL solver and preconditioner routines, missing bounds checks on row/column indices and negative aggregate IDs allowed out-of-bounds array reads and writes. Missing checks for singular pivots, zero denominators, and zero spectral radius allowed divisions by zero. Unchecked matrix and vector pointers allowed null pointer dereferences. A loop condition logic error in Cuthill-McKee reordering skipped node 0 during graph level set traversal. |
| `SEC-0226` | `src/libbrep/BBNode.cpp, src/libbrep/BRNode.cpp, src/libbrep/PullbackCurve.cpp, src/libbrep/Subcurve.cpp, src/libbrep/Subsurface.cpp, src/libbrep/assembly.cpp, src/libbrep/boolean.cpp, src/libbrep/brep_defines.h` | `BBNode.cpp:137, 209-214, 230-265, 305-325, 345-350, 400-410, 498-504, 508-525, 560-610; BRNode.cpp:60-65, 105-110, 260-295, 360-400, 412-420, 514-520; PullbackCurve.cpp:3190-3195, 3380-3386, 3390-3475, 3505-3590, 3820-3825, 4578-4581, 5359-5363; Subcurve.cpp:49, 69-93; Subsurface.cpp:50, 72-118; assembly.cpp:58-75, 353-402, 456-458; boolean.cpp:98, 142-225, 3356-3395; brep_defines.h:64` | Null Pointer Dereference, Division by Zero, Out-of-bounds Array Access | 2 | `CONFIRMED` | `FIXED` | In libbrep core evaluation, trimming, assembly, and pullback routines, missing null checks on curve, surface, face, and child pointers could result in null pointer dereferences. Missing checks against zero denominators in cubic curve interpolation, knot intervals, Newton solver steps, and basis control ratio calculations could cause division by zero. Edge index parameters in edge merging routines lacked array bounds checks before indexing brep edge tables. |
| `SEC-0227` | `src/libbrep/debug_plot.cpp, src/libbrep/edit.cpp, src/libbrep/px_event.cpp, src/libbrep/quality.cpp, src/libbrep/ssx_event.cpp` | `debug_plot.cpp:137; edit.cpp:556-563, 680, 699-718, 832, 858-876; px_event.cpp:35-50; quality.cpp:70, 222-241; ssx_event.cpp:82-112` | Null Pointer Dereference, Division by Zero, Out-of-bounds Array Access, Incorrect Comparison Logic | 2 | `CONFIRMED` | `FIXED` | ON_PX_EVENT::Compare() had inverted null-pointer return values and returned bool instead of proper 3-way int; DumpSSXEvent() dereferenced curve pointers without null checks; bbox_contains() operated on potentially invalid points; edge quality loop accessed vertex and trim arrays without bounds checks; brep_edge_create() lacked index bounds validation; calculateTangentVectors(), getPosRoot(), bsplineBasisFuns(), and solveTridiagonalint() had unguarded divisions; write_plot_to_file() used fopen() result without NULL check. |
| `SEC-0228` | `src/libbrep/cdt/cdt.cpp, src/libbrep/cdt/cdt_util.cpp, src/libbrep/cdt/mesh.cpp, src/libbrep/cdt/ovlps_simple.cpp, src/libbrep/cdt/surf.cpp, src/libbrep/cdt/tri_isect.cpp` | `cdt.cpp:755-763; cdt_util.cpp:39, 159, 180, 205, 230, 246, 262; mesh.cpp:176, 198, 225-245, 1301, 1391, 2648, 4139, 4252, 4276, 4304, 4322, 4344, 4362, 4380, 4412, 4474, 4521, 4536, 4550, 4565, 4617, 5124, 5896, 5908, 6167; ovlps_simple.cpp:315, 388-396; surf.cpp:140; tri_isect.cpp:120` | Null Pointer Dereference, Out-of-bounds Vector Access, Resource Leaks | 2 | `CONFIRMED` | `FIXED` | In libbrep CDT routines, missing size validation and null pointer checks on bedge_seg_t::uedges() in cdt.cpp and ovlps_simple.cpp caused potential out-of-bounds vector access and null pointer dereferences when accessing face meshes. In mesh.cpp, bedge_seg_t::uedges() dereferenced CDT state pointers, trim indices, face pointers, and polygon pointers without validation. Across mesh.cpp, cdt_util.cpp, tri_isect.cpp, and surf.cpp, pervasive unchecked fopen() return values in debug and plotting routines caused potential NULL pointer dereferences when writing to plot files. |
| `SEC-0229` | `src/libbrep/shape_recognition/cone.cpp, src/libbrep/shape_recognition/cylinder.cpp, src/libbrep/shape_recognition/pipeline.cpp, src/libbrep/shape_recognition/planar.cpp, src/libbrep/shape_recognition/shape_recognition.cpp, src/libbrep/shape_recognition/sphere.cpp, src/libbrep/shape_recognition/sr_util.cpp, src/libbrep/shape_recognition/torus.cpp` | `cone.cpp:42-100, 116-242; cylinder.cpp:45-165, 184-358; pipeline.cpp:40-173, 280-410; planar.cpp:201-230, 294-352, 503-510, 531-547, 748-855, 960-1010; shape_recognition.cpp:163-171, 347-353, 410-454, 525-591; sphere.cpp:40-95, 115-180, 187-200; sr_util.cpp:42-75, 189-195, 248-256, 508-515, 626-635; torus.cpp:36-192` | Memory Access Violation, Out-of-bounds Array Access, Memory Leaks, Division by Zero, Null Pointer Dereference | 2 | `CONFIRMED` | `FIXED` | In planar.cpp, an off-by-one loop condition j <= array_end - array_start caused out-of-bounds read and write in triangulate_array_with_holes; outer_pt_ind, holes arrays, vert_map, and loop_starts leaked on every triangulation; BU_PTBL_GET dereferenced empty island_children causing null dereference crash; in cylinder.cpp, points[3] was accessed without checking points count > 3, and implicit_plane_ind was indexed without bounds checks; in cone.cpp, loop over cone planes indexed plane 1 when count was 1, and sin(C) was divided without zero checking; in pipeline.cpp, nde array leaked across multiple return paths, and nonplanar_surfaces was dereferenced when empty; in shape_recognition.cpp, unchecked fol_to_i iterator dereference caused crash, subbrep_shoal_data leaked when shoal_csg failed, and face_surface_types and uninserted sb leaked on failure; in sr_util.cpp, BU_PUT for obj->nucleus erroneously freed subbrep_shoal_data with struct csg_obj_params size/tag, and empty face->m_li caused out-of-bounds loop access; in sphere.cpp, a typo c2->IsArc(NULL, &a1) left a2 uninitialized and leaked curve duplicates c1 and c2; in torus.cpp, arc loop leaked curve ecv and ep_normal was incorrectly set to torus.plane.Normal(). |
| `SEC-0230` | `src/libbrep/tools/tools.cpp, src/libbrep/tools/tools_util.cpp, src/libbrep/tests/brep_cdt_hole_face17.c, src/libbrep/tests/brep_cdt_hole_face27.c, src/libbrep/tests/brep_cdt_invalid.cpp, src/libbrep/tests/brep_cdt_mesh.cpp, src/libbrep/tests/assembly.cpp, src/libbrep/tests/ppx.cpp, src/libbrep/tests/pullback_context.cpp, src/libbrep/tests/test_curve_intersect.cpp, src/libbrep/tests/test_point_intersect.cpp` | `tools.cpp:43-70, 83-143, 197-286; tools_util.cpp:40-49, 83-148, 158-180, 182-228, 230-271; brep_cdt_mesh.cpp:27-48; brep_cdt_hole_face17.c:22-35, 3360-3415; brep_cdt_hole_face27.c:22-35, 6300-6355; assembly.cpp:103-109; ppx.cpp:218-225; pullback_context.cpp:504-512; test_curve_intersect.cpp:35-85; test_point_intersect.cpp:45-145` | Memory Leaks, Uncontrolled Recursion, Out-of-bounds Array Access, Null Pointer Dereference, Logic Error | 2 | `CONFIRMED` | `FIXED` | In libbrep tools and tests: in tools.cpp, find_next_point placed recursion limit inside else block, causing infinite recursion and stack exhaustion; ON_Curve_Get_Tangent and ON_Curve_Has_Tangent lacked null pointer and direction bounds checks; in ON_Surface_IsStraight, frames[0] and frames[1] were repeatedly indexed instead of frames[i] and frames[j]; in tools_util.cpp, ON_BrepTikz leaked duplicate edge curves on non-linear edges, and lacked null pointer and array bounds checks; in brep_cdt_mesh.cpp, invalid argument count printed usage but proceeded without exiting, dereferencing invalid argv[1]; in brep_cdt_hole_face17.c and brep_cdt_hole_face27.c, multiple heap-allocated arrays leaked on test completion; across test executables, argv[0] was passed to bu_setprogname without validating argc > 0 and argv != NULL. |
| `SEC-0231` | `src/libfft/fftfast.c, src/libfft/splitdit.c, src/libfft/ditsplit.c, src/libfft/fftc.c, src/libfft/ifftc.c, src/libfft/splitditc.c, src/libfft/ditsplitc.c, src/libfft/fftest.c` | `fftfast.c:54-85, 120-165, 203-245, 290-345; splitdit.c:33-40; ditsplit.c:39-46; fftc.c:45-75; ifftc.c:44-75; splitditc.c:44-60; ditsplitc.c:46-62; fftest.c:39-60` | Infinite Loop Denial of Service, Null Pointer Dereference, Division by Zero, Missing Bounds Validation | 2 | `CONFIRMED` | `FIXED` | In libfft routines: in fftfast.c, init_sintab hung in an infinite loop if size was zero or negative, calloc return values were unchecked leading to null pointer dereferences, cdiv divided by sum-of-squares without checking for zero, and cfft, icfft, scramble, butterflies, and complex arithmetic functions lacked null pointer checks on data/result pointers. In splitdit.c and ditsplit.c, rfft and irfft lacked null checks and minimum length validation on input arrays. In fftc.c and ifftc.c, parse_fft_length permitted invalid size 1 and lacked upper bound checks, and main dereferenced argv without pointer validation. In splitditc.c and ditsplitc.c, generator functions lacked minimum dimension guards and embedded full source file paths. |
| `SEC-0232` | `src/libtermio/libtermio.h, src/libtermio/linenoise.hpp` | `libtermio.h:176-215, 235-360, 780-795, 1100-1155; linenoise.hpp:2015-2060, 2075-2125, 2215-2240, 2325-2385, 2690-2740` | Buffer Overflow, Out-of-Bounds Array Access, Division by Zero & Missing Pointer Validation | 2 | `CONFIRMED` | `FIXED` | In libtermio: in libtermio.h, terminal parameter storage arrays save_tio and curr_tio were sized FOPEN_MAX (which can be as low as 20 on POSIX platforms) and lacked file descriptor bounds checking across clr_Echo, reset_Tty, save_Tty, set_Cbreak, and set_Raw, allowing out-of-bounds array writes on large or invalid file descriptors; termio_getch lacked FD_SET bounds checking on fd (fd >= FD_SETSIZE causes stack buffer overflow in select/FD_SET); in linenoise.hpp, EditHistoryNext used unbounded strcpy() from history strings into buf_ risking buffer overflow, EditInsert failed to check if len_ + clen exceeded buf_len_ leading to buffer overflow on multi-byte UTF-8 insertions, completeLine used unchecked string indexing &lc[i][0] on potentially empty strings and failed to clamp snprintf return value causing len_ to exceed buf_len_, refreshSingleLine and refreshMultiLine divided and modulo'd by cols_ without checking for <= 0 leading to division-by-zero crashes, and LoadHistory/SaveHistory/AddHistory/SetPrompt lacked null pointer validation. |
| `SEC-0233` | `src/libpc/gecode_librt_test.cpp, src/libpc/solver_test.cpp, src/libpc/vm_test.cpp, src/libpc/domain_constraint_propagator.cpp, src/libpc/cartesian-heart.cpp, src/libpc/gecode_solver_test.cpp` | `gecode_librt_test.cpp:45-95; solver_test.cpp:43-85, 90-115; vm_test.cpp:38-45, 70-78, 140-145; domain_constraint_propagator.cpp:60-110; cartesian-heart.cpp:112-120; gecode_solver_test.cpp:70-75` | Out-of-Bounds Array Access, Division by Zero, and Missing Pointer Validation | 2 | `CONFIRMED` | `FIXED` | In libpc routines: in gecode_librt_test.cpp, add_constraint_coincident_pnt, add_constraint_perpendicular_vect, and add_constraint_pnt_on_line_segment indexed Space variable arrays with unchecked point indices risking out-of-bounds array access; in solver_test.cpp, constraint functors f1-f4 dereferenced getVariablebyID() return pointers without null checks, and getParameter('G') was dereferenced without null checking; in vm_test.cpp, div() divided by parameter b without zero protection, and findfunction dereferenced ct** ap without null validation; in domain_constraint_propagator.cpp, DisEq::post, copy, propagate, and diseq accepted Space* home without null checks; across test drivers, argv[0] was passed to bu_setprogname without validating argc > 0 and argv != NULL. |
| `SEC-0234` | `src/nirt/main.cpp, src/nirt/showshot.c` | `main.cpp:145-158, 260-312, 460-505, 595-635, 740-815, 875-905; showshot.c:65-85, 90-100, 115-140` | Use-After-Free, Double-Free, Buffer Overflow, and Resource Leaks | 2 | `CONFIRMED` | `FIXED` | In nirt routines: in main.cpp, db_close(dbip) was invoked before reading database metadata dbi_local2base and dbi_title leading to use-after-free; ns was freed with BU_PUT but left non-NULL on failure paths triggering double-free in the cleanup block; in nirt_dest_cmd, popen/fopen/pclose logic set both io_data->out and io_data->err to the same pointer leading to double-pclose/double-fclose and leaked unclosed file handles on re-routing; in list_formats, fopen return was unchecked causing potential NULL pointer dereference; in the matrix reading loop, rt_read_cmd returned heap buffers that were leaked on each iteration; when no database file argument was provided, argv[0] was indexed out-of-bounds. In showshot.c, region name rname was populated in an unbounded character loop risking stack buffer overflow; radius input was unvalidated against zero or negative values; argv[0] was passed to bu_setprogname without validating argc > 0. |
| `SEC-0235` | `src/bwish/cmd.c, src/bwish/input.c, src/bwish/main.c` | `cmd.c:80-155, 210-245, 250-285, 290-350; input.c:135-150, 220-240, 255-285, 320-335, 365-425, 490-530; main.c:75-85, 230-265, 280-288, 315-335` | Heap/Stack Buffer Overflow, Pointer Underflow, and Memory Leaks | 2 | `CONFIRMED` | `FIXED` | In bwish/btclsh routines: in cmd.c, historyInit allocated cmdhist with sizeof(struct bu_cmdhist_obj) instead of sizeof(struct bu_cmdhist) in realloc, and history_record_priv lacked capacity check before writing to cmdhist[currHist.size] risking heap buffer overflow; history_prev, history_cur, and history_next lacked bounds and empty-list checks; cmd_history leaked fp and continued processing on invalid option; in input.c, inputHandler loop condition evaluated buf[++i] when i == count - 1 leading to out-of-bounds read of buf[BU_PAGE_SIZE]; processChar underflowed size_t to SIZE_MAX when checking trailing newline on an empty string; backward-word and CTRL_W formed out-of-bounds pointers before the start of the string when index was zero; temporary bu_vls buffers were leaked across multiple editing operations; in main.c, tty_usable passed unvalidated file descriptors into FD_SET causing potential stack buffer overflow on fd >= FD_SETSIZE; main dereferenced unchecked argv[0] and lacked null verification on Tcl_CreateInterp. |
| `SEC-0236` | `bench/clean.c, bench/compute.c, bench/run.c, bench/pixcmp.c, bench/benchmark.c` | `clean.c:70-90; compute.c:50-85; run.c:64-90; pixcmp.c:201-375; benchmark.c:80-105, 285-345, 385-455, 475-625, 820-965` | Format String Bugs, Division Errors, File Descriptor Leaks, and Bounds Checks | 2 | `CONFIRMED` | `FIXED` | In bench suite tools: in clean.c, clean_obstacles reused un-truncated vls instances appending .log to .pix strings creating corrupted paths and leaked heap buffers; in compute.c, average() decremented element count in loop condition causing division by negative one instead of total element count; in run.c, format string %s received a struct bu_vls by value corrupting the varargs stack; in pixcmp.c, argv[1] was dereferenced out-of-bounds when argc == 1, effective file size subtraction underflowed unsigned size_t when skip exceeded file size, and file pointers were leaked on exit paths; in benchmark.c, unchecked getenv("LOGFILE") and fopen returns risked null dereferences, inverted bu_strncasecmp logic caused any non-instruction flag to abort into instructions mode, option=value parsing used the key instead of the value, open(logfile) leaked file descriptors, %.2lfs format string received a const char* instead of double, and bu_vls structs were leaked across all exit paths. |
| `SEC-0237` | `src/art/tile.cpp, src/art/brlcadplugin.h, src/art/brlcadplugin.cpp, src/art/art.cpp` | `tile.cpp:63-88; brlcadplugin.h:60-65; brlcadplugin.cpp:120-175, 215-260, 325-455, 525-540; art.cpp:270-285, 400-405, 479-514, 550-600, 740-750, 880-910, 1065-1075, 1135-1145, 1280-1310, 1375-1380, 1415-1445, 1475-1545, 1605-1615` | Buffer Bounds, Resource Leaks, Null Dereferences, and Out-of-Bounds Memory Access | 2 | `CONFIRMED` | `FIXED` | In art Appleseed ray tracing integration: in tile.cpp, on_tile_end lacked null checks on frame and framebuffer handle fbp, lacked tile index bounds checks, inverted row offset calculation risked out-of-bounds row indexing on edge pixels, and pixel buffer reads lacked size bounds validation; in brlcadplugin.h, Model lacked static linkage risking duplicate symbols; in brlcadplugin.cpp, brlcad_hit lacked null validation on ap and PartHeadp and dereferenced unchecked pt_inseg and pt_outseg pointers, BrlcadObject constructor dereferenced unchecked p_ap and rti_dbip pointers, BrlcadObject::release leaked rtip by never calling rt_i_destroy, intersect routines lacked null checks on resources and name, get_id allowed unbounded thread counter indexing past MAX_PSW in resources array leading to out-of-bounds heap access, and configure_raytrace_application leaked heap-allocated objv and accessed objects[0] without bounds validation; in art.cpp, color_hook called BU_CK_STRUCTPARSE before checking null pointer sp, art_validate_options performed raw float equality on airdensity, art_parse_light_intensity lacked pointer checks on bright and fract, register_region opened a ged instance per visited region and leaked it on all non-light paths while failing to check for GED_NULL, build_project opened a secondary dbip and leaked it every frame without calling db_close, temporary bu_vls instances fov, dimensions, and str were leaked on exit paths, art_save_image lacked null checks on filename and frame pointer, and main lacked argv[0] guards and leaked resources on failure exits. |
| `SEC-0238` | `src/launcher/launcher.c, src/launcher/registry.c, src/launcher/launch.c, src/launcher/fbtext.c, src/launcher/ui_fb.c, src/launcher/ui_text.c` | `launcher.c:48-62, 73-95; registry.c:59-87, 92-104, 110-165, 190-210, 235-260; launch.c:46-72, 120-135; fbtext.c:83-119, 174-198; ui_fb.c:64-88, 108-170, 174-237, 260-272, 380-422; ui_text.c:56-72` | Buffer Overflow, Out-of-bounds Array Access, Null Pointer Dereference, and Input Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD launcher tools and UI: in launcher.c, bu_setprogname(argv[0]) was called without validating argc > 0 and argv != NULL, list_apps dereferenced r without checking for NULL, and fprintf hardcoded binary name instead of using bu_getprogname(); in registry.c, registry_grow and trim lacked null pointer validation on inputs, registry_resolve dereferenced unchecked pointer e, registry_parse and registry_add_builtins failed to check registry_grow return values risking null dereference if growth failed, and app_registry_load failed to check bu_dir return values before probing paths and directory existence; in launch.c, prepend_bindir_to_path unchecked bu_dir return before using bindir, and launch_shell used un-buffered static bu_which pointer across multiple function invocations; in fbtext.c, draw_char lacked framebuffer vertical row bounds checks risking out-of-bounds row indexing on edge pixels and lacked pointer validation on fbp, vfp, and vdp, and fbtext_draw calculated width limit without margin margin check; in ui_fb.c, fill_rect, draw_border, blit_icv, load_splash, redraw, and activate lacked null pointer checks on framebuffer, image, and registry structures, load_splash lacked zero/negative dimension guards, redraw and activate indexed r->apps without bounds-checking button action indices, and mouse click and Enter key handlers indexed button array without bounds validation; in ui_text.c, print_menu lacked null pointer checks on r. |
| `SEC-0239` | `src/isst/gfile.h, src/isst/gfile.cpp, src/isst/isstgl.h, src/isst/isstgl.cpp, src/isst/main.cpp, src/isst/main_window.cpp, src/isst/isstapp.cpp` | `gfile.h:44-55; gfile.cpp:45-55, 60-120, 130-200, 210-235, 240-340; isstgl.h:58-69, 79-95; isstgl.cpp:37-67, 68-106, 108-126, 128-250, 280-295, 300-330, 340-390; main.cpp:35-40, 50-75; main_window.cpp:61-78, 99-103; isstapp.cpp:28-42` | Buffer Overflow, Memory Leaks, Division by Zero, Null Pointer Dereference, and Out-of-Bounds Memory Access | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD ISST interactive ray-tracing subsystem: in gfile.h and gfile.cpp, GFile lacked constructor and destructor leaving pointer members uninitialized; closedb() only freed the tie wrapper and leaked tie tree internals, meshes list, and mesh attributes; load_g() leaked dbip if db_dirbuild() failed, left dangling pointers in tribuf and dbip, and leaked allocated strings from db_path_to_string() on every region; in nmg_to_adrt_internal(), vert_count increment and buffer writing occurred before bounds validation risking out-of-bounds array writes on non-triangle loops and called bu_exit() instead of gracefully skipping; in nmg_to_adrt_regstart(), BoT face vertex indices lacked bounds checking against num_vertices risking heap out-of-bounds reads and leaked intern memory from rt_db_get_internal(); file-static gcvwriter global state caused concurrency and re-entrancy issues; in isstgl.h and isstgl.cpp, TIERenderer constructor left camera struct uninitialized causing multiplication of garbage integers in texdata buffer allocation, resize() performed unchecked integer division by width risking division by zero, res_decr() miscalculated horizontal resolution using height instead of width, render() dereferenced NULL tie if no scene was loaded, set_tie() updated renderer state without acquiring render mutex, and camera.view_list was leaked in destructor; in main.cpp, argc check if (argc > 1) prevented loading single file arguments and lacked argv[0] null guard; in main_window.cpp, raw C casts and unchecked canvas pointers were used; in isstapp.cpp, statusBar and canvas pointers were dereferenced without null checks. |
| `SEC-0240` | `src/libbv/adc.c, src/libbv/diff.c, src/libbv/font.c, src/libbv/hash.c, src/libbv/knobs.cpp, src/libbv/lod.cpp, src/libbv/polygon.c, src/libbv/polygon_fill.cpp, src/libbv/polygon_op.cpp, src/libbv/snap.c, src/libbv/tests/list.c, src/libbv/tests/plot3.c, src/libbv/tests/test_camera.c, src/libbv/tests/test_lod_cache.cpp, src/libbv/tests/vlist.c, src/libbv/util.cpp, src/libbv/view_sets.cpp, src/libbv/vlist.c` | `adc.c:48-95; diff.c:60-120, 180-240; font.c:50-80; hash.c:70-130, 200-280; knobs.cpp:60-110, 190-260, 480-530; lod.cpp:90-140, 240-300, 390-440, 500-550, 1200-1260; polygon.c:80-140, 200-350, 400-520, 600-750; polygon_fill.cpp:40-90, 120-180; polygon_op.cpp:60-90; snap.c:70-130, 180-250, 300-380; tests/list.c:60-100, 150-170, 350-370, 490-535; tests/plot3.c:50-80; tests/test_camera.c:280-290; tests/test_lod_cache.cpp:280-290; tests/vlist.c:40-65; util.cpp:45-55, 335-445, 480-515, 560-675, 940-1055, 1125-1150, 1200-1540, 1630-1910; view_sets.cpp:40-120; vlist.c:40-60, 115-135, 175-215, 220-235, 240-255, 260-275, 325-340, 360-395, 400-475, 565-675` | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Array Access, and Null Pointer Dereferences | 1 | `CONFIRMED` | `FIXED` | In BRL-CAD libbv view library: in vlist.c, bv_vlblock_to_objs leaked cname and oobjs data structures, and bv_vlblock_init suffered integer overflow and out-of-bounds writes when max_ent < 2; in util.cpp, bv_free leaked display list freelist nodes and freed scene object internal state, division by zero was possible in _bv_trans, _bv_scale, and isize calculations, and bv_obj_get_vo mismatched free list tracking and dereferenced null pointer structures; in lod.cpp, POPState divisions lacked zero-extent checks, and bv_mesh_lod_free leaked context and state; in knobs.cpp, divisions by gv_scale and gv_size lacked ZERO checks; in polygon.c, polygon_fill.cpp, and snap.c, missing array bounds checks risked out-of-bounds memory accesses and divisions lacked zero checks; in test binaries, plot3.c leaked file pointers and inverted text mode, tests/vlist.c indexed argv before checking argc and leaked vlist nodes, and tests/list.c had an off-by-one loop in convert_points. |
| `SEC-0241` | `src/libdm/X/color.c, src/libdm/X/dm-X.c, src/libdm/X/if_X24.c, src/libdm/axes.c, src/libdm/clip.c, src/libdm/dm-generic.c, src/libdm/dm-gl.c, src/libdm/dm_plugins.cpp, src/libdm/dm_util.c, src/libdm/fb_generic.c, src/libdm/fb_paged_io.c, src/libdm/fb_util.c, src/libdm/fbserv.c, src/libdm/glx/if_ogl.c, src/libdm/if_mem.c, src/libdm/if_remote.c, src/libdm/if_stack.c, src/libdm/labels.c, src/libdm/postscript/dm-ps.c, src/libdm/qtgl/dm-qtgl.cpp, src/libdm/qtgl/fb-qtgl.cpp, src/libdm/scale.c, src/libdm/swrast/dm-swrast.cpp, src/libdm/swrast/fb-swrast.cpp, src/libdm/tkswrast/dm-tkswrast.cpp, src/libdm/view.c, src/libdm/wgl/dm-wgl.c, src/libdm/wgl/if_wgl.c` | `X/color.c:70-130, 200-240; X/dm-X.c:200-250, 480-530, 600-660; X/if_X24.c:480-530, 1100-1160; axes.c:80-140, 200-260; clip.c:70-130, 180-230; dm-generic.c:50-90; dm-gl.c:180-240, 380-440; dm_plugins.cpp:60-140; dm_util.c:40-80; fb_generic.c:80-150; fb_paged_io.c:60-150; fb_util.c:60-140; fbserv.c:160-220, 380-430; glx/if_ogl.c:480-540, 950-1050; if_mem.c:70-140, 200-260; if_remote.c:120-180, 240-300; if_stack.c:60-120; labels.c:80-140, 200-260; postscript/dm-ps.c:120-180, 320-380; qtgl/dm-qtgl.cpp:160-220, 400-470; qtgl/fb-qtgl.cpp:200-260, 400-470, 750-820; scale.c:60-80; swrast/dm-swrast.cpp:180-250, 420-490; swrast/fb-swrast.cpp:210-270, 420-490, 750-820; tkswrast/dm-tkswrast.cpp:70-130; view.c:120-190, 320-400, 500-600; wgl/dm-wgl.c:180-250, 410-480; wgl/if_wgl.c:200-270, 440-510, 800-870` | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 1 | `CONFIRMED` | `FIXED` | In BRL-CAD libdm display manager and framebuffer library: in X/color.c, _X_copy_cmap had out-of-bounds write risk, float cast truncation in X_get_pixel, and division by zero in X_allocate_color_cube; in X/if_X24.c and X/dm-X.c, off-by-one loop bound in X24_cmap, integer overflow in X24_getmem, missing XDestroyImage resource leaks, and division by zero in X_reshape; in glx/if_ogl.c, wgl/if_wgl.c, and dm-gl.c, integer overflow in getmem, leaks on context creation failures, division by zero in reshape and clipper, and bounds check vulnerabilities in image routines; in postscript/dm-ps.c, NULL pointer checks and memory leaks in ps_close and draw routines; in qtgl and swrast backends, unprotected VIEWFACTOR macro, out-of-bounds scanline writes in xmit_scanlines, division by zero in fb_clipper, and leaks of dm_log and memory contexts; in tkswrast, NULL pointer dereferences in event and buffer handlers; in clip.c, division by zero when dx/dy is zero and unsafe static locals; in axes.c, view.c, scale.c, and labels.c, unchecked pointer dereferences, division by zero in aspect/FPS calculations, unbounded tick iteration, and buffer overflow in POINT_LABEL_STR; in fb_generic.c and fb_paged_io.c, unchecked division by zero in page calculations and zoom; in if_mem.c, if_remote.c, and if_stack.c, integer multiplication overflow in allocation, unclosed sockets/resources on error paths, and unbounded stack buffer copy in stk_open. |
| `SEC-0242` | `src/libgcv/bottess.c, src/libgcv/facetize.c, src/libgcv/plugins/decimate/decimate.c, src/libgcv/plugins/fastgen4/fastgen4_read.c, src/libgcv/plugins/fastgen4/fastgen4_write.cpp, src/libgcv/plugins/iges/tests/test_gcv_iges.cpp, src/libgcv/plugins/iges/tests/test_iges_brep.cpp, src/libgcv/plugins/iges/tests/test_iges_document.cpp, src/libgcv/plugins/iges/tests/test_iges_import.cpp, src/libgcv/plugins/iges/tests/test_iges_orientation.cpp, src/libgcv/plugins/iges/tests/test_iges_rays.cpp, src/libgcv/plugins/iges/tests/test_iges_writer.cpp, src/libgcv/plugins/jt/jt_read.cpp, src/libgcv/plugins/jt/test_jt_parser.cpp, src/libgcv/plugins/jt/test_jt_topology.cpp, src/libgcv/plugins/obj/obj_read.c, src/libgcv/plugins/obj/obj_write.c, src/libgcv/plugins/obj/tri_face.c, src/libgcv/plugins/ply/ply_read.c, src/libgcv/plugins/ply/ply_write.c, src/libgcv/plugins/rhino/rhino_read.cpp, src/libgcv/plugins/scad/scad_read.c, src/libgcv/plugins/stl/stl_read.c, src/libgcv/plugins/stl/stl_write.cpp, src/libgcv/plugins/vrml/vrml_read/file_util.cpp, src/libgcv/plugins/vrml/vrml_read/string_util.cpp, src/libgcv/plugins/vrml/vrml_read/test_vrml1_parser.cpp, src/libgcv/plugins/vrml/vrml_read/vrml_read.cpp, src/libgcv/plugins/vrml/vrml_write.c, src/libgcv/region_end.c, src/libgcv/region_end_mc.c, src/libgcv/tests/test_bottess.c, src/libgcv/tests/test_context.c, src/libgcv/tri_intersect.c` | `bottess.c:80-140, 200-260, 480-530; facetize.c:60-120; plugins/decimate/decimate.c:70-130; plugins/fastgen4/fastgen4_read.c:80-140; plugins/fastgen4/fastgen4_write.cpp:100-160; plugins/iges/tests/test_*.cpp:40-100; plugins/jt/jt_read.cpp:80-150; plugins/obj/obj_read.c:120-180; plugins/obj/obj_write.c:90-150; plugins/obj/tri_face.c:60-120; plugins/ply/ply_read.c:80-140; plugins/ply/ply_write.c:100-160; plugins/rhino/rhino_read.cpp:120-180; plugins/scad/scad_read.c:60-120; plugins/stl/stl_read.c:70-130; plugins/stl/stl_write.cpp:80-140; plugins/vrml/vrml_read/*:60-140; plugins/vrml/vrml_write.c:90-160; region_end.c:70-140; region_end_mc.c:80-150; tests/test_bottess.c:40-80; tests/test_context.c:40-80; tri_intersect.c:50-110` | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libgcv geometry conversion library and plugins: in bottess.c, fixed -Wbad-function-cast float-to-integer conversion by using safe integer arithmetic for face count partitioning, added bounds checks on polygon vertices, and plugged memory leaks; in plugins/obj/obj_read.c and ply_write.c, initialized structure members preventing undefined memory reads and uninitialized pointer dereferences; in plugins/fastgen4, obj, ply, stl, jt, rhino, and vrml readers/writers, guarded against division by zero in normal and scaling calculations, added boundary validation on vertex and triangle indices, and prevented resource leaks on error exit paths; in region_end.c and region_end_mc.c, added cleanup for intermediate geometry allocations; in standalone tests, guarded input arguments and initialized bu_setprogname(argv[0]). |
| `SEC-0243` | `src/libged/3ptarb/3ptarb.c, src/libged/adc/adc.c, src/libged/adjust/adjust.c, src/libged/alphanum.h, src/libged/analyze/arb8.cpp, src/libged/analyze/arbn.cpp, src/libged/analyze/ars.cpp, src/libged/analyze/op_pnts_vol.cpp, src/libged/analyze/sketch.cpp, src/libged/analyze/superell.cpp, src/libged/analyze/util.cpp, src/libged/arb/arb.cpp, src/libged/arb/repair.cpp, src/libged/arb/rotate_arb_face.c, src/libged/arced/arced.c, src/libged/arot/arot.c, src/libged/arrange/nest_raster.cpp, src/libged/bb/bb.c, src/libged/bev/bev.c, src/libged/bo/bo.c, src/libged/ged_util.cpp` | `3ptarb.c:70-130; adc.c:160-230, 480-530; adjust.c:80-140; alphanum.h:50-100; analyze/arb8.cpp:100-140; analyze/arbn.cpp:80-130; analyze/ars.cpp:40-100; analyze/op_pnts_vol.cpp:120-180; analyze/sketch.cpp:60-120; analyze/superell.cpp:70-130; analyze/util.cpp:100-180; arb/arb.cpp:80-140; arb/repair.cpp:60-120; arb/rotate_arb_face.c:70-130; arced/arced.c:90-140; arot/arot.c:60-120; arrange/nest_raster.cpp:80-130; bb/bb.c:90-160; bev/bev.c:100-180; bo/bo.c:70-140; ged_util.cpp:210-270` | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged command implementations (3ptarb, adc, adjust, alphanum, analyze, arb, arced, arot, arrange, bb, bev, bo, and ged_util): in 3ptarb.c, fixed memory leak of internal.idb_ptr when db_diradd fails; in adc.c, prevented stack buffer overflow by clamping argc > 3 before populating user_pt[3], added ZERO(gv_scale) guards preventing division by zero, and corrected pos_model vs pos_view typo in MAT4X3PNT; in adjust.c, prevented memory leak and fixed double-free on wdb_put_internal; in alphanum.h, added NULL pointer checks and replaced unsigned long subtraction with direct comparison to prevent integer wrap-around; in analyze/arb8.cpp, arbn.cpp, ars.cpp, op_pnts_vol.cpp, sketch.cpp, superell.cpp, and util.cpp, added NULL pointer checks, checked wdb_dbopen return values, prevented division by zero, bounded ARS curve and point indices, bounded face table widths, and plugged resource leaks; in arb.cpp, repair.cpp, rotate_arb_face.c, and arced.c, eliminated double-free bugs following database insertion and validated ARB type ranges; in arot.c and ged_util.cpp, added input validation and ZERO(MAGNITUDE(axis)) division-by-zero guards; in arrange/nest_raster.cpp, guarded voxel_count against division by zero; in bb.c, eliminated unconditional double-free of new_intern and freed memory on db_diradd failure; in bev.c, validated boolean operator, cleaned up intermediate trees and NMG models on error paths, and fixed memory leaks; in bo.c, checked NULL pointer returns and added integer multiplication overflow checks before file output. |
| `SEC-0244` | `src/libged/bot/bot.cpp, src/libged/bot/bot_condense.c, src/libged/bot/bot_decimate.c, src/libged/bot/bot_face_fuse.c, src/libged/bot/bot_face_sort.c, src/libged/bot/bot_flip.c, src/libged/bot/bot_flood_exterior.cpp, src/libged/bot/bot_fuse.c, src/libged/bot/bot_merge.c, src/libged/bot/bot_openvdb.cpp, src/libged/bot/bot_smooth.c, src/libged/bot/bot_split.c, src/libged/bot/bot_sync.c, src/libged/bot/bot_vertex_fuse.c, src/libged/bot/check.cpp, src/libged/bot/decimate.cpp, src/libged/bot/dump/bot_dump.cpp, src/libged/bot/dump/dxf.c, src/libged/bot/dump/obj.c, src/libged/bot/dump/sat.c, src/libged/bot/dump/stl.c, src/libged/bot/edbot.c, src/libged/bot/exterior.cpp, src/libged/bot/extrude.cpp, src/libged/bot/info.cpp, src/libged/bot/pick.cpp, src/libged/bot/remesh.cpp, src/libged/bot/smooth.cpp, src/libged/bot/subdivide.cpp, src/libged/brep/brep.cpp, src/libged/brep/conversion.cpp, src/libged/brep/csg.cpp, src/libged/brep/dplot.c, src/libged/brep/dplot_reader.c, src/libged/brep/info.cpp, src/libged/brep/intersect.cpp, src/libged/brep/pick.cpp, src/libged/brep/plot.cpp, src/libged/brep/repair.cpp, src/libged/brep/tikz.cpp, src/libged/brep/topology.cpp, src/libged/brep/valid.cpp` | `bot/bot.cpp:148-166; bot/bot_*.c:40-150; bot/check.cpp:50-90; bot/decimate.cpp:40-90; bot/dump/*:40-160; bot/edbot.c:70-130; bot/exterior.cpp:60-120; bot/extrude.cpp:70-130; bot/info.cpp:50-100; bot/pick.cpp:40-90; bot/remesh.cpp:50-100; bot/smooth.cpp:60-120; bot/subdivide.cpp:50-100; brep/brep.cpp:100-180; brep/conversion.cpp:80-180; brep/csg.cpp:60-220; brep/dplot.c:50-110; brep/dplot_reader.c:60-120; brep/info.cpp:70-150; brep/intersect.cpp:60-130; brep/pick.cpp:50-110; brep/plot.cpp:80-500; brep/repair.cpp:60-140; brep/tikz.cpp:35-240; brep/topology.cpp:55-275; brep/valid.cpp:60-535` | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Array Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged bot and brep command implementations: across bot subcommands, ensured proper rt_db_internal initialization and cleanup, added array bounds checks on vertices, faces, and thicknesses, guarded against division by zero in normal and decimation calculations, prevented memory leaks of internal structures and allocated vertex/face buffers on error paths, and fixed double-free hazards on wdb_export/wdb_put_internal; in bot dumping routines (dxf, obj, sat, stl), added bounds checks, validated fopen returns, and plugged resource leaks; in brep subcommands (brep, conversion, csg, dplot, dplot_reader, info, intersect, pick, plot, repair, tikz, topology, valid), fixed memory leaks of internal structures and temporary trees, added NULL pointer checks on brep and surface pointers, guarded array and trim indices across all plotting and validity commands, fixed copy-paste typo in repair and rgb check in tikz, added division-by-zero protection on scale calculation, and validated return values of edge creation. |
| `SEC-0245` | `src/libged/cc/cc.c, src/libged/check/check.c, src/libged/check/check_adj_air.c, src/libged/check/check_centroid.c, src/libged/check/check_exp_air.c, src/libged/check/check_gap.c, src/libged/check/check_mass.c, src/libged/check/check_moments.c, src/libged/check/check_overlaps.c, src/libged/check/check_surf_area.c, src/libged/check/check_unconf_air.c, src/libged/check/check_volume.c, src/libged/coil/coil.c, src/libged/color/color.c, src/libged/columns.c, src/libged/comb/comb.c, src/libged/comb_std/comb_std.c, src/libged/combmem/combmem.c, src/libged/concat/concat.cpp, src/libged/constraint/constraint.c, src/libged/copymat/copymat.c, src/libged/cpi/cpi.c, src/libged/dbi_state.cpp, src/libged/debug/debug2c/debug2c.cpp` | `cc.c:70-95; check/check.c:190-210, 440-520; check/check_adj_air.c:40-60, 95-105; check/check_centroid.c:35-50; check/check_exp_air.c:40-60, 95-105; check/check_gap.c:40-60, 95-105; check/check_mass.c:35-50; check/check_moments.c:160-175; check/check_overlaps.c:165-175, 230-260; check/check_surf_area.c:35-50; check/check_unconf_air.c:40-65, 95-110; check/check_volume.c:35-80; coil/coil.c:330-405, 440-555; color/color.c:165-245; columns.c:45-80; comb/comb.c:110-120, 480-550; comb_std/comb_std.c:330-350, 610-660; combmem/combmem.c:470-498; concat/concat.cpp:280-335, 400-475; constraint/constraint.c:30-175; copymat/copymat.c:90-155; cpi/cpi.c:85-100; dbi_state.cpp:240-305, 455-465; debug/debug2c/debug2c.cpp:150-160` | Memory Leaks, Double-Free, Division by Zero, Infinite Loop, Array Out-of-Bounds, and File Descriptor Leaks | 2 | `CONFIRMED` | `FIXED` | In libged Batch 3 commands: in cc.c and cpi.c, freed internal representation on db_diradd failure and removed redundant double-free on write; in check/*.c routines, added NULL checks, guarded against division by zero on uninitialized unit values, plugged plot file descriptor leaks on raytrace failure, and freed heap VLS instances; in coil.c, freed allocated sections on exit paths, validated sscanf on -S, prevented division by zero, and clamped negative lengths; in color.c, fixed cnt != 9 typo to cnt != 5 and ensured temp file deletion on error paths; in columns.c, added NULL checks on input strings; in comb.c, comb_std.c, combmem.c, and copymat.c, fixed double-frees following rt_db_put_internal, freed internal structures across decimation iterations and diradd errors, freed rt_tree_array in combmem, and fixed infinite loop on paren evaluation; in concat.cpp, guarded argv[1] bounds, closed incoming database on error exits, and freed internal memory on copy failures; in constraint.c, validated argc bounds across all subcommands; in dbi_state.cpp, deleted view_states map in destructor, and aborted/cleared transactions on cache retrieval failure; in debug2c.cpp, checked file open success before reading. |
| `SEC-0246` | `src/libged/decompose/decompose.c, src/libged/delay/delay.c, src/libged/display_list.c, src/libged/dm/dm.c, src/libged/dm/ert.cpp, src/libged/dm/screengrab.c, src/libged/draw.cpp, src/libged/draw/bigE.c, src/libged/draw/draw.c, src/libged/draw/draw2.cpp, src/libged/draw/loadview.cpp, src/libged/draw/preview.cpp, src/libged/dsp/dsp.c, src/libged/dump/dump.c, src/libged/dup/dup.c, src/libged/eac/eac.c, src/libged/edcodes/edcodes.c` | `decompose.c:110-185; delay.c:50-75; display_list.c:130-170, 715-770; dm/dm.c:280-320, 680-775; dm/ert.cpp:115-180; dm/screengrab.c:60-140; draw.cpp:210-240, 310-335, 785-845; draw/bigE.c:70-200; draw/draw.c:840-865, 1260-1285; draw/draw2.cpp:260-310; draw/loadview.cpp:140-180, 220-370; draw/preview.cpp:190-205, 370-475; dsp/dsp.c:85-125; dump/dump.c:60-70; dup/dup.c:50-165, 220-235; eac/eac.c:75-90; edcodes/edcodes.c:45-65, 110-135, 220-285` | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 4 commands: in decompose.c, fixed memory leaks on non-NMG solids and db_lookup/db_diradd failures, replaced sprintf with snprintf, and eliminated double-free of new_m; in delay.c, validated sec/usec against negative values before select(); in display_list.c, added NULL checks across erase and hash helpers and handled failure in invent_solid; in dm/dm.c, guarded argc > 0 before argv indexing, freed dm_name leaks, and corrected return status; in dm/ert.cpp, guarded against division by zero in aspect ratio, fixed loop index typo, and freed bu_vls; in dm/screengrab.c, freed dm_name on help path, added ndmp NULL guard, fixed argv bounds, and freed idata on failure; in draw.cpp, guarded division by zero, plugged db_intern leaks in csg_wireframe_update and brep_adaptive_plot, and cleaned up on draw_scene error paths; in draw/bigE.c, resolved TODO by freeing dgcdp, plugged dgcdp->ap leak on each iteration, and prevented duplicate ptbl initializations; in draw/draw.c, freed brep_intern on get_path_and_state error and freed obj_path in ged_redraw_core; in draw/draw2.cpp, guarded dbi_state and corrected view state lookup loop; in draw/loadview.cpp, prevented size_t underflows, freed tcl_argv, fixed orientation quaternion bounds, and guarded against division by zero; in draw/preview.cpp, prevented buffer overflow in ged_cm_tree, checked argc >= 2 before fopen, and freed gd_rt_cmd and ged_tmp_uptrs; in dsp/dsp.c, validated xy argument count, fixed off-by-one bounds check, fixed intern2 typo in diff subcommand, and freed intern on lookup/read errors; in dump/dump.c, used wdb_close on rt_wdb; in dup/dup.c, enforced max_entries check to prevent array bounds overflow; in eac/eac.c, freed vls on read error, checked ID_COMBINATION, and used rt_db_free_internal; in edcodes/edcodes.c, added NULL pointer checks in comparisons, checked argc >= 2, freed av on fopen error, and used rt_db_free_internal. |
| `SEC-0247` | `src/libged/edit/edarb.c, src/libged/edit/edit.cpp, src/libged/edit/facedef.c, src/libged/edit/rotate_eto.c, src/libged/edit/rotate_extrude.c, src/libged/edit/rotate_hyp.c, src/libged/edit/rotate_tgc.c, src/libged/edit/scale_ehy.c, src/libged/edit/scale_ell.c, src/libged/edit/scale_epa.c, src/libged/edit/scale_eto.c, src/libged/edit/scale_extrude.c, src/libged/edit/scale_hyp.c, src/libged/edit/scale_metaball.c, src/libged/edit/scale_part.c, src/libged/edit/scale_pipe.c, src/libged/edit/scale_rhc.c, src/libged/edit/scale_rpc.c, src/libged/edit/scale_superell.c, src/libged/edit/scale_tgc.c, src/libged/edit/scale_tor.c, src/libged/edit/translate_extrude.c, src/libged/edit/translate_tgc.c, src/libged/edit/uri.hh` | `edarb.c:125-135, 175-185, 215-275, 325-335; edit.cpp:1350-1365, 1515-1555; facedef.c:190-205, 385-395; rotate_eto.c:38-46; rotate_extrude.c:38-45; rotate_hyp.c:38-46; rotate_tgc.c:38-46; scale_ehy.c:38-52; scale_ell.c:38-92; scale_epa.c:38-52; scale_eto.c:38-115; scale_extrude.c:38-52; scale_hyp.c:38-75; scale_metaball.c:45-56; scale_part.c:38-50; scale_pipe.c:255-268; scale_rhc.c:38-56; scale_rpc.c:38-56; scale_superell.c:38-92; scale_tgc.c:38-170; scale_tor.c:38-46; translate_extrude.c:38-48; translate_tgc.c:38-48; uri.hh:54-64` | Memory Leaks, Double-Free, Dangling Pointer, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged edit commands (src/libged/edit/*): in edarb.c and facedef.c, eliminated double-free hazards where rt_db_free_internal was called after GED_DB_PUT_INTERN (which unconditionally frees the internal structure), added ARB edge bounds validation (1 to 12) in edarb_edgedir, and validated argc >= 4 before accessing argv in edarb_facedef; in edit.cpp, scoped bn_tol to function scope in cmd_checkpoint::exec to prevent dangling pointer in s->tol, and in cmd_perturb::dp_perturb ensured intern is freed on all exit paths, prevented double-free of pintern contents on write failure, and freed the pintern container struct; in rotate_*.c, scale_*.c, and translate_*.c, guarded against NULL attribute pointers and empty strings before indexing; across scale_*.c (scale_ehy, scale_ell, scale_epa, scale_eto, scale_extrude, scale_hyp, scale_part, scale_rhc, scale_rpc, scale_superell, scale_tgc), guarded all vector MAGNITUDE calculations against division by zero in non-relative scaling modes; and in uri.hh, guarded against constructing std::string from NULL uri_text pointer. |
| `SEC-0248` | `src/libged/editit/editit.c, src/libged/edmater/edmater.c, src/libged/env/env.c, src/libged/env/env2c/env2c.cpp, src/libged/erase/erase.c, src/libged/erase/erase2.cpp, src/libged/exec.cpp, src/libged/exists/exists.c, src/libged/expand/expand.c, src/libged/eye_pos/eye_pos.c` | `editit.c:58-95; edmater.c:72-100; env.c:50-56; env2c.cpp:184-198, 480-488, 575-585; erase.c:76-105, 130-145, 172-185; erase2.cpp:72-80, 104-115; exec.cpp:37-58, 80-100; exists.c:224-248, 300-312, 472-530, 665-672; expand.c:36-54, 75-95; eye_pos.c:38-54, 80-90` | Memory Leaks, Out-of-bounds Memory Access, Logic Errors, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 6 commands: in editit.c, corrected bu_opt_desc array indexing collision (d[0]..d[4]) where -e and -f overwrote -h and -? options, handled negative opt_ret return values, and freed bu_vls buffers on error and help paths; in edmater.c, passed argc + 1 instead of argc to ged_exec_wmater to prevent argument truncation and failure in wmater, guarded argc <= 1 before accessing argv[0], and matched bu_malloc allocation tag; in env.c, added gedp and gedp->ged_result_str NULL checks and validated argc > 0; in env2c.cpp, validated argc range (3..4), added negative argc check on bu_opt_parse in generated env_cmd code, and broadened exception catching to std::exception; in erase.c, freed new_argv on the attribute lookup path, freed bu_vls across all exits, prevented out-of-bounds indexing in bu_avs_add, and properly skipped flag arguments in erase -r and default paths without variable shadowing; in erase2.cpp, guarded negative opt_ret from bu_opt_parse, freed cvls on failure, and guarded against argc <= 0 and NULL bvs before calling erase_path; in exec.cpp, guarded against NULL argv[0] when argc decreases, checked gedp->i and gedp->i->i before dereferencing, and decremented cmd_recursion_depth_cnt and popped exec_stack when recursion limit is exceeded to prevent persistent command lockouts; in exists.c, guarded against out-of-bounds pointer advances and NULL dereferences in t_lex, isoperand, primary, and binop, and checked leftover tokens without modifying pointer; in expand.c, scoped backslash tracking per argument to prevent state leaking across arguments, used bu_vls_putc, and guarded against NULL string arguments; and in eye_pos.c, corrected unit conversion from dbi_base2local to dbi_local2base when converting user-specified eye coordinates to base units. |
| `SEC-0249` | `src/libged/facetize/brep.cpp, src/libged/facetize/facetize.cpp, src/libged/facetize/nmg.cpp, src/libged/facetize/old_facetize.cpp, src/libged/facetize/old_facetize_log.c, src/libged/facetize/regions.cpp, src/libged/facetize/subprocess/brep_csg.cpp, src/libged/facetize/subprocess/continuation.cpp, src/libged/facetize/subprocess/main.cpp, src/libged/facetize/subprocess/nmg.cpp, src/libged/facetize/subprocess/sample.cpp, src/libged/facetize/subprocess/spsr.cpp, src/libged/facetize/subprocess/util.cpp, src/libged/facetize/tess_opts.h, src/libged/facetize/tri.cpp, src/libged/facetize/util.cpp` | `brep.cpp:115-235; facetize.cpp:115-125; nmg.cpp:215-230, 395-460; old_facetize.cpp:925-1055, 1200-1210, 1275-1315, 1375-1475, 1630-1640, 1915-1925; old_facetize_log.c:45-120; regions.cpp:145-165, 340-410, 810-850; brep_csg.cpp:145-160; continuation.cpp:125-140, 260-285; main.cpp:210-230, 520-530; nmg.cpp:65-75; sample.cpp:125-145; spsr.cpp:95-105; util.cpp:45-90; tess_opts.h:205-235; tri.cpp:335-345, 415-425, 1720-1745; util.cpp:445-470, 715-745` | Use-After-Free, Memory Leaks, Double-Free, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 7 facetize commands (src/libged/facetize/*): in brep.cpp, fixed Cat 1 Use-After-Free of wgedp database handle across iterative meshing attempts, freed br ptbl and in_intern on early failure, and freed bot export allocations on write failure; in facetize.cpp, added argc <= 0 bounds checks in _ged_facetize_objs; in nmg.cpp, corrected 4 BU_PUT struct type mismatches freeing union tree nodes as struct directory, eliminated double-free of intern on rt_db_put_internal failure, and freed intern on db_diradd failure; in old_facetize.cpp, guarded against division by zero on obj_bbox_vol, freed temporary bot faces and vertices in continuation retry and abortion paths, eliminated duplicate bounding box check, ensured bot is freed on all decimation and validity failure exits, replaced mismatched calloc/bu_free with bu_calloc, and paired BU_GET with BU_PUT for manifold_mesh; in old_facetize_log.c, validated stderr file descriptor and guarded against NULL struct pointers in log redirection hooks; in regions.cpp, freed dpa directory array on lookup error, freed ir on search failure, handled wdbip reopen failure, freed tree_list nodes with BU_PUT, eliminated double-frees of eval_roots and ir, and cleaned up on bu_vls_incr error; in subprocess/brep_csg.cpp, fixed kill argument array bounds and layout; in subprocess/continuation.cpp, freed candidate bot on retry and continue paths, replaced incorrect BU_PUT pointer type with rt_bot_internal_free, and cleaned up bot on decimation failure; in subprocess/main.cpp, freed cache_dir on early help/list exits and added NULL check on seed; in subprocess/nmg.cpp, verified intern->idb_meth->ft_tessellate function pointer before invocation; in subprocess/sample.cpp, checked obj_bbox_vol with ZERO before division; in subprocess/spsr.cpp, validated point cloud array bounds and counts; in subprocess/util.cpp, added NULL and empty checks before decimate, write_bot, and manifold checks; in tess_opts.h, freed temporary bu_vls in method_optstr and fixed plate_max_time copy-paste error; in tri.cpp, eliminated duplicate curtree allocation, freed td_name on error paths, and used bu_calloc for bot vertices and faces; and in util.cpp, validated _ged_facetize_write_bot inputs, freed internal representation on diradd failure, and closed wdbip on error exits in _ged_facetize_working_file_setup. |
| `SEC-0250` | `src/libged/fb2pix/fb2pix.c, src/libged/fbclear/fbclear.c, src/libged/form/form.c, src/libged/fracture/fracture.c, src/libged/garbage_collect/garbage_collect.cpp, src/libged/gdiff/gdiff.c, src/libged/ged.cpp, src/libged/ged_cmd_scanner.cpp, src/libged/ged_exec.cpp, src/libged/ged_init.cpp` | `fb2pix/fb2pix.c:50-130; fbclear/fbclear.c:45-80; form/form.c:50-80; fracture/fracture.c:55-195; garbage_collect/garbage_collect.cpp:110-185; gdiff/gdiff.c:50-55, 140-192, 280-295, 370-380; ged.cpp:552-556, 628-654, 735-742, 820-835, 840-900; ged_cmd_scanner.cpp:323-330; ged_exec.cpp:42-50, 95-103; ged_init.cpp:128-138, 160-170` | Memory Corruption, Memory Leaks, Resource Leaks, Catastrophic Data Loss Hazard, Recursion Lockout Bug, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 8 core and command implementations: in fb2pix.c, validated image dimensions against non-positive values, modernized error logging, and guarded fclose against stdout/NULL; in fbclear.c, replaced floating-point comparison with ZERO/integer literals, supported unquoted RGB arguments, and routed error diagnostics to ged_result_str; in form.c, reordered argc check ahead of database check and reported unsupported form type errors to result string; in fracture.c, freed old_intern across all exits, prevented log10(0) domain error on empty model, fixed cross-model region bug where new shell pointed to old region shell list head, replaced static global frac_stat with local status, freed NMG model on db_diradd failure, and expanded newname/prefix buffers to 256 bytes; in garbage_collect.cpp, plugged memory leak of bu_external in object copy loop, guarded against division by zero on old_file_size, verified stream write success before deleting the original database to prevent data destruction, checked db_ls path count and validity, and ensured working file cleanup on errors; in gdiff.c, guarded tolerance retrieval against NULL wdbp, guarded path bounds, initialized rt_db_internal structures, freed in1 on in2 retrieval failure, validated ID_COMBINATION types, guarded msgs against NULL dereference, reordered db_lookup before allocating full paths, and checked raydiff results before access; in ged.cpp, resolved heap corruption caused by BU_PUT struct type mismatch freeing struct bu_list as struct bu_vls for gd_headDisplay and gd_headVDraw, zeroed ged_cbs on allocation with memset to prevent uninitialized counters triggering false recursive warnings, verified wdbp and dbip before creating ged struct in ged_open, decremented callback recursion depth before error return to prevent permanent callback lockout, and added NULL checks in callback handlers; in ged_cmd_scanner.cpp, eliminated duplicate and out-of-bounds argv checks in generated wrappers; in ged_exec.cpp, guarded argv[0] and argc before bu_setprogname and verified plugin function pointers before dispatch; in ged_init.cpp, allocated sentinel NULL termination for command array and guarded filenames before path lookup. |
| `SEC-0251` | `src/libged/ged_inside.c, src/libged/ged_private.h, src/libged/ged_track.c, src/libged/ged_util.cpp, src/libged/get/get.c, src/libged/get_autoview/get_autoview.c, src/libged/get_comb/get_comb.c, src/libged/get_eyemodel/get_eyemodel.c, src/libged/get_obj_bounds.c, src/libged/get_solid_kp.c` | `ged_inside.c:130-170, 310-335, 430-490, 600-660, 720-790; ged_private.h:505-515; ged_track.c:160-230, 350-410, 480-550, 620-660; ged_util.cpp:110-140, 320-350, 610-670, 890-950; get/get.c:60-95; get_autoview/get_autoview.c:55-85; get_comb/get_comb.c:65-140; get_eyemodel/get_eyemodel.c:45-75; get_obj_bounds.c:70-130, 220-270; get_solid_kp.c:50-90, 150-220, 310-390` | Memory Leaks, Buffer Overflow, Double-Free, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 9 utilities (ged_inside, ged_track, ged_util, get, get_autoview, get_comb, get_eyemodel, get_obj_bounds, get_solid_kp): in ged_inside.c, eliminated memory leaks of rt_db_internal on early returns and interactive prompt paths, fixed out-of-bounds argv[2] access on completion, cleared dangling idb_ptr after nmg_km to avoid double-free, fixed copy-paste typo in unit_d scaling (mag_b vs mag_c), and guarded against negative sqrt radicand and division by zero across tgc, ell, rpc, rhc, epa, ehy, and eto routines; in ged_track.c, resolved longstanding 30-year-old swap bug where tr[0] was overwritten with uninitialized tr[2], expanded track name allocations to prevent buffer overflow with multi-digit indices, replaced sprintf with snprintf, eliminated double-free of intern in wrobj, ensured track member lists are freed on all exits, and guarded acos and slope calculations against division by zero and domain errors; in ged_util.cpp, added array bounds checks in ged_results_get, validated wdbp and freed previous dbi_title in ged_dbcopy, added scale factor scan failure checks in ged_scale_args, guarded eye model functions against NULL pointers, freed intern on combadd2 region validation error, and passed correct element count to db_mkgift_tree; in get.c, freed internal representation and logged diagnostics when ft_get is unavailable, and guarded wdbp; in get_autoview.c, fixed option parsing bug where initial argc check rejected the -p flag, and validated remaining arguments; in get_comb.c, eliminated memory leaks of internal representation and rt_tree_array across all error exits, guarded wdbp, and formatted matrices with snprintf; in get_obj_bounds.c, enforced _GED_TRACE_MAX_LEVELS limit to prevent array overflow in gtd_obj, replaced free with bu_free, freed intern on rt_i_create failure, and validated ft_prep; in get_solid_kp.c, guarded input pointers against NULL, checked for empty list before accessing first node in pipe, metaball, and nmg handlers, and guarded vertex/curve pointers in bot, ars, poly, and extrude. |
| `SEC-0252` | `src/libged/get_type/get_type.c, src/libged/glob/glob.c, src/libged/gqa/gqa.cpp, src/libged/graph/graph.cpp, src/libged/grid/grid.c, src/libged/grid2model_lu/grid2model_lu.c, src/libged/grid2view_lu/grid2view_lu.c, src/libged/group/group.c, src/libged/heal/heal.c, src/libged/help/help.cpp` | `get_type/get_type.c:45-75; glob/glob.c:130-175, 240-275, 340-395; gqa/gqa.cpp:155-165, 340-360, 560-580, 890-950, 1540-1590, 1680-1760, 1780-1880, 2600-2645, 2730-2815, 2885-2985; graph/graph.cpp:270-315, 640-675, 905-920, 1025-1055; grid/grid.c:38-60, 110-125, 280-310; grid2model_lu/grid2model_lu.c:50-65; grid2view_lu/grid2view_lu.c:50-60; group/group.c:50-65; heal/heal.c:54-85; help/help.cpp:35-105, 110-225, 260-285` | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, Logic Errors, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 10 commands (get_type, glob, gqa, graph, grid, grid2model_lu, grid2view_lu, group, heal, help): in get_type.c, validated argc and argv[1], initialized rt_db_internal before import, and guarded wdbp; in glob.c, added null checks to _debackslash, _backslash_specials, and _ged_expand_str_glob, checked gp->gl_pathv before string access, added per-word match counting to fall back to unescaping individual patterns when unmatched, and guarded argc and argv in ged_glob_core; in gqa.cpp, added null check on units buffer, constrained num_views (1..3) to prevent fixed-size array out-of-bounds access, guarded region and hit pointers against null in _gqa_overlap, initialized point arrays and passed valid pointer in _gqa_hit, bounded string traversal in find_cmd_line_obj, validated inputs and region count returning error on invalid state in allocate_per_region_data, removed redundant duplicate density file loading, fixed massive memory leaks of intern, density names, and avs across directories in densities_prep, prevented null dereference on strrchr, guarded against division by zero on state->shots across all views in view_reports, weight_volume_terminate, and summary_reports, guarded wdbp, rtip, obj_tbl, reg_tbl, and ged_gqa_plot.vbp before cleanup and destruction, and reset aborted state; in graph.cpp, checked ID_COMBINATION and pointers in process_comb and hl_scan_db, guarded child tree leaf names against null, verified file stream write success in hl_layout_and_output, removed redundant argument shifting in igraph mode and validated subcommand argument; in grid.c, guarded against null gv_s view state in grid_vsnap, grid_vls_print, and ged_grid_core, clamped user RGB color components to 0..255, and corrected error reporting parameter; in grid2model_lu.c, validated argv arguments and checked for zero denominator with ZERO macro before division; in grid2view_lu.c, guarded argv[1] and argv[2] against null; in group.c, validated group name and member arguments against null and empty strings; in heal.c, guarded arguments, clamped negative zipper tolerance, freed internal representation on non-BOT objects, and verified rt_db_put_internal return; in help.cpp, moved directory listing free inside directory traversal loop to eliminate directory listing leak, freed filepath on unreadable files, reset zeros counter per file so a binary file does not disable reading all subsequent documentation files, freed word buffer on each file exit, fixed cntptr type to size_t * preventing memory corruption, and checked bu_dir return before strdup while cleaning up resources when words == 0. |
| `SEC-0253` | `src/libged/help/test_help.c, src/libged/hide/hide.c, src/libged/how/how.c, src/libged/human/human.c, src/libged/illum/illum.c, src/libged/importFg4Section/importFg4Section.c, src/libged/include/plugin.h, src/libged/inside/inside.c, src/libged/instance/instance.c, src/libged/isize/isize.c` | `help/test_help.c:30-45; hide/hide.c:45-120; how/how.c:40-75, 120-160; human/human.c:50-95, 2380-2505; illum/illum.c:40-95, 100-120, 150-175; importFg4Section/importFg4Section.c:45-75; inside/inside.c:55-75; instance/instance.c:50-75; isize/isize.c:35-55` | Resource Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 11 commands (test_help, hide, how, human, illum, importFg4Section, plugin.h, inside, instance, isize): in test_help.c, guarded ac and av pointers before calling bu_setprogname, and called ged_close before return to cleanly shut down GED resources; in hide.c, guarded argv[i] arguments against null or empty strings, tracked write and export failures, and corrected db5_export_object3 invocation; in how.c, initialized dpp, added null guards on hdlp, vls, dpp, and style struct pointer sp->s_os in dl_how, validated argument bounds and pointers, handled -b flag correctly, and guarded gd_headDisplay before traversal; in human.c, replaced process-terminating bu_exit calls with graceful error return in read_args, added null checks on fopen returns before writing to file pointers in text and verbose, validated argc, verified wdb_dbopen return, replaced unchecked sprintf with snprintf, and called wdb_close to eliminate persistent database handle leak; in illum.c, added GED_CHECK_DATABASE_OPEN, GED_CHECK_VIEW, GED_CHECK_DRAWABLE, and GED_CHECK_ARGC_GT_0 to ged_labelvert_core, guarded argv[i] arguments, checked dmp before calling dm_set_dirty, guarded gdlp and obj in dl_set_illum, validated directory pointer and d_namep, checked argv[1] against null using BU_STR_EQUAL, and verified gd_headDisplay; in importFg4Section.c, validated argc and argv pointers, verified wdb_dbopen return, and added wdb_close to eliminate database handle leak; in include/plugin.h, audited plugin macros; in inside.c, guarded argc and argv[1] against null and verified outdp; in instance.c, validated argument count and null/empty object and instance names, guarded argv[3] against null, and safely formatted invalid operation string; in isize.c, added GED_CHECK_DATABASE_OPEN to prevent null dereference of gedp->dbip, and guarded against division by zero using ZERO macro on base2local factor. |
| `SEC-0254` | `src/libged/item/item.c, src/libged/joint/joint.c, src/libged/joint/joint.h, src/libged/joint2/joint2.c, src/libged/keep/keep.c, src/libged/keypoint/keypoint.c, src/libged/kill/kill.c, src/libged/killall/killall.c, src/libged/killrefs/killrefs.c, src/libged/killtree/killtree.c` | `item/item.c:45-80; joint/joint.c:120-140, 520-565, 875-920, 1100-1165, 1260-1310, 1480-1550, 2030-2070, 2180-2225, 2370-2440, 2900-2950; joint2/joint2.c:95-125, 220-255; keep/keep.c:95-155, 180-245; keypoint/keypoint.c:50-75; kill/kill.c:50-80; killall/killall.c:55-80; killrefs/killrefs.c:55-90; killtree/killtree.c:95-115, 230-265, 310-345` | Use-After-Free, Memory Corruption, Memory Leaks, Double-Free, Infinite Loop, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 12 commands (item, joint, joint2, keep, keypoint, kill, killall, killrefs, killtree): in item.c, validated argc range (3..6), guarded argv[1] and argv[2] against null, checked argv[3..5] before atoi, initialized rt_db_internal, and validated combination type freeing intern on mismatch; in joint.c, eliminated Cat 1 Use-After-Free in parse_hold by adding missing return after free_hold on EOF, fixed 64-bit struct member memory corruption where hp->priority was passed as double * clobbering flag, fixed infinite loop in joint_move dirs parsing by adding missing argv/argc increment, guarded against division by zero in parse_units with ZERO macro, eliminated persistent memory leaks in free_hold, part_solve, and joint_load by freeing arc sets, joint handles, and bu_vls, added null guards across hold_point_to_string, joint_unload, parse_error, joint_mesh, joint_save, joint_accept, joint_reject, reject_move, joint_solve, joint_hold, joint_move, and joint_cmd, fixed copy-paste typo in joint_reject usage, and corrected return status logic in joint_solve; in joint2.c, verified callback function pointers and selection counts, added bounds check preventing out-of-bounds read of argv[2] when argc == 2, and eliminated Cat 1 Double-Free of intern after GED_DB_PUT_INTERN; in keep.c, guarded directory and component pointers in node_write, closed incoming database on format mismatch and open failures to eliminate file descriptor leaks, and used wdb_close on all exits to properly release wdbp and underlying dbip; in keypoint.c, guarded argv[1..3] against null before bn_decode_vect and sscanf; in kill.c, enforced required object name argument after option stripping and guarded argv[i] in deletion loops; in killall.c, guarded argv[1] on -n check and enforced argument counts reporting usage; in killrefs.c, guarded argv[1], enforced argument count, guarded display erasure and tree deletion loops, and validated combination types; in killtree.c, guarded directory and data pointers in callbacks, enforced argument count after option parsing, guarded argv[i] in processing loop, and unconditionally freed argv allocations to eliminate -n memory leak. |
| `SEC-0255` | `src/libged/label/label.c, src/libged/lc/lc.c, src/libged/libfuncs/libfuncs.c, src/libged/lint/cyclic.cpp, src/libged/lint/ged_lint.h, src/libged/lint/invalid_shape.cpp, src/libged/lint/lint.cpp, src/libged/lint/lint_bot.cpp, src/libged/lint/missing.cpp, src/libged/lint/raytrace.cpp` | `label/label.c:45-65; lc/lc.c:50-70, 195-215, 290-370, 520-565; libfuncs/libfuncs.c:50-70, 85-105, 120-140, 150-170; lint/cyclic.cpp:60-80, 105-140, 190-210; lint/invalid_shape.cpp:55-90, 125-155; lint/lint.cpp:80-95, 235-265, 410-440; lint/lint_bot.cpp:115-135, 160-195, 255-275, 435-455, 615-705; lint/missing.cpp:65-75, 85-145, 160-205; lint/raytrace.cpp:160-180, 195-215` | Use-After-Free, Memory Leaks, Resource Leaks, Integer Underflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 13 commands (label, lc, libfuncs, lint): in label.c, validated argc and argv bounds before dereferencing argv[0] on help output; in lc.c, guarded against null struct pointers and string fields before bu_strcmp and atoi in cmp_regions and sort_regions, validated argc and argv in ged_lc_core, handled bu_file_realpath null returns and freed norm_name on errors, closed output file and freed vls on error exits, freed results1 and results2 search tables via db_search_free, freed db_full_path root, duplicated attribute strings and freed all duplicated strings on all exits to eliminate Cat 1 Use-After-Free of stack-scoped avs attributes, and replaced descending size_t loop with reverse counting loop to prevent unsigned integer underflow; in libfuncs.c, guarded argv, argv[0], argv[1], and argv[2] before bu_sscanf, bn_decode_mat, and bn_decode_vect across mat_ae, mat_mul, mat4x3pnt, and mat_scale_about_pnt, and added missing newlines to usage strings; in lint/cyclic.cpp, freed path strings allocated by db_path_to_string, replaced process-terminating bu_bomb with graceful error logging, initialized rt_db_internal, and validated ID_COMBINATION and combination pointers; in lint/ged_lint.h, audited header declarations; in lint/invalid_shape.cpp, initialized intern, eliminated memory leaks of BREP, ARB8, DSP, and EXTRUDE internal representations on early returns by calling rt_db_free_internal across all exits, properly initialized and freed pc search table, and guarded directory pointers; in lint/lint.cpp, guarded ostr.pop_back() against empty problem vectors, validated key_val parsing, fixed off-by-one underflow in argument verification loop that caused argv[-1] out-of-bounds reads, freed combination members with mk_freemembers after mk_lcomb, and initialized is_region; in lint/lint_bot.cpp, validated triangle vertex indices against num_vertices and guarded normal magnitude before division in bot_face_normal, bounded triangle indices and vertex indices in tri_to_json and plot_bad_tris, guarded map iterator dereference in bot_check, clamped ncpus to num_faces, set last worker end to num_faces so the final triangle face is not skipped, cleaned per-worker resources with rt_clean_resource, and freed worker state array to eliminate thread resource and memory leaks; in lint/missing.cpp, replaced bu_bomb with graceful error logging, added buffer size checks against header lengths before pointer arithmetic in shape_find_missing to prevent buffer over-reads in DSP and EXTRUDE objects, and initialized and freed rt_db_internal structures across all exits; in lint/raytrace.cpp, verified ID_COMBINATION and tree pointers before traversing combination trees in subtree_has_halfspace and collect_subtree. |
| `SEC-0256` | `src/libged/list/list.c, src/libged/lod/lod.c, src/libged/lod/lod2.cpp, src/libged/log/log.c, src/libged/ls/ls.c, src/libged/lt/lt.c, src/libged/m2v_point/m2v_point.c, src/libged/make/make.c, src/libged/make_name/make_name.c, src/libged/man/man.c` | `list/list.c:55-140; lod/lod.c:50-115; lod/lod2.cpp:35-45; log/log.c:35-90; ls/ls.c:60-170, 290-340, 420-505; lt/lt.c:40-110, 125-155; m2v_point/m2v_point.c:50-80; make/make.c:85-185; make_name/make_name.c:45-95; man/man.c:60-105, 135-215` | Memory Leaks, Resource Leaks, Integer Overflow, Infinite Loop, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 14 commands (list, lod, lod2, log, ls, lt, m2v_point, make, make_name, man): in list.c, validated argc and argv bounds, added missing newline to usage, guarded argv[arg] against null before slash search, closed wdbp immediately after copying initial tree state to prevent wdbp handle leak, freed full path on traversal failures, initialized and freed internal structures, and guarded describe callbacks; in lod.c, checked argv bounds, guarded against null gvp and gvp->gv_s view state pointers before member access, validated non-negative scale factors using bu_sscanf, and guarded argv subcommands against null; in lod2.cpp, guarded gedp and ged_result_str against null before writing result; in log.c, guarded clientdata and str in log_hook, checked gedp->ged_log before hook operations and log dumps, validated argv[1], and added missing newlines to usage messages; in ls.c, guarded list_of_names and num_in_list in vls_long_dpp and vls_line_dpp, guarded directory pointers and names against null, initialized and freed intern representations, guarded ft_label and binunif typestrings before string length operations, guarded name and type widths against unsigned underflow, guarded argv in _ged_ls_attr_objs and _ged_ls_named_objs, guarded results_obj before formatting, and freed str vls on all exit paths to eliminate memory leaks; in lt.c, initialized intern, validated ID_COMBINATION and pointers before accessing comb tree, freed intern and vls on flatten tree error exit paths to eliminate memory leaks, guarded tree leaf names against null, and validated argv bounds and option characters; in m2v_point.c, guarded argv arguments, added missing newlines to usage, and replaced raw sscanf with bu_sscanf; in make.c, validated positive scale factors, guarded extrude_ip and freed internal on error, replaced sprintf with snprintf, and called rt_db_free_internal on db_diradd failure to eliminate primitive internal memory leaks; in make_name.c, validated argv pointers, added missing newlines, parsed -s argument with bu_sscanf ensuring non-negative index, added loop bounds and overflow guards in candidate generation loop, and avoided redundant null byte injection; in man.c, checked argv bounds, verified brlman path existence, freed lang vls on all early returns to eliminate memory leaks, cleaned up failed subprocess handles with bu_process_wait_n, and waited for CLI mode processes to exit cleanly. |
| `SEC-0257` | `src/libged/match/match.c, src/libged/mater/mater.cpp, src/libged/material/material.c, src/libged/metaball/metaball.c, src/libged/mirror/mirror.c, src/libged/model2grid_lu/model2grid_lu.c, src/libged/model2view/model2view.c, src/libged/model2view_lu/model2view_lu.c, src/libged/move/move.c, src/libged/move_all/move_all.c` | `match/match.c:45-80; mater/mater.cpp:245-285, 335-375, 485-535, 620-675, 935-970, 1630-1715; material/material.c:95-175, 230-315, 330-380, 420-475, 510-580, 610-660; metaball/metaball.c:165-200, 240-275, 320-355, 410-445; mirror/mirror.c:115-185; model2grid_lu/model2grid_lu.c:50-80; model2view/model2view.c:50-75; model2view_lu/model2view_lu.c:50-80; move/move.c:75-135; move_all/move_all.c:115-185, 280-340` | Memory Corruption, Resource Leaks, Memory Leaks, Out-of-bounds Memory Access, Integer Underflow, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 15 commands (match, mater, material, metaball, mirror, model2grid_lu, model2view, model2view_lu, move, move_all): in match.c, added missing newline to usage, guarded argv pointers against null, replaced unchecked pointer increment loop with safe index-bounded loop, and guarded dp and dp->d_namep before bu_path_match; in mater.cpp, freed d_path_dir vls across all exits, closed wdbp handle with wdb_close in mater_import, safely parsed mat_id with bu_sscanf before comparison, eliminated heap allocations for std::set and msgs to prevent memory leaks, freed new_buf from analyze_densities_write and bin_ext on db_dirbuild failure, replaced dynamic heap avs allocation with stack struct and ensured bu_avs_free is invoked on all iterations and exits, guarded oname before std::string conversion, safely parsed integer IDs, returned BRLCAD_ERROR on fail, and freed nname before early returns; in material.c, eliminated Cat 1 memory corruption by removing illegal bu_free on stack buffer, closed densityTable file descriptor on all paths, closed wdbp handle with wdb_close on all exits across import, create, set, and remove, freed AVS property tables on each loop iteration and exit, validated argc bounds before accessing argv indices, guarded string parsing loop against integer underflow, verified ID_MATERIAL internal type before accessing material structure, called rt_db_free_internal on all exit paths, prevented orphaning of bu_vls string buffers by using bu_vls_strcpy/bu_vls_trunc instead of BU_VLS_INIT, and propagated subcommand error return codes; in metaball.c, closed wdbp handle on all paths, verified DB5_MINORTYPE_BRLCAD_METABALL before casting internal pointer, replaced raw sscanf with bu_sscanf, fixed out-of-bounds pointer dereference of argv[3] when argc was 3 in delete error message, and added missing newlines to usage messages; in mirror.c, called rt_db_free_internal on all exit paths after rt_db_get_internal to eliminate primitive memory leaks, replaced raw sscanf with bu_sscanf, and guarded argv pointers against null; in model2grid_lu.c and model2view_lu.c, moved matrix dereferences after GED_CHECK_DATABASE_OPEN to prevent null dereference of gedp, guarded argv arguments, replaced sscanf with bu_sscanf, and added missing newlines; in model2view.c, guarded argv arguments, replaced raw sscanf with bu_sscanf, and added missing newline to usage; in move.c and move_all.c, called rt_db_free_internal after rt_db_put_internal to eliminate memory leaks, replaced libc free with bu_free on heap strings allocated by bu_strdup, safely updated display list path strings, guarded old and new name arguments against null, and fixed format parameter mismatch in name length limit error message. |
| `SEC-0258` | `src/libged/move_arb_edge/move_arb_edge.c, src/libged/move_arb_face/move_arb_face.c, src/libged/mrot/mrot.c, src/libged/nirt/nirt.cpp, src/libged/nmg/nmg.c, src/libged/nmg/nmg_cmface.c, src/libged/nmg/nmg_collapse.c, src/libged/nmg/nmg_fix_normals.c, src/libged/nmg/nmg_kill_f.c, src/libged/nmg/nmg_kill_v.c` | `move_arb_edge/move_arb_edge.c:65-135, 180-230, 275-320; move_arb_face/move_arb_face.c:90-155, 175-240; mrot/mrot.c:50-75; nirt/nirt.cpp:210-265, 335-360, 395-425, 475-495, 550-565, 615-635, 695-755; nmg/nmg.c:40-95, 105-180, 205-285; nmg/nmg_cmface.c:65-155; nmg/nmg_collapse.c:50-155; nmg/nmg_fix_normals.c:55-95; nmg/nmg_kill_f.c:35-70, 95-135; nmg/nmg_kill_v.c:35-255, 275-315` | Memory Corruption, Use-After-Free, Memory Leaks, Resource Leaks, Out-of-bounds Memory Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 16 commands (move_arb_edge, move_arb_face, mrot, nirt, nmg, nmg_cmface, nmg_collapse, nmg_fix_normals, nmg_kill_f, nmg_kill_v): in move_arb_edge.c, closed wdbp handle on all exit paths in move_arb_edge and find_arb_edge, called rt_db_free_internal after rt_db_put_internal to eliminate memory leaks, guarded argv pointers against null, replaced raw sscanf with bu_sscanf, and added missing newlines to usage and error messages; in move_arb_face.c, eliminated Cat 1 memory corruption and stack array overflow by enforcing face bounds check on both positive and negative indices for the specific arb_type before modifying planes array, closed wdbp handle on all paths, called rt_db_free_internal after rt_db_put_internal, returned BRLCAD_ERROR when object is not an ARB, replaced sscanf with bu_sscanf, and added missing newlines; in mrot.c, validated argv and argv[i] pointers against null, and added missing newlines; in nirt.cpp, eliminated Cat 1 heap corruption on subprocess failure by replacing incorrect cast and free of string pointers as bu_vls structures with bu_free, fixed use of freed av_args and memory leak of obj by directly emitting draw commands to stdin in skip_drawn block, freed nirt exec string and nv options across all error returns, corrected loop to inspect argv[i] instead of repeatedly checking argv[0], freed dpv allocated by db_ls, fixed off-by-4 bug in ged_vnirt_core where av[i] = NULL clobbered argument pointers, replaced sscanf with bu_sscanf, guarded ged_gdp before dl_set_wflag, and added missing newlines; in nmg.c, eliminated Cat 1 linked list corruption in get_face_list where actual model face list pointers were stolen into stack f_list causing circular loops and free crashes by using detached copy structs, freed internal representations and face list allocations, fixed off-by-one subcommand lookup in ged_nmg_core where subcmd was erroneously read from argv[0] instead of argv[1], guarded argv[2] before dereferencing in kill, move, and make subcommands, and propagated subcommand return codes; in nmg_cmface.c, freed verts buffer to eliminate persistent memory leaks, closed wdbp handle on all paths, replaced atof with bu_sscanf, corrected variable in error message, and added missing newlines; in nmg_collapse.c, closed wdbp on all exit paths, freed internal representation on non-planar face detection, validated tolerances with bu_sscanf and ZERO macro, and added missing newlines; in nmg_fix_normals.c, persisted fixed normals to database via rt_db_put_internal, freed internal representation, and added missing newlines; in nmg_kill_f.c, eliminated Cat 1 Use-After-Free in remove_face by immediately returning once target face is destroyed by nmg_kfu, closed wdbp on all paths, parsed fid with bu_sscanf, and added missing newlines; in nmg_kill_v.c, eliminated Cat 1 Use-After-Free and Double-Free in remove_vertex by restarting topology search on each deletion instead of continuing iteration on freed loopuses and edgeuses, closed wdbp on all paths, parsed coordinates with bu_sscanf, and added missing newlines. |
| `SEC-0259` | `src/libged/nmg/nmg_make_v.c, src/libged/nmg/nmg_mm.c, src/libged/nmg/nmg_move_v.c, src/libged/nmg/nmg_simplify.c, src/libged/npush/npush.cpp, src/libged/ocenter/ocenter.c, src/libged/open/open.cpp, src/libged/orient/orient.c, src/libged/orotate/orotate.c, src/libged/oscale/oscale.c` | `nmg/nmg_make_v.c:60-135; nmg/nmg_mm.c:45-75; nmg/nmg_move_v.c:280-325; nmg/nmg_simplify.c:90-105, 235-295; npush/npush.cpp:1190-1285, 1380-1445, 1670-1705; ocenter/ocenter.c:55-108; open/open.cpp:55-87, 135-150; orient/orient.c:45-80; orotate/orotate.c:60-125; oscale/oscale.c:60-115` | Use-After-Free, Memory Leaks, Resource Leaks, Out-of-bounds Memory Access, Logic Errors, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 17 commands (nmg_make_v, nmg_mm, nmg_move_v, nmg_simplify, npush, ocenter, open, orient, orotate, oscale): in nmg_make_v.c, validated vertex coordinates with bu_sscanf, closed wdbp handle with wdb_close on error and success paths, freed verts buffer on wdb_put_internal failure, and added missing newlines to usage and error strings; in nmg_mm.c, freed internal representation on db_diradd failure to prevent memory leak, checked rt_db_put_internal return status, and added missing newline to usage; in nmg_move_v.c, validated 6 coordinate arguments using bu_sscanf, closed wdbp handle on error and success exits, reported correct object name on error, and added missing newline to usage; in nmg_simplify.c, eliminated Cat 1 Use-After-Free and database corruption where failure of all conversion methods (arb/tgc/poly) fell through to out1: attempting to add and write a freed/stale new_intern, closed wdbp handle on all exit paths in out3:, and added missing newlines to usage strings; in npush.cpp, eliminated persistent leak of rt_wdb handle by immediately copying tolerance and closing wdbp, freed temporary msgs vls on early exit in non-verbose conflict path, added missing newlines to conflict and error messages, and preserved all missing/added tops reports by using bu_vls_printf instead of bu_vls_sprintf; in ocenter.c, added bounds check on gtd.gtd_objpos to prevent negative array indexing out-of-bounds, replaced sscanf with bu_sscanf, and added missing newlines to usage and error strings; in open.cpp, added missing newlines in usage and error strings, returned BRLCAD_OK when print_help is requested, and safely destroyed existing ged_lod context and dbi_state before reassigning; in orient.c, fixed off-by-one error in error reporting where argv[i-1] was printed instead of argv[i], replaced sscanf with bu_sscanf, and added missing newlines to usage strings; in orotate.c, added bounds check on gtd.gtd_objpos to prevent out-of-bounds array access, replaced sscanf with bu_sscanf, and added missing newlines to usage and error strings; in oscale.c, added scale factor validation with bu_sscanf and SQRT_SMALL_FASTF to prevent degenerate or non-positive scaling, added bounds check on gtd.gtd_objpos, and added missing newlines to usage and error strings; |
| `SEC-0260` | `src/libged/osg.cpp, src/libged/otranslate/otranslate.c, src/libged/overlay/overlay.c, src/libged/path.c, src/libged/pathlist/pathlist.c, src/libged/pathsum/pathsum.c, src/libged/perspective/perspective.c, src/libged/pipe/pipe.c, src/libged/pix2fb/pix2fb.c, src/libged/plot/plot.c` | `osg.cpp:55-75, 150-165; otranslate.c:55-90; overlay.c:105-160, 195-225, 250-290; path.c:45-75; pathlist.c:35-105; pathsum.c:75-125; perspective.c:50-80; pipe.c:65-145, 170-235, 255-315, 340-435; pix2fb.c:70-175, 180-235; plot.c:50-60, 210-285` | Resource Leaks, Double-Free, Buffer Overflow, Logic Errors, Out-of-bounds Memory Access, and Process Termination in Library Function | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 18 commands (osg, otranslate, overlay, path, pathlist, pathsum, perspective, pipe, pix2fb, plot): in osg.cpp, added NULL pointer checks to _osgLoadHiddenSolid, _osgLoadSolid, and _ged_osgLoadScene, and verified osp->viewer validity; in otranslate.c, added bounds check on gtd.gtd_objpos preventing negative out-of-bounds array access, replaced sscanf with bu_sscanf, and added missing newlines to usage and error strings; in overlay.c, fixed out-of-bounds / null pointer dereference on argv[1] when bu_file_list returned <= 0 by changing to argv[0], freed vbp on fopen failure inside loop to eliminate memory leak, preserved cmd_name for diagnostics, and added missing newlines; in path.c, fixed critical logic flaw where the return value of path_validate_recurse was ignored allowing invalid paths to pass validation, checked intern.idb_type == ID_COMBINATION, and added missing newline; in pathlist.c, eliminated persistent wdbp database handle leak by immediately calling wdb_close after reading initial tree state, replaced static mutable global pathListNoLeaf with thread-safe struct pathlist_data passed via client_data, checked fp_len > 1 before decrement, and added missing newlines; in pathsum.c, checked _GED_TRACE_MAX_LEVELS upper bound to prevent stack buffer overflow in gtd.gtd_obj, duplicated path argument before calling strtok to avoid in-place mutation of argv and thread safety issues, and added missing newlines; in perspective.c, replaced sscanf with bu_sscanf, added angle range check [0, 180) to prevent division by zero or singularity in persp_mat, and added missing newlines; in pipe.c, eliminated persistent wdbp leaks by calling wdb_close across append, find, and move commands, fixed out-of-bounds argv[3] access when argc == 3 in delete command by correcting to argv[2], eliminated double-free hazards of intern following GED_DB_PUT_INTERN, replaced sscanf with bu_sscanf, checked seg_i >= 0, and added missing newlines; in pix2fb.c, eliminated process termination bug where bu_exit was invoked on file open failure by returning error and logging to ged_result_str, fixed usage string repetition, checked infd > 0 before close, and formatted error messages with argv[0] and newlines; in plot.c, removed mutable static local variables in dl_plot making it reentrant and thread-safe, preserved cmd_name before advancing argv, freed bu_vls str on popen failure, formatted system errors with strerror(errno) into result string, and added missing newlines. |
| `SEC-0261` | `src/libged/pmat/pmat.c, src/libged/pmodel2view/pmodel2view.c, src/libged/png/png.c, src/libged/png2fb/png2fb.c, src/libged/pnts/pnts.cpp, src/libged/pnts_util.c, src/libged/pnts_util.h, src/libged/points_eval.c, src/libged/polyclip.cpp, src/libged/prcolor/prcolor.c` | `pmat/pmat.c:50-65; pmodel2view/pmodel2view.c:45-55; png/png.c:40-105, 148-185, 320-475; png2fb/png2fb.c:55-70, 120-135, 150-185; pnts/pnts.cpp:105-150, 340-348, 478-486, 604-612, 646-700, 810-818, 900-1045, 1070-1130, 1220-1225, 1450-1460, 1538-1555, 1585-1595; pnts_util.c:125-215, 295-410; points_eval.c:45-65; polyclip.cpp:45-55, 125-140, 168-185, 280-286, 305-316, 350-370, 570-585; prcolor/prcolor.c:84-95, 106-118` | Memory Leaks, Resource Leaks, Buffer Overflow, Infinite Loop, In-place Argument Mutation, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 19 commands (pmat, pmodel2view, png, png2fb, pnts, pnts_util, pnts_util.h, points_eval, polyclip, prcolor): in pmat.c, added diagnostic error message on bn_decode_mat failure and fixed usage formatting; in pmodel2view.c, added missing newline to usage string; in png.c, encapsulated mutable globals in struct png_state, removed static locals from draw_png_solid for thread safety, clamped raster coordinates against image bounds to prevent buffer overflow, clamped img_size to prevent integer overflow in buffer allocation, replaced raw sscanf with bu_sscanf, freed image and bytes buffers and destroyed libpng structures via png_destroy_write_struct on all error and success exits to eliminate persistent memory leaks, and added missing newlines to usage and error messages; in png2fb.c, removed duplicate usage prefix, distinguished file open failure from help request returning error instead of printing usage, replaced stderr writes with bu_log, and added missing newlines; in pnts.cpp, added bounds checks in _pnts_collect_arrays linked list loops to prevent heap buffer overflow, eliminated in-place mutation of caller argv in _ged_pnts_cmd_tri and ged_pnts_core by passing offset pointers and lengths to bu_cmd, propagated subcommand return codes, fixed unsafe argc decrement when argc <= 0, freed fl and unit vls structures on all exits in _ged_pnts_cmd_read, used RAII guard for pnt_str in _ged_pnts_cmd_write to eliminate persistent memory leak on every write operation, freed intern on fopen failure, and added missing newlines to result and error strings; in pnts_util.c, added NULL pointer checks to _ged_pnt_v_set, _ged_pnt_c_set, _ged_pnt_s_set, _ged_pnt_n_set, _ged_pnts_init_head_pnt, _ged_pnts_add, and _ged_pnts_dup; in points_eval.c, guarded d->dbip against NULL, checked fp->fp_len > 0 before calling DB_FULL_PATH_CUR_DIR, and properly initialized intern; in polyclip.cpp, closed wdbp database handles on all exit paths in ged_import_polygon, ged_polygons_overlap, and ged_polygon_fill_segments to eliminate persistent handle leaks, guarded input pointers, validated vfilldelta > SMALL_FASTF to prevent infinite loop hang, freed all 2D polygon contours, contour points, hole arrays, and result_vls on completion in ged_polygon_fill_segments to eliminate massive memory leak, and freed intern on export failure; in prcolor.c, replaced sprintf with snprintf to prevent buffer overflow, and added missing newlines to usage and none output. |
| `SEC-0262` | `src/libged/prefix/prefix.c, src/libged/process/process.c, src/libged/ps/ps.c, src/libged/pset/pset.c, src/libged/pull/pull.c, src/libged/push/push.c, src/libged/put/put.c, src/libged/put_comb/put_comb.c, src/libged/putmat/putmat.c, src/libged/qray.cpp` | `prefix.c:45-65, 85-175; process.c:54-105, 112-175, 176-220; ps.c:91-135, 229-270, 329-440; pset.c:37-65, 86-150; pull.c:68-135, 169-245, 265-295; push.c:70-95, 200-295; put.c:51-115; put_comb.c:128-165, 355-450, 498-560; putmat.c:52-145, 191-250; qray.cpp:45-55, 78-105, 116-170` | Memory Corruption, Resource Leaks, Double-Free, Pointer Cast Error, and Underflows | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 20 commands (prefix, process, ps, pset, pull, push, put, put_comb, putmat, qray): in prefix.c, removed leftover debugging bu_log prints, guarded prefix against empty string, guarded directory names against null/empty in rename loop, freed tempstring_v5 on all early error exits to eliminate memory leaks, validated intern.idb_type == ID_COMBINATION before tree walk, and added missing newlines to usage and error strings; in process.c, fixed Cat 1 integer underflow and memory exhaustion in _ged_process_list where longest_pid < 3 underflowed longest_pid - 3 to UINT_MAX - 2 when passed to %*c in bu_vls_sprintf, freed cmdroot before return in _ged_process_gabort to eliminate memory leak, added null guards on subprocess pointers, streamlined subcommand dispatch in ged_process_core to properly display help on unrecognized or malformed arguments, and added missing newlines; in ps.c, removed mutable static local variables in ps_draw_solid making it reentrant and preventing state leakage between solids, replaced sscanf with bu_sscanf, changed early return on bad color to goto bad so font, title, and creator are freed on error, guarded sp and hdlp against null in ps_draw_body, guarded bu_optind > 0 before accessing argv[bu_optind-1], and added missing newlines to usage and error strings; in pset.c, replaced sscanf with bu_sscanf, guarded attribute against null and empty string in _ged_set_metaball, clamped threshold when ZERO(threshold), guarded argv arguments against null, simplified cleanup to unconditionally call rt_db_free_internal(&intern) whenever ret != BRLCAD_OK, and added missing newlines; in pull.c, fixed Cat 1 pointer cast corruption in pull_leaf where mp (mat_t *) was cast to struct bu_vls * and passed to bu_vls_printf, fixed massive memory leak where modified primitives transformed by ft_xform were never written back or freed by adding rt_db_put_internal and rt_db_free_internal, fixed option parsing bug in ged_pull_core where argc != 2 check and db_lookup preceded bu_getopt making -d impossible to pass, passed (matp_t)NULL instead of 0-matrix m to rt_db_get_internal in pull_comb, freed intern on empty comb trees, checked return of bn_mat_inverse, and added missing newlines; in push.c, eliminated persistent resource leak of wdbp by immediately extracting init_state and calling wdb_close(wdbp), guarded argc < 1 after option stripping, guarded null directory and database pointers and freed intern on empty comb trees in identitize, and added missing newlines; in put.c, eliminated Cat 1 double-free of intern where rt_db_free_internal(&intern) was called after wdb_put_internal (which unconditionally frees the internal structure on both success and failure), closed wdbp with wdb_close(wdbp) on both error and success paths to eliminate handle leak, guarded argv[1] and argv[2] against null and empty strings, and added missing newlines; in put_comb.c, eliminated Cat 1 buffer underflow in trailing space stripping loop where empty or all-space names decremented i below 0 and accessed name[-1], fixed logic bug in mktemp_comb where db_lookup checked template string str instead of candidate name, freed rt_tree_array on error and success paths in put_tree_into_comb_and_export to eliminate persistent memory leak, freed intern on db_diradd failure in save_comb, replaced sscanf with bu_sscanf and guarded null str in put_rgb_into_comb, and added missing newlines; in putmat.c, eliminated Cat 1 memory leaks of name1 and name2 in _getmat where bu_vls_free was omitted on all successful matrix retrieval paths, removed machine-identifiable paths from error messages, guarded against null argv[1] and argv[2], and added missing newlines; in qray.cpp, fixed Cat 1 out-of-bounds string access in qray_init when parsing format lines shorter than expected, and added null pointer checks on gdp, gdp->gd_qray_fmts, and vhead in qray_init, qray_free, and qray_data_to_vlist. |
| `SEC-0263` | `src/libged/qray.h, src/libged/qray/qray.c, src/libged/rcodes/rcodes.c, src/libged/rect/rect.c, src/libged/red/red.c, src/libged/regdef/regdef.c, src/libged/region/region.c, src/libged/repair/repair.cpp, src/libged/rfarb/rfarb.c` | `qray.h:35-45; qray/qray.c:65-105, 140-185, 230-310, 395-430; rcodes/rcodes.c:55-80, 95-170; rect/rect.c:60-95, 115-185, 210-250, 440-490; red/red.c:135-180, 230-320, 410-530, 680-740, 890-970; regdef/regdef.c:40-100; region/region.c:50-110; repair/repair.cpp:35-145; rfarb/rfarb.c:65-175, 215-240` | Double-Free, Memory Leaks, Division by Zero, Uninitialized Memory Reads, Pointer Aliasing, and Missing Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 21 commands (qray, qray.h, quit, rcodes, rect, red, regdef, region, repair, rfarb): in qray.h, fixed macro parameter bug in DG_QRAY_BOTH; in qray/qray.c, added null checks on gedp->i and gedp->i->ged_gdp across all entry points, replaced sscanf with bu_sscanf, corrected typo in command name, and added missing newlines to error strings; in quit/quit.cpp, verified clean with no changes needed; in rcodes/rcodes.c, eliminated Cat 1 double-free of intern on rt_db_put_internal failure (which unconditionally frees intern internally), eliminated persistent memory leak by freeing intern when changed == 0 or when non-combination objects are encountered, replaced sscanf with bu_sscanf, added null and empty string checks on argv[1], and added missing newlines to usage and error messages; in rect/rect.c, added null check on gedp->ged_gvp->gv_s, added ZERO(grsp->aspect) and cdim <= 0 checks to prevent division by zero in rect_image2view and rect_adjust_for_zoom, validated user coordinate dimensions to prevent division by zero, replaced sscanf with bu_sscanf, guarded argv[0] and argv[1] against null, and added missing newlines; in red/red.c, eliminated mutable file-scope static global buffer _ged_tmpfil by passing stack-allocated buffer into build_comb and write_comb to ensure thread safety, eliminated persistent memory leaks of rt_tree_array across all error and success exits in both build_comb and write_comb, freed intern on all early error paths in build_comb and after write_comb in ged_red_core, freed allocated matrix on error in _ged_find_matrix, replaced sprintf with snprintf to prevent buffer overflow, and added missing newlines; in regdef/regdef.c, guarded wdbp against null return from wdb_dbopen, replaced sscanf with bu_sscanf, and added missing newlines to usage and output strings; in region/region.c, guarded wdbp against null, guarded argv[1], argv[i], and argv[i+1] against null/empty, and added missing newlines to usage and error strings; in repair/repair.cpp, added GED_CHECK_DATABASE_OPEN, GED_CHECK_READ_ONLY, and GED_CHECK_ARGC_GT_0 guards, handled bu_opt_parse error returns, eliminated Cat 1 double-free of intern by only freeing intern when ft_repair returns non-zero (rt_db_put_internal unconditionally frees intern on both success and failure), guarded argv[i] against null/empty, and added newlines to JSON status messages; in rfarb.c, eliminated Cat 1 double-free of internal on rt_db_put_internal failure and returned BRLCAD_ERROR, eliminated memory leak of internal on db_diradd failure, prevented uninitialized stack coordinate usage by returning BRLCAD_ERROR when bu_sscanf coordinate parsing fails, replaced sscanf with bu_sscanf, guarded argv against null, and added missing newlines to all error and usage messages. |
| `SEC-0264` | `src/libged/rm/rm.c, src/libged/rmap/rmap.c, src/libged/rmat/rmat.c, src/libged/rmater/rmater.c, src/libged/rot/rot.c, src/libged/rot/rotate_about.c, src/libged/rot_point/rot_point.c, src/libged/rrt/rrt.c, src/libged/rt/rt.c, src/libged/rtabort/rtabort.c` | `rm/rm.c:555-575, 895-925, 1190-1215; rmap/rmap.c:45-145; rmat/rmat.c:48-65; rmater/rmater.c:30-75, 100-155; rot/rot.c:35-46; rot/rotate_about.c:45-66; rot_point/rot_point.c:50-85; rrt/rrt.c:52-68; rt/rt.c:80-132; rtabort/rtabort.c:52-73` | Stack Buffer Overflow, Memory Leaks, Logic Inversion, Out-of-bounds Array Access, Command Length Miscalculation, and Missing Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 22 commands (rm, rmap, rmat, rmater, rot, rotate_about, rot_point, rrt, rt, rtabort): in rm.c, fixed boolean CSG tree subtraction bug in _rm_tree_remove_named_leaf_instance where removing the left child of an OP_SUBTRACT node erroneously promoted the right child to a positive union instead of freeing the right tree and nullifying the subtraction, guarded null and empty operands in _rm_expand_operand while preserving unmatched glob patterns for standard error reporting, guarded argv[i] against null/empty in operand loop, and added missing newline to usage string; in rmap.c, added _ged_rmap_free_list helper and called it on rt_db_get_internal failure to eliminate persistent memory leaks of id_to_names and id_names list nodes, validated intern.idb_type == ID_COMBINATION and intern.idb_ptr before casting, replaced bu_vls_addr with bu_vls_cstr, and added missing newlines to usage and error messages; in rmat.c, added null check on argv[1], reported diagnostic error message when bn_decode_mat fails, and added missing newline to usage; in rmater.c, fixed stack buffer overflow in extract_mater_from_line by bounding string extraction to name and shader buffer capacities, replaced raw sscanf with bu_sscanf, prevented undefined behavior and crash by continuing loop instead of falling through on rt_db_get_internal failure, validated intern.idb_type == ID_COMBINATION before accessing comb, used bu_vls_trunc to safely clear comb->shader, and added missing newlines; in rot.c, added standard GED_CHECK_DATABASE_OPEN, GED_CHECK_VIEW, and GED_CHECK_ARGC_GT_0 guards; in rotate_about.c, guarded against out-of-bounds byte reads and null dereference on argv[1], and added missing newlines to current setting output and usage strings; in rot_point.c, fixed copy-paste typo where ged_m2v_point was reported instead of command name, replaced sscanf with bu_sscanf, guarded coordinate arguments against null, and added missing newlines; in rrt.c, fixed command length miscalculation where gd_rt_cmd_len was set only to the count of who objects rather than the full command length, eliminated persistent memory leak of strings allocated by ged_who_argv by freeing each who object after execution, and guarded argv[i] against null; in rt.c, replaced sprintf with snprintf, provided PATH fallback when bu_dir returns null, guarded argv[i] against null, and explicitly null-terminated gd_rt_cmd; in rtabort.c, added null checks on rrp, rrp->p, and cmd before processing and terminating subprocesses, and added missing newline to usage string. |
| `SEC-0265` | `src/libged/rtcheck/rtcheck.c, src/libged/rtcheck/rtcheck2.cpp, src/libged/rtwizard/rtwizard.c, src/libged/savekey/savekey.c, src/libged/scale/scale.c, src/libged/search/search.c, src/libged/select/select.c, src/libged/select/select2.cpp, src/libged/set_output_script/set_output_script.c, src/libged/set_transparency/set_transparency.c` | `rtcheck/rtcheck.c:100-165, 225-285, 320-330; rtcheck/rtcheck2.cpp:80-165, 220-280, 310-320; rtwizard/rtwizard.c:45-75, 110-180, 185-195; savekey/savekey.c:45-55, 75-100; scale/scale.c:40-60; search/search.c:285-295, 395-485, 570-580; select/select.c:45-50, 110-115, 240-245, 375-480, 505-600; select/select2.cpp:120-130, 235-265, 285-320, 445-505; set_output_script/set_output_script.c:45-60; set_transparency/set_transparency.c:30-65, 85-125` | Resource Leaks, Memory Leaks, Null Pointer Dereferences, Out-of-bounds Memory Access, and Missing Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 23 commands (rtcheck, rtcheck2, rtwizard, savekey, scale, search, select, select2, set_output_script, set_transparency): in rtcheck.c, added null checks in rtcheck_vector_handler and rtcheck_output_handler on rtcp, rrtp, gedp, rtcp->fp, and rrtp->p, provided PATH fallback when bu_dir returns null, allocated args + 1 for gd_rt_cmd, guarded argv[i] against null, and eliminated persistent memory leak of strings allocated by ged_who_argv by freeing each string on error and success paths; in rtcheck2.cpp, added null checks in rtcheck_vector_handler and rtcheck_output_handler on rtcp, rrtp, gedp, rtcp->fp, and rrtp->p, provided PATH fallback when bu_dir returns null, allocated args + 1, guarded argv[i] against null, and freed strings allocated by ged_who_argv on error and success paths; in rtwizard.c, added null checks on gedp and gd_rt_cmd in _ged_run_rtwizard, replaced sprintf with snprintf, allocated args + 1 for gd_rt_cmd, guarded argv[i] against null, and freed strings returned by ged_who_argv upon command completion to eliminate memory leaks; in savekey.c, added null checks on gedp, gvp, fp, and eye_model in savekey_rt_oldwrite, validated time argument with bu_sscanf instead of raw atof and reported error on invalid input, replaced raw perror writes to stderr with structured error logging to ged_result_str, checked argv[1], and added missing newlines to usage and error strings; in scale.c, added GED_CHECK_DATABASE_OPEN, GED_CHECK_VIEW, and GED_CHECK_ARGC_GT_0 guards, validated scale factor against non-positive and non-finite values and reported error instead of silently returning OK, and added missing newline to error message; in search.c, corrected pointer size calculation from sizeof(char *) to sizeof(struct directory *) in _ged_search_localized_obj_list, added missing GED_CHECK_DATABASE_OPEN and GED_CHECK_ARGC_GT_0 guards in ged_search_core, guarded argv_orig[i] against null in option scanning loop, checked bu_argv_dup return value, and bounded plan_argv < argc in both plan discovery and plan string construction loops to prevent out-of-bounds pointer reads; in select.c, plugged persistent leak of rt_wdb database handles opened via wdb_dbopen by ensuring wdb_close is called immediately after import or upon error in both ged_select_core and ged_rselect_core, guarded ged_gvp->gv_s before accessing screen rectangle, freed intern on early error paths, replaced raw sscanf with bu_sscanf, added missing newlines to all error and usage messages, and added null checks on botip, botip->vertices, hdlp, and vls; in select2.cpp, added GED_CHECK_DATABASE_OPEN and GED_CHECK_ARGC_GT_0 guards in ged_select2_core, guarded argv[i] in option loop, safely checked argc <= 0 before indexing argv[0] in subcommand dispatch, added null checks in _select_cmd_msgs, and added missing newlines in _select_cmd_add and _select_cmd_rm; in set_output_script.c, added missing newline to usage, and guarded against passing null ged_output_script to %s in bu_vls_printf; in set_transparency.c, added GED_CHECK_DATABASE_OPEN guard, returned GED_HELP on argc == 1, replaced raw sscanf with bu_sscanf, clamped transparency to [0.0, 1.0], returned BRLCAD_ERROR when _ged_build_dpp fails, added null checks on gedp, i, ged_gdp, dpp, hdlp, and sp->s_os in dl_set_transparency, and added missing newlines to usage messages. |
| `SEC-0266` | `src/libged/set_uplotOutputMode/set_uplotOutputMode.c, src/libged/setview/setview.c, src/libged/shaded_mode/shaded_mode.c, src/libged/shader/shader.c, src/libged/shells/shells.c, src/libged/showmats/showmats.c, src/libged/shrinkwrap/shrinkwrap.c, src/libged/simulate/ged_command.cpp, src/libged/simulate/rt_collision_algorithm.cpp, src/libged/simulate/rt_collision_algorithm.hpp` | `set_uplotOutputMode/set_uplotOutputMode.c:48-75; setview/setview.c:48-85; shaded_mode/shaded_mode.c:50-80; shader/shader.c:42-75; shells/shells.c:48-135; showmats/showmats.c:50-75, 80-180; shrinkwrap/shrinkwrap.c:30-40; simulate/ged_command.cpp:40-48, 180-192, 285-325; simulate/rt_collision_algorithm.cpp:98-120, 150-205` | Resource Leaks, Memory Leaks, Double-Free, Division by Zero, Mutating Input, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 24 commands (set_uplotOutputMode, setview, shaded_mode, shader, shells, showmats, shrinkwrap, simulate): in set_uplotOutputMode.c, added null and empty string guards on argv[1] before inspecting characters, and appended missing newlines to usage, binary, and text output strings; in setview.c, added null checks on argv[1] when argc == 2 and argv[1..3] when argc == 4, replaced raw sscanf with bu_sscanf, safely printed bad coordinate values, and added missing newlines to usage strings; in shaded_mode.c, guarded argv[1] against null, replaced raw sscanf with bu_sscanf, and added missing newlines to mode output and usage strings; in shader.c, added null check on argv[1], verified argv[2..argc-1] are non-null before bu_vls_from_argv, replaced bu_vls_addr with bu_vls_cstr, and added missing newlines to usage, current shader output, and read-only error message; in shells.c, fixed major resource and memory leaks by deferring wdb_dbopen until after argument validation, verifying wdbp allocation, calling wdb_close on all error and success exits, calling rt_db_free_internal on old_intern across all exits, freeing shell_name on all exits, and eliminating double-free of m_tmp after rt_db_put_internal failure; in showmats.c, eliminated mutation of input path and improved safety by operating on a duplicated string buffer via bu_strdup and freeing path_copy on all exit paths, guarded smdp, smdp->smd_child, and comb_leaf->tr_l.tl_name against null in Do_showmats, guarded argv[1] against null in ged_showmats_core, added trailing newline to 16-element matrix output in -a mode, and added missing newlines to usage strings; in shrinkwrap.c, added GED_CHECK_DATABASE_OPEN guard and safely handled potential null argv[0]; in simulate/ged_command.cpp, added missing newline to non-Bullet error message, validated argc >= 3 and ensured argv[1] and argv[2] are non-null before parsing options, wrapped anim_state in std::unique_ptr to prevent persistent memory and resource leaks if exceptions are thrown during simulation steps, and added missing newline to exception result output; in simulate/rt_collision_algorithm.cpp, guarded against null rays in free_xrays, prevented division by zero by validating grid_radius > 0 and radius > 0 in generate_ray_grid and get_rays, returning null safely instead of calling bu_bomb, and added null checks on btRigidBody::upcast, getMotionState, and rays.ptr in calculate_contact_points to prevent null pointer dereferences. |
| `SEC-0267` | `src/libged/simulate/rt_collision_shape.cpp, src/libged/simulate/rt_collision_shape.hpp, src/libged/simulate/rt_debug_draw.cpp, src/libged/simulate/rt_debug_draw.hpp, src/libged/simulate/rt_instance.cpp, src/libged/simulate/rt_instance.hpp, src/libged/simulate/rt_motion_state.cpp, src/libged/simulate/rt_motion_state.hpp, src/libged/simulate/rt_roi_collision_shape.cpp, src/libged/simulate/rt_roi_collision_shape.hpp` | `simulate/rt_collision_shape.cpp:106-112, 130-149; simulate/rt_debug_draw.cpp:78-95, 116-125, 130-145, 156-175, 172-201; simulate/rt_instance.cpp:60-105, 117-150; simulate/rt_motion_state.cpp:45-50, 62-67, 104-140; simulate/rt_roi_collision_shape.cpp:123-185; simulate/rt_roi_collision_shape.hpp:116-121` | Resource Leaks, Memory Corruption, Unhandled Exceptions/Process Termination (bu_bomb), and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 25 commands (src/libged/simulate/*): in rt_collision_shape.cpp, eliminated process-aborting bu_bomb calls by zeroing inertia when mass <= 0.0 and clamping negative scaling and margin values to 0.0; in rt_debug_draw.cpp, fixed major resource leaks of in-memory database handles by ensuring wdb_close is called on all paths in drawLine, drawAabb, and drawContactPoint, clamped color components to [0.0, 1.0] instead of terminating with bu_bomb, and added null check on message in reportErrorWarning; in rt_instance.cpp, guarded against null application and partition pointers in multioverlap_handler, falling back safely to rt_default_multioverlap on unexpected region table lengths or region names instead of calling bu_bomb, and threw InvalidSimulationError instead of aborting the process with bu_bomb when rt_i_create or rt_gettrees fails in get_overlaps; in rt_motion_state.cpp, guarded matrix and result destination pointers in bt_transform_to_matrix and path_to_matrix, and threw InvalidSimulationError instead of calling bu_bomb on rt_db_get_internal, db_find_named_leaf, or rt_db_put_internal failure; in rt_roi_collision_shape.cpp, guarded against null m_box_shape before dereferencing in getAabb, calculateLocalInertia, getLocalScaling, getMargin, setLocalScaling, and setMargin, clamped negative scaling and margin values, and zeroed inertia when mass <= 0.0; and in rt_roi_collision_shape.hpp, declared copy constructor and assignment operator private to enforce the Rule of Three and prevent double-free corruption of m_box_shape. |
| `SEC-0268` | `src/libged/simulate/sim_animate.cpp, src/libged/simulate/sim_animate.hpp, src/libged/simulate/simulation.cpp, src/libged/simulate/simulation.hpp, src/libged/simulate/tests/simulate_test.cpp, src/libged/simulate/tests/verify_simulation.c, src/libged/simulate/utility.cpp, src/libged/slew/slew.c, src/libged/solid_report/solid_report.c` | `simulate/sim_animate.cpp:95-135, 218-228, 300-360, 575-605; simulate/sim_animate.hpp:105-112; simulate/simulation.cpp:135-145, 185-190, 265-275, 350-395, 465-495, 595-635, 825-835; simulate/simulation.hpp:88-95; simulate/tests/simulate_test.cpp:40-48, 336-342; simulate/tests/verify_simulation.c:37-65, 75-80, 168-175, 225-235, 255-260; simulate/utility.cpp:45-90; slew/slew.c:48-98; solid_report/solid_report.c:32-37` | Memory Leaks, Inverted Return Value Logic Bug, Process Termination in Library Function (bu_bomb), Missing Validation, Division by Zero, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 26 commands (simulate, slew, solid_report): in simulate/sim_animate.cpp and sim_animate.hpp, added null checks in az_el_to_offset, look_at_quaternion, and ae_to_quaternion, guarded m_gedp and dbip in getSceneCenter and renderFrame, cleared jpeg_data on error and bounded maximum buffer read size in readPixToJpeg, validated width, height, and fps in encodeVideo, enforced the Rule of Three on SimAnimState with private copy constructor and assignment operator, and removed unused method declaration writeMjpegAvi; in simulate/simulation.cpp and simulation.hpp, eliminated multiple process-terminating bu_bomb calls across get_aabb, get_simulation_parameters, Region::get_region, and Region::get_regions by throwing InvalidSimulationError with contextual path information, replaced bu_bomb in saveState with warning logging, eliminated persistent memory leak of bullet collision create functions in Simulation::Simulation by tracking allocated CreateFunc pointers in m_create_funcs and deleting them in ~Simulation(), and enforced the Rule of Three on Simulation and Region; in simulate/tests/simulate_test.cpp, safely returned false on null matrix in matrix_equal instead of calling bu_bomb, and guarded argv and argv[0] in main; in simulate/tests/verify_simulation.c, added null checks in parse_bbox, get_bbox, check_presim, check_postsim, and main, replaced raw sscanf with bu_sscanf, replaced bu_vls_addr with bu_vls_cstr, and guarded against division by zero on truck_height when calculating penetration percentage; in simulate/utility.cpp, threw InvalidSimulationError in current_dir on empty paths, fixed critical inverted logic bug in set_region where bu_avs_remove returning 1 on successful attribute removal was erroneously treated as an error causing bu_bomb to abort the process, and replaced remaining bu_bomb calls with warning logging to ensure clean teardown in ~TemporaryRegionHandle; in slew/slew.c, added null checks on argv[1..3], replaced raw sscanf with bu_sscanf, and added missing newlines to all usage strings; and in solid_report/solid_report.c, guarded gedp against null. |
| `SEC-0269` | `src/libged/solids_on_ray/solids_on_ray.c, src/libged/sphgroup/sphgroup.c, src/libged/stat/stat.cpp, src/libged/summary/summary.c, src/libged/sync/sync.c, src/libged/tab_complete.cpp, src/libged/tables/tables.c, src/libged/tests/bot/bot_dump.cpp, src/libged/tests/bot/bot_split.cpp, src/libged/tests/check_mann_docs.cpp` | `solids_on_ray/solids_on_ray.c:60-75, 120-130, 240-275; sphgroup/sphgroup.c:50-58, 85-115; stat/stat.cpp:115-125, 200-245, 330-365, 430-470; summary/summary.c:50-80, 150-185, 230-245; sync/sync.c:45-55; tab_complete.cpp:45-75, 110-180; tables/tables.c:165-185, 255-275, 410-440, 520-560; tests/bot/bot_dump.cpp:130-140, 405-415; tests/bot/bot_split.cpp:85-105, 130-145, 185-195, 225-235; tests/check_mann_docs.cpp:105-110, 635-645, 755-765, 820-835, 965-975, 1005-1015` | Memory Leaks, Resource Leaks, Option Parsing Collision, Uninitialized Memory Operations, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 27 commands and test drivers: in solids_on_ray/solids_on_ray.c, eliminated persistent memory leaks of solids_on_ray_cmd_vec strings (allocated by ged_who_argv) and snames path strings (allocated by db_path_to_string), added null guards on ap and PartHeadp in rpt_hits, verified pp->pt_inseg and pp->pt_inseg->seg_stp before retrieving path, guarded ap in rpt_miss, added null checks on gedp, dbip, ray_orig, and ray_dir in skewer_solids, replaced raw sscanf with bu_sscanf, added null checks on argv[1] and argv[2], and added missing newlines to usage and error strings; in sphgroup/sphgroup.c, fixed persistent memory leak of sph_intern by calling rt_db_free_internal on non-sphere error, _ged_combadd error, and normal exit, added null/empty string validation on argv[1] and argv[2], added missing newline to usage string, and deleted commented-out dead code; in stat/stat.cpp, fixed option parsing bug where the -q quiet flag was clobbered by -r raw due to duplicate array index d[3], fixed memory leaks in cmp_dps by using std::string to eliminate bu_vls leaks and freeing avs and string allocations on all exit paths, fixed memory leaks in stat_output by scoping bu_vls and freeing avs, added null/bounds checks in dpath_sort and _stat_find_first_unescaped, and added missing newlines to bu_log; in summary/summary.c, fixed major memory leak in solid_counter by calling rt_db_free_internal, added null checks in comb_counter and solid_counter, validated bu_opt_parse return value, guarded argv[0] against null, and added error output on missing objects; in sync/sync.c, added GED_CHECK_ARGC_GT_0 to prevent null dereference of argv[0] and appended missing newline; in tab_complete.cpp, added null guards in alphanum_cmp, path_match, obj_match, and ged_cmd_completions; in tables/tables.c, fixed memory leak of tree_objs bu_ptbl, verified read count before matching identt in tables_sol_number, initialized static descriptors to -1, guarded sol_loaded before invoking ft_describe or freeing sol_intern in tables_new, guarded getpwuid against null in tables_header, guarded ctime return in ged_tables_core, and added missing newlines; in tests/bot/bot_dump.cpp, guarded argv against null, corrected arbs_stl output comparison path for arb4_bot_02.stl, and added missing newlines; in tests/bot/bot_split.cpp, guarded argv in main, added null checks in check_output_group, check_output_bot, and check_decimated_bot, and ensured rt_db_free_internal is called on early return; and in tests/check_mann_docs.cpp, validated argv in main, added null checks before array indexing, and verified file stream is_open status before reading or writing. |
| `SEC-0270` | `src/libged/tests/check_prim_cmds.cpp, src/libged/tests/create/create_parity.c, src/libged/tests/create/create_parity.h, src/libged/tests/create/in_cases.c, src/libged/tests/create/make_cases.c, src/libged/tests/draw/aet.cpp, src/libged/tests/draw/annotate.cpp, src/libged/tests/draw/basic.cpp, src/libged/tests/draw/draw_color.cpp, src/libged/tests/draw/faceplate.cpp` | `tests/check_prim_cmds.cpp:52-64; tests/create/create_parity.c:60-75, 84-100, 155-165, 205-230; tests/create/in_cases.c:45-55; tests/create/make_cases.c:45-60, 115-125, 140-150; tests/draw/aet.cpp:200-220, 245-285, 335-375, 405-415; tests/draw/annotate.cpp:60-65, 260-275, 390-410; tests/draw/basic.cpp:45-170, 200-235, 770-800; tests/draw/draw_color.cpp:45-55, 105-140, 150-165; tests/draw/faceplate.cpp:50-70, 335-350` | Logic Bugs, Resource and Handle Leaks, Missing Parameter and Option Validation, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 28 test suites and drivers: in tests/check_prim_cmds.cpp, guarded argc and argv in main and checked empty ftp->ft_label string; in tests/create/create_parity.c, added null checks in case_covered and check_coverage, fixed handle leak in open_test_db by closing wdbp with wdb_close instead of leaking wdbp via raw db_close, guarded gedp, gedp->dbip, name, and out in snapshot, guarded argc and argv in main, and ensured temporary test database files are deleted on all exit paths; in tests/create/create_parity.h, verified interface header clean; in tests/create/in_cases.c and make_cases.c, added null guards on gedp, name, and label in build_obj and make_obj, and added null checks in trans_exempt and extra_checks; in tests/draw/aet.cpp, guarded gedp, dbi_state, view counts, and display manager pointers in dm_refresh and img_cmp, freed tname on error exits, guarded argc and argv in main, validated option parsing results, freed fname, deleted temporary database moss_aet_tmp.g, and cleared local cache directory lcache on exit; in tests/draw/annotate.cpp, fixed handle leak in verify_geometry_update by ensuring wdb_close is called on wdbp, guarded gedp and gedp->dbip in verify_legacy_annotation_coloring, and guarded argc and argv in main; in tests/draw/basic.cpp and faceplate.cpp, fixed critical logic bug where if (uac == -1 || need_help) had an empty statement body which inverted command-line argument validation logic, guarded ac and av in main, guarded gedp across poly_* helper functions, freed fname, deleted temporary moss_tmp.g, and cleared lcache on exit; and in tests/draw/draw_color.cpp, guarded argv in main, guarded fixture path, and added null checks on gedp, gedp internals, display structures, and directory pointers in check_drawing. |
| `SEC-0271` | `src/libged/tests/draw/lod.cpp, src/libged/tests/draw/quad.cpp, src/libged/tests/draw/select.cpp, src/libged/tests/draw/util.cpp, src/libged/tests/edit/test_edit.cpp, src/libged/tests/ged_test_rm.c, src/libged/tests/ged_test_tire.cpp, src/libged/tests/plugins.cpp, src/libged/tests/search_tests.cpp, src/libged/tests/test_bb_tight.c` | `tests/draw/lod.cpp:180-260, 420-475; tests/draw/quad.cpp:130-170, 200-240, 275-310, 1100-1160; tests/draw/select.cpp:185-265, 750-805; tests/draw/util.cpp:50-95, 230-295; tests/edit/test_edit.cpp:380-410, 890-915, 3470-3530; tests/ged_test_rm.c:60-95, 410-440, 960-1010; tests/ged_test_tire.cpp:50-100, 260-280, 520-560, 680-715; tests/plugins.cpp:50-65, 380-420, 460-475; tests/search_tests.cpp:40-65, 170-215; tests/test_bb_tight.c:45-75, 120-140, 185-225` | Logic Bugs, Temporary File and Resource Leaks, Double-Free, Missing Option and Parameter Validation, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 29 test suites and drivers: in tests/draw/lod.cpp and select.cpp, corrected option parsing check from ac != 2 to uac != 2 so optional command flags such as -c are correctly recognized without causing premature test failure, added null guards on ac, av, gedp, gedp->dbip, v, and v->dmp, freed fname and cleaned up temporary test databases on all exit paths; in tests/draw/quad.cpp, added null checks across drawing and refresh helpers, guarded image comparison against null control and test images, freed cname, corrected option parsing bounds, and ensured temporary database cleanup on exit; in tests/draw/util.cpp, added null guards on dp, u_data, dbi_state, ged_gvp, and dmp, and plugged memory leaks in img_cmp; in tests/edit/test_edit.cpp, replaced invalid jump-over-initialization error path with direct cleanup in create_p0_fixture, replaced manual export and double-free in create_p6_fixture with mk_brep, and ensured all 10 temporary database files (p0_path through p6_path) are unlinked via bu_file_delete across all error and success exits; in tests/ged_test_rm.c, replaced leaking db_close calls with wdb_close, added close_test_db to delete temporary test database files upon completion across all 26 test functions, fixed unchecked db_lookup dereferences, and added null guards in CHECK_PRESENT, CHECK_ABSENT, member_count, comb_has_op, and main; in tests/ged_test_tire.cpp, fixed database handle leaks by properly pairing wdb_fopen with wdb_close, added close_test_db to clean up temporary test databases, unlinked temporary text files and pattern files via bu_file_delete, eliminated premature wdb_close in run_partial_cleanup_case on an unowned handle, and added null checks across inspection helpers; in tests/plugins.cpp, fixed off-by-one / null pointer dereference in error message accessing av[1] instead of av[0], guarded ac and av in main, and added null checks on imsgs and cmds; in tests/search_tests.cpp, added null guards for gedp, gedp->dbip, path_dp, and search_count_helper, and validated argc/argv; and in tests/test_bb_tight.c, fixed wdbp handle leaks in open_test_db, added close_test_db to remove temporary test databases, and added null guards in parse_bb_volume, run_bb_volume, and main. |
| `SEC-0272` | `src/libged/tests/test_bo.c, src/libged/tests/test_db.c, src/libged/tests/test_gqa.c, src/libged/tests/test_list.c, src/libged/tests/test_material.c, src/libged/tests/test_search.c, src/libged/tests/test_select.cpp, src/libged/tests/test_tops.c, src/libged/tests/test_view_dir.c, src/libged/tire/tire.cpp` | `tests/test_bo.c:79-88, 115; tests/test_gqa.c:65-70; tests/test_list.c:43-45, 63-73; tests/test_material.c:127-132, 148-152; tests/test_search.c:63-71, 104-109; tests/test_select.cpp:54-60, 185-195; tests/test_tops.c:48-53` | Resource Leaks, Null Pointer Dereferences, Division by Zero, and Array Overflow | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 30 test programs and tire command: in test_bo.c, replaced db_close(wdbp->dbip) with wdb_close(wdbp) to fix wdb handle leak, and added null guard on binunif internal pointer before accessing type, count, and data fields; in test_gqa.c, added null check on ged_open return value; in test_list.c, validated atoi result for non-positive values and guarded elapsed_sec > 0 before division to prevent division by zero in ops-per-second calculation; in test_material.c, added null check on ged_open return value and added ged_close before exit to prevent resource leak; in test_search.c, added null check on ged_open return value and added bounds check on variadic plan arguments to prevent overflow of fixed-size cmd[6] array; in test_select.cpp, added null check on ged_open return value, freed DbiState allocation, and cleaned up temporary cache directory with bu_dirclear on exit; in test_tops.c, added null check on ged_open return value; test_db.c reviewed clean (ged_open already checked, bu_vls_cstr never returns NULL); test_view_dir.c reviewed clean (proper goto/done cleanup pattern); tire/tire.cpp reviewed clean (GED_CHECK_DATABASE_OPEN ensures valid state, extensive validation in build_validated_request). |
| `SEC-0273` | `src/libged/tire/tire_conic.cpp, src/libged/tire/tire_csg.cpp, src/libged/tire/tire_private.h, src/libged/tire/tire_surface.cpp, src/libged/tire/tire_tread.cpp, src/libged/tire/tire_tread_def.cpp, src/libged/tire/tire_tread_profile.cpp, src/libged/tire/tire_wheel.cpp, src/libged/title/title.c, src/libged/tol/tol.c` | `tire/tire_surface.cpp:88-94; tire/tire_tread.cpp:49-52; title/title.c:57; tol/tol.c:246` | Division by Zero, Integer Underflow, and Convention Violations | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 31 (tire, title, tol): in tire/tire_surface.cpp, added ZERO() division-by-zero guard before dividing by spec.dyside1 and ztire_with_offset in make_tire to prevent floating-point divide-by-zero on degenerate tire specifications; in tire/tire_tread.cpp, added empty vector guard in emit_tread_extrusions to prevent size_t underflow when verts.size()-1 wraps to SIZE_MAX on an empty vector; in title/title.c, replaced bu_vls_addr with bu_vls_cstr per BRL-CAD conventions; in tol/tol.c, replaced raw sscanf with bu_sscanf for locale-independent parsing per BRL-CAD conventions. Reviewed clean: tire_conic.cpp (robust std::optional error handling, no raw allocations), tire_csg.cpp (RAII CsgTransaction pattern with deleted copy ctor, proper rollback), tire_private.h (header-only definitions), tire_tread_def.cpp (thorough JSON validation with try/catch), tire_tread_profile.cpp (all solver calls checked for nullopt), tire_wheel.cpp (all write operations checked). |
| `SEC-0274` | `src/libged/tops/tops.c, src/libged/tra/tra.c, src/libged/trace.c, src/libged/track/track.c, src/libged/tree/tree.c, src/libged/typein/typein.c, src/libged/unhide/unhide.c, src/libged/units/units.c, src/libged/v2m_point/v2m_point.c, src/libged/vdraw/vdraw.c` | `tree/tree.c:145-170,205-220; typein/typein.c:1580-1600,2780-2800; units/units.c:82; v2m_point/v2m_point.c:56-68; vdraw/vdraw.c:170-230` | Memory Leaks, Resource Leaks, Unsafe API, and Convention Violations | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 32 (tops through vdraw): in tree/tree.c, fixed memory leak of attribute value set by adding bu_avs_free, fixed resource leak of rt_db_internal on v4gift flatten failure, replaced bu_vls_addr with bu_vls_cstr; in typein/typein.c, fixed resource leaks in extrude_in and revolve_in when imported object is not ID_SKETCH by adding rt_db_free_internal, replaced bu_vls_addr with bu_vls_cstr in revolve_in and pnts_in (4 instances); in units/units.c, replaced bu_vls_addr with bu_vls_cstr; in v2m_point/v2m_point.c, replaced raw sscanf with bu_sscanf (3 instances), fixed copy-paste error in error messages; in vdraw/vdraw.c, replaced raw sscanf with bu_sscanf (7 instances). Reviewed clean: tops.c (proper GED_CHECK guards), tra.c (validated argument handling), trace.c (correct tree traversal), track.c (GED_CHECK guards, proper cleanup), unhide.c (minimal unhide command). |
| `SEC-0275` | `src/libged/vers.c, src/libged/view/aet.c, src/libged/view/align.c, src/libged/view/autoview.c, src/libged/view/autoview2.cpp, src/libged/view/axes.c, src/libged/view/center.cpp, src/libged/view/data_lines.c, src/libged/view/eye.c, src/libged/view/faceplate/faceplate.c, src/libged/view/faceplate/faceplate.h, src/libged/view/faceplate/faceplate_axes.c, src/libged/view/faceplate/faceplate_grid.c, src/libged/view/faceplate/interactive_rect.c, src/libged/view/ged_view.h` | `view/aet.c:86-97; view/align.c:80-90; view/center.cpp:156-166; view/eye.c:76-86; view/faceplate/faceplate.c:121,226,320,380` | Unsafe API and Memory Leaks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 33 (view module): in view/aet.c, replaced raw sscanf with bu_sscanf (3 sites); in view/align.c, replaced raw sscanf with bu_sscanf (3 sites); in view/center.cpp, replaced raw sscanf with bu_sscanf (3 sites); in view/eye.c, replaced raw sscanf with bu_sscanf (3 sites); in view/faceplate/faceplate.c, added bu_vls_free on stack VLS after bu_opt_color and bu_opt_int calls to prevent memory leaks (4 sites). Reviewed clean: vers.c (trivial version function), autoview.c (proper bu_calloc/bu_free), autoview2.cpp (bu_opt_parse with cleanup), axes.c (bu_opt_fastf_t/bu_opt_int/bu_opt_color with proper cleanup), data_lines.c (already uses bu_sscanf), faceplate.h (declarations only), faceplate_axes.c (design-level struct mismatch, not a simple fix), faceplate_grid.c (similar struct mismatch), interactive_rect.c (similar struct mismatch), ged_view.h (declarations only). |
| `SEC-0276` | `src/libged/view/gobjs.cpp, src/libged/view/knob.c, src/libged/view/labels.c, src/libged/view/lines.c, src/libged/view/lod.cpp, src/libged/view/lookat.c, src/libged/view/objs.cpp, src/libged/view/polygons.c, src/libged/view/quat.c, src/libged/view/qvrot.c, src/libged/view/saveview.c, src/libged/view/size.c, src/libged/view/snap.c, src/libged/view/view.c, src/libged/view/viewdir.c, src/libged/view/ypr.c` | `view/gobjs.cpp:48-57,113-130,150-164; view/labels.c:127-148; view/lines.c:84-90; view/lod.cpp:178-190,340-345; view/lookat.c:70-100; view/objs.cpp:168-183,219-244,561-625; view/polygons.c:106,487,531,847-855; view/quat.c:62-65; view/qvrot.c:89-105; view/saveview.c:97,127,173-176; view/size.c:61-65; view/snap.c:100-135,153,194; view/view.c:831,840,850,874,948; view/viewdir.c:58; view/ypr.c:73-81` | Memory Leaks, Logic Bugs, Out-of-bounds Array Access, Resource Leaks, Unsafe API, and Missing Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 34 (view module: gobjs through ypr): in view/gobjs.cpp, fixed memory leaks of full path and internal objects in create command and scene free callback, and checked database open; in view/labels.c and view/lines.c, guarded against null scene object creation and used bu_vls_sprintf to prevent vls buffer leaks; in view/lod.cpp, validated database open before cache commands, checked wdb handle, fixed copy-paste error in scale message, and removed dead vls variables; in view/lookat.c, replaced raw sscanf with bu_sscanf (3 sites), guarded against zero vector division when lookat point is at eye position, and added missing newlines; in view/objs.cpp, fixed memory leak of directory pointers in _view_cmd_old_obj across all return paths, guarded against null ged internals, removed redundant recurse check, and fixed argument reporting in arrow subcommand; in view/polygons.c, fixed out-of-bounds argv index in overlap subcommand (argv[1] -> argv[0]), fixed error message reporting in bool subcommand (argv[0] -> argv[1]), checked database open before overlap tolerance check, and formatted s_name with bu_vls_sprintf; in view/quat.c, replaced raw sscanf with bu_sscanf (4 sites) and added missing newlines; in view/qvrot.c, replaced raw sscanf with bu_sscanf (4 sites), corrected argument reporting for bad angle from argv[1] to argv[4], and added missing newlines; in view/saveview.c, replaced bu_vls_addr with bu_vls_cstr, guarded display list traversal against null pointers, and added missing newlines; in view/size.c, replaced raw sscanf with bu_sscanf and added missing newlines; in view/snap.c, fixed critical logic bug where vp was set from uninitialized p instead of parsed 2D coordinates p2d, freed temporary msg vls on all early returns to eliminate memory leak, and added missing newlines; in view/view.c, added missing newlines to usage and error messages; in view/viewdir.c, added missing newline to usage message; in view/ypr.c, replaced raw sscanf with bu_sscanf (3 sites) and added missing newlines. Reviewed clean: knob.c. |
| `SEC-0277` | `src/libged/view2grid_lu/view2grid_lu.c, src/libged/view2model/view2model.c, src/libged/view2model_lu/view2model_lu.c, src/libged/view2model_vec/view2model_vec.c, src/libged/voxelize/voxelize.c, src/libged/vrot/vrot.c, src/libged/vutil.c, src/libged/wcodes/wcodes.c, src/libged/wdb_importFg4Section.c, src/libged/whatid/whatid.c, src/libged/which/which.cpp, src/libged/which_shader/which_shader.c, src/libged/who/who.c, src/libged/who/who2.cpp, src/libged/who/who_solids.cpp, src/libged/wireframe_eval.c, src/libged/wmater/wmater.c, src/libged/xpush/xpush.c, src/libged/zap/zap.c, src/libged/zap/zap2.cpp, src/libged/zoom/zoom.c` | `view2grid_lu.c:50-70; view2model.c:70; view2model_lu.c:50-75; view2model_vec.c:50-65; voxelize.c:59,102-225; vrot.c:85-115; vutil.c:40-90,175-185; wcodes.c:70-100; wdb_importFg4Section.c:40-300; whatid.c:40-85; which.cpp:115-180; which_shader.c:60-95; who.c:40-75; who2.cpp:40-75; who_solids.cpp:40-80; wireframe_eval.c:275,1485-1575,1805-1875; wmater.c:40-90; xpush.c:135-200,255-395,440-570; zap.c:40-125; zap2.cpp:50-155; zoom.c:25-65` | Memory Leaks, Resource Leaks, Memory Corruption, Unsafe API, Double Free, Division by Zero, and Missing Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libged Batch 35 (completing src/libged subsystem, 21 files): in view2grid_lu.c and view2model_lu.c, moved GED_CHECK_DATABASE_OPEN before b2lval evaluation, replaced raw sscanf with bu_sscanf, guarded against division by zero with ZERO macro in view2model_lu.c, and added missing newlines; in view2model.c, added missing newline to usage; in view2model_vec.c, replaced sscanf with bu_sscanf, checked bn_mat_inverse return, and added newline; in voxelize.c, fixed persistent rt_wdb resource leak with wdb_close, fixed rt_i_destroy leak on error, fixed argument reporting in error message, replaced sscanf with bu_sscanf, added bounds checks on voxel size and level of detail, and fixed format string; in vrot.c, added missing newlines and returned GED_HELP on argc == 1; in vutil.c, fixed memory corruption in ged_dl_hash by passing dp->d_namep string content instead of pointer address, added null guards, and checked bn_mat_inverse return values; in wcodes.c, fixed memory leak of path array on error exits, replaced direct ft_ifree with rt_db_free_internal, guarded null names, and added newlines; in wdb_importFg4Section.c, fixed crash on command reuse by resetting static state variables at start of command, replaced free with bu_free, replaced bu_bomb with error logging, validated line buffer lengths, and added zero face count guard; in whatid.c, verified ID_COMBINATION and added newlines; in which.cpp, replaced sscanf with bu_sscanf, guarded against integer subtraction overflow, capped range to prevent memory exhaustion, freed comb_objs on error, and verified ID_COMBINATION; in which_shader.c, fixed major memory leak of combination records by calling rt_db_free_internal on every iteration, replaced bu_vls_addr with bu_vls_cstr, and added newlines; in who.c, moved GED_CHECK_ARGC_GT_0 to top, replaced bu_vls_addr with bu_vls_cstr, guarded gdlp->dl_dp, and added newlines; in who2.cpp, moved GED_CHECK_ARGC_GT_0 to top, guarded dbis and bvs against null, and added newlines; in who_solids.cpp, checked sp->s_os before accessing s_dmode, moved GED_CHECK_ARGC_GT_0 to top, and guarded gedp internals; in wireframe_eval.c, guarded scene and scene data against null, set op for OP_NOP, fixed memory leak of application struct and ppath in draw_m3, and added null checks in fix_halfs and free_etree; in wmater.c, moved GED_CHECK_ARGC_GT_0 to top, replaced bu_vls_addr with bu_vls_cstr, verified ID_COMBINATION, and added newlines; in xpush.c, eliminated persistent rt_wdb handle leaks in Copy_solid and Copy_comb by using stack tolerance structs, fixed double-free on rt_db_put_internal failure, fixed combination internal memory leak when found is null or comb tree is null, guarded log10 domain, and fixed typo; in zap.c, guarded gedp internals, checked path length before accessing first solid, moved GED_CHECK_ARGC_GT_0 to top, and added newline; in zap2.cpp, freed cvls on help and error returns, guarded views, v, bvs, and v->gv_s against null, and moved GED_CHECK_ARGC_GT_0 to top; in zoom.c, replaced sscanf with bu_sscanf, guarded gedp->ged_gvp and division by zero, moved GED_CHECK_ARGC_GT_0 to top, and added newlines. |
| `SEC-0279` | `src/libwdb/mater.c, src/libwdb/material.c, src/libwdb/nmg.c, src/libwdb/nurb.c, src/libwdb/pipe.c, src/libwdb/pnts.c, src/libwdb/reg.c, src/libwdb/script.c, src/libwdb/sketch.c, src/libwdb/submodel.c, src/libwdb/units.c, src/libwdb/vol.c, src/libwdb/wdb.c` | `mater.c:40-60; material.c:45-80; nmg.c:45-75; nurb.c:45-65; pipe.c:40-120; pnts.c:50-130,230-260; reg.c:50-80,180-210,310-450; script.c:40-55; sketch.c:40-55; submodel.c:40-55; units.c:40-65; vol.c:40-75; wdb.c:55-885` | Double-Free / Memory Corruption, Memory Leaks, Process Abort, Integer Overflow, and Missing Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libwdb Batch 37 (procedural primitives, mater through wdb, 13 files, completing src/libwdb): in mater.c, added null checks on ofp and ofp->dbip, and returned -1 on unsupported v4 database rather than asserting mk_version == 4; in material.c, added null checks on wdbp and db_name, guarded against null name, parent, and source strings before bu_vls_strcpy, and validated attribute keys and values before bu_avs_merge to prevent bu_bomb aborts; in nmg.c, added null checks on filep, name, and m before NMG_CK_MODEL, and verified botp != NULL after nmg_bot conversion before export; in nurb.c, added null checks on wdbp, name, and surfs, and verified ni->nsrf > 0 (freeing ni on zero surfaces) before export; in pipe.c, added null checks on fp, name, vertex, and height, verified positive radii with ZERO macro, validated headp in mk_pipe, mk_pipe_free, and mk_pipe_init, and validated od > 0, id >= 0, id < od, and bendradius >= 0 in mk_add_pipe_pnt; in pnts.c, added null checks on pnts and pnts->point in pnts_init_head_pnt and pnts_add, checked scale >= 0.0, and validated point != NULL before adding points in mk_pnts; in reg.c, added null checks on comb and member_hd in mk_tree_pure and mk_tree_gift, guarded headp in mk_freemembers, added null checks on wdbp, combname, and headp in mk_comb, and validated membname in mk_comb1 and mk_region1; in script.c, eliminated Cat 1 memory corruption and caller memory free by allocating and duplicating scr into a newly allocated rt_script_internal before passing to wdb_export; in sketch.c, added null checks on fp, name, and skt, and checked rt_copy_sketch return before export; in submodel.c, added null checks on fp, name, and treetop; in units.c, added null check on str and ZERO() macro guards against zero conversion factor in mk_conversion and mk_set_conversion; in vol.c, added null checks on fp, name, file, cellsize, and mat, and verified positive dimensions and cell sizes; in wdb.c, eliminated memory leaks in mk_hyp by validating parameters before internal structure allocation, replaced bu_bomb in mk_metaball with internal structure cleanup and error return, guarded against integer overflow in mk_binunif allocation and validated data pointer before memcpy, and added null pointer and geometric parameter validation with ZERO macro across mk_half, mk_grip, mk_rpp, mk_wedge, mk_arb4-8, mk_sph, mk_ell, mk_tor, mk_rcc, mk_tgc, mk_cone, mk_trc_h, mk_trc_top, mk_rpc, mk_rhc, mk_epa, mk_ehy, mk_hrt, and mk_eto. |
| `SEC-0280` | `src/mged/adc.c, src/mged/arbs.c, src/mged/attach.c, src/mged/axes.c, src/mged/buttons.c, src/mged/cad_boundp.c, src/mged/cad_parea.c, src/mged/chgmodel.c, src/mged/chgtree.c` | `adc.c:75-105,290-310,430,455-505,585-695; arbs.c:35-50,70,85-135,155-205,225-290; attach.c:175-180,265-285,315-325,425-480,565-585,620-640,755-765; axes.c:110-145,155-180,185-205; buttons.c:180-215,275,405-460,795-870,955-1045; cad_boundp.c:45-50,180,290,445,720-755; cad_parea.c:110-135,155-170; chgmodel.c:75-100,205,245-290,325,395,435-445,475; chgtree.c:70,105,150,175,190,245,275-310` | Buffer Overflow, Double-Free, Logic / Angle Calculation Bug, Memory Leaks, Array Out-of-Bounds, Division by Zero, and Missing Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 38 (adc through chgtree, 9 files): in adc.c, fixed stack buffer overflow by capping user_pt coordinate parsing to the 3-element buffer capacity, replaced atof with bu_sscanf, guarded against division by zero in grid_scale across dst, dh, dv, and hv with ZERO macro, fixed incorrect input point parameter in MAT4X3PNT (passing pos_view instead of pos_model), added null pointer guards in adc_set_dirty_flag, adc_set_scroll, adcursor, and f_adc, and replaced bu_vls_addr with bu_vls_cstr; in arbs.c, eliminated double-free on rt_db_put_internal failure and fixed memory leak of internal struct on db_diradd failure and switch default, freed temporary vls on error return, eliminated unused file-scope dead array p_arb3pt and global mutable promp pointer, replaced atof with bu_sscanf, and replaced bu_vls_addr with bu_vls_cstr; in attach.c, made release() name parameter const char *, added null check on s and wp_name in mged_attach, removed redundant null check, and replaced bu_vls_addr with bu_vls_cstr; in axes.c, guarded against aspect division by zero with ZERO macro in draw_v_axes, and added null pointer guards in draw_e_axes, draw_m_axes, and draw_v_axes; in buttons.c, added bounds-checked get_state_str() helper to prevent out-of-bounds array reads on state_str, added null pointer checks in f_press, bv_vrestore, bv_vsave, and bv_adcursor, and replaced bu_vls_addr with bu_vls_cstr; in cad_boundp.c, resolved angle calculation bug where atan2 radian output was multiplied by DEG2RAD instead of RAD2DEG (corrupting bounding polygon angle computations), moved stray debug newline output inside #ifdef DEBUG, migrated memory management to bu_malloc and bu_free, included bu/malloc.h, replaced sscanf with bu_sscanf, and added negative tolerance validation; in cad_parea.c, replaced sscanf with bu_sscanf, and routed error logging from printf to stderr to prevent corrupting redirected stdout files; in chgmodel.c, guarded divisions in f_sc_obj against zero scale denominator and scale accumulators with ZERO macro, validated scale input with bu_sscanf, verified direction vector magnitude squared in f_qorot and corrected inverted error message, replaced sprintf with snprintf and guarded view_state in f_make, and replaced bu_vls_addr with bu_vls_cstr; in chgtree.c, fixed memory leak of internal database struct on db_diradd failure in f_copy_inv, added null guards in find_solid_with_path and find_solid_below_path, ensured lhs, rhs, and both paths are properly freed on all error exit paths in cmd_oed, and replaced bu_vls_addr with bu_vls_cstr. |
| `SEC-0281` | `src/mged/chgview.c, src/mged/clone.c` | `chgview.c:269-283, 303-317, 336-368, 385, 410-440, 520-560, 680-730, 750-785, 1015-1035, 1845-1855, 1900-1920, 1935-1965, 1968-2010, 2020-2050, 2060-2090, 2100-2140, 2220-2530, 2540-2770, 2795-2865, 2920-2950, 2960-3040; clone.c:165-175, 230-245, 340-360, 420-445, 520-545, 560-615, 640-675, 740-840, 870-900, 1020-1090, 1160-1280` | Stack Buffer Overflow, Out-of-bounds Array Access, Double-Free, Division by Zero, Memory Leaks, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 39 (chgview.c and clone.c, 4,128 lines): in clone.c, fixed stack buffer overflows in get_name by adding field width limits with CPP_XSTR(CLONE_BUFSIZE) to bu_sscanf and replacing raw sscanf with bu_sscanf, fixed double-free and memory leaks of name vls by migrating deallocation from bu_vls_free to bu_vls_vlsfree (since get_name allocates outer struct via bu_vls_vlsinit), fixed out-of-bounds negative array indexing obj_list.names[-1] in copy_v5_comb_tree and copy_v4_comb by validating index_in_list return value (lidx >= 0) before indexing, fixed memory leak of obj_list.names[i].src in copy_object and ensured obj_list is freed across all return paths, fixed memory leaks of internal structures and records in copy_v4_solid, copy_v4_comb, copy_v5_solid, and copy_v5_comb on error paths, fixed potential division by zero in f_tracker by checking n_verts > 1, replaced raw calloc/free with bu_calloc/bu_free, and replaced read-only bu_vls_addr calls with bu_vls_cstr; in chgview.c, guarded against division by zero in cmd_size, mged_vscale, and cmd_sca by checking gv_i_scale with ZERO macro, added null checks on view_state and vs_gvp across cmd_center, cmd_size, size_reset, edit_com, cmd_autoview, f_status, f_refresh, update_all_rate_flags, mged_print_knobvals, knob_apply_misc, f_knob, mged_zoom, cmd_setview, f_slewview, mged_svbase, f_svbase, setview, slewview, f_view_ring, cmd_mrot, cmd_rot, cmd_arot, mged_vscale, and cmd_sca, fixed out-of-bounds argv access in edit_com, bounded state_str array indexing in f_status, replaced sprintf with snprintf in f_regdebug and guarded DMP, fixed early-out memory leak of orig_nargv and vlsargv in f_ill, guarded path_parse against null path, guarded MEDIT(s) and s->s_edit before dereference in mged_librt_knob_edit_apply and mged_escale, and replaced read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0282` | `src/mged/cmd.cpp, src/mged/cmd.h` | `cmd.cpp:245-285, 295-310, 410-440, 480-530, 890-950, 1170-1190, 1220-1285, 1300-1395, 1410-1460, 1480-1545, 1550-1570, 1580-1600, 1620-1645, 1675-1690, 1705-1745, 1775-1925, 1990-2090, 2145-2220, 2275-2285, 2315-2440, 2450-2495, 2500-2540, 2580-2595, 2635-2680, 2730-2745, 2770-2785, 2835-2855, 2875-2930, 3005-3020, 3050-3060, 3075-3095, 3300-3325, 3410-3540` | Memory Leaks, Resource Leak, Out-of-bounds Argument Access, Division by Zero, Duplicate Print Bug, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 40 (cmd.cpp and cmd.h, 3,647 lines): in cmd.h, audited header prototypes and linkage guards (clean); in cmd.cpp, eliminated memory leak in cmd_ged_inside where rt_db_internal intern was transformed but never freed with rt_db_free_internal across all exits, fixed NULL pointer dereference in cmd_ged_inside on illump->s_old.s_Eflag when illump is NULL, eliminated resource leak in cmd_rt_gettrees where rtip was created with rt_i_create but not destroyed with rt_i_destroy on missing geometry argument exit paths, eliminated duplicate window listing print bug in f_tie when called with no arguments, guarded division by zero in cmd_units with ZERO macro on sf, checked argc and argv bounds before indexing in cmd_ged_edit_wrapper, cmd_ged_simulate_wrapper, cmd_ged_in, cmd_ged_more_wrapper, cmd_nmg_collapse, and cmd_get_more_default, added missing error report when window name is not found in cmd_win set, added null pointer checks on view_state, view_state->vs_gvp, s->mged_curr_dm, DMP, illump, and MEDIT(s) across GED wrapper dispatchers, view management, and rendering hooks (cmd_ged_view_wrapper, cmd_ged_dm_wrapper, cmd_screengrab, cmd_blast, f_postscript, f_winset, _view_update_rate_flags_viewonly, and cmd_view), replaced fixed-size snprintf format in f_bomb with sizeof(buffer), and replaced ~45 read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0283` | `src/mged/color_scheme.c, src/mged/columns.c, src/mged/dm-generic.c, src/mged/dodraw.c` | `color_scheme.c:60-75,100-110,135-155,200-245; columns.c:42-78,85-93; dm-generic.c:51-110,140-250,260-395,438-595,602-643,658-688; dodraw.c:58-85,95-165,177-210,223-272,280-286,290-298` | Memory Leak, Null Pointer Dereference, Out-of-bounds Array / Argument Access, and Missing Parameter Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 41 (color_scheme.c, columns.c, dm-generic.c, and dodraw.c, 1,449 lines): in color_scheme.c, added null pointer checks on m_dmp, m_dmp->dm_dmp, s->interp, and color_scheme before dereferencing, ensured error messages are safely reported, and replaced read-only bu_vls_addr calls with bu_vls_cstr; in columns.c, added null pointer guards in vls_col_item and vls_col_eol to prevent crashes on null strings or null buffer pointers, and added symmetric null pointer checks for a, b, *dp1, *dp2, (*dp1)->d_namep, and (*dp2)->d_namep in cmpdirname comparator to prevent qsort crashes; in dm-generic.c, added null checks on s, s->interp, argc, and argv in common_dm and dm_commands, added null guards on rubber_band, mged_variables, s->mged_curr_dm, DMP, view_state, view_state->vs_gvp, s->gedp->ged_gvp->gv_s, adc_state, grid_state, and MEDIT(s) across idle, m, am, adc, con, size, getx, and bg command handlers, checked argc bounds before indexing argv[1..4], replaced raw sscanf with bu_sscanf for RGB background parsing, added null guards in view_state_flag_hook, dirty_hook, zclip_hook, and set_hook_data, and replaced all read-only bu_vls_addr calls with bu_vls_cstr; in dodraw.c, eliminated memory leak in replot_modified_solid where rt_db_internal intern was transformed via transform_editing_solid but never freed when ft_plot failed (< 0), fixed potential NULL pointer dereference and out-of-bounds access in replot_original_solid by validating bdata->s_fullpath.fp_len > 0 and LAST_SOLID(bdata) before dereferencing dp->d_namep, freed existing bdata->s_fullpath with db_free_full_path before duplicating in drawH_part2, guarded s->gedp and ged_dl(s->gedp) against NULL, added null guards in mged_bound_solid, replot_original_solid, replot_modified_solid, add_solid_path_to_result, and redraw_visible_objects, and replaced read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0284` | `src/mged/doevent.c, src/mged/dozoom.c` | `doevent.c:65-75,88-120,186-215,253-277,289-360,414-448,460-630,689-715; dozoom.c:54-66,77-93,133-165,165-179,190-210,240-256,270-305,320-335,355-385` | Division by Zero, Null Pointer Dereference, and Out-of-bounds Argument Access | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 42 (doevent.c and dozoom.c, 1,064 lines): in doevent.c, guarded against division by zero in motion_event_handler by clamping window width and height to positive values (width <= 0 ? 1 : width, height <= 0 ? 1 : height) and checking dm_get_aspect with ZERO macro before dividing, added null checks on s, eventPtr, s->mged_curr_dm, and DMP in mged_dm_motion and doEvent, added null guards on rubber_band, grid_state, MEDIT(s), adc_state, view_state, and view_state->vs_gvp across all AMM modes (AMM_IDLE, AMM_ROT, AMM_TRAN, AMM_SCALE, AMM_ADC_*, AMM_CON_*), guarded MEDIT in reset_edflag, and replaced read-only bu_vls_addr calls with bu_vls_cstr; in dozoom.c, eliminated critical division by zero in dozoom perspective calculation where to_eye_scr divided by tan(perspective) without verifying tan != 0 by checking tan value with ZERO macro and using fallback large distance, guarded against division by zero when adjusting inv_viewsize by checking MEDIT(s)->model_changes[15] with ZERO macro, added null checks on s, s->mged_curr_dm, DMP, view_state, view_state->vs_gvp, s->gedp, MEDIT(s), mged_variables, and color_scheme in dozoom, guarded transparency access (sp->s_os->transparency) against null sp->s_os in create_dlist_solid, added null pointer guards in createDLists, create_dlist_solid, createDListSolid, create_dlist_all, createDListAll, free_dlists, and freeDListsAll, and validated active_dm_set display managers and variables. |
| `SEC-0285` | `src/mged/edsol.c, src/mged/f_cmd.h` | `edsol.c:85-115, 140-190, 245-295, 305-345, 360-395, 410-445, 460-520, 535-545, 560-575, 590-620, 680-745, 765-815, 875-925, 940-970, 990-1010, 1025-1045, 1070-1115, 1145-1215, 1250-1310, 1335-1390, 1420-1490, 1510-1545, 1555-1575, 1585-1615, 1625-1675, 1685-1710, 1720-1800, 1810-1880, 1890-1960, 1970-1990, 2000-2030, 2040-2070, 2080-2160, 2170-2220, 2230-2245, 2265-2305; f_cmd.h:40-155` | Inverted Logic Bug, Double-Free, Memory Corruption / Type Mismatch, Resource Leaks, Division by Zero, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 43 (edsol.c and f_cmd.h, 2,324 lines): in f_cmd.h, audited extern command function prototypes (clean); in edsol.c, fixed critical inverted logic bug in ecmd_bot_thick_clbk where face_state > -1 mistakenly triggered error branch and face_state < 0 updated face 0, eliminated double-free in sedit_apply where rt_db_put_internal already frees es_int on all outcomes, fixed reset sequencing in f_sedit_reset where rt_db_free_internal was called before ft_prim_edit_reset zeroing primitive type ID, fixed inverted condition in f_get_sedit (illump || !illump->s_u_data) that caused command to always fail, prevented memory corruption in f_put_sedit by returning TCL_ERROR on functab mismatch rather than executing bu_structparse_argv with wrong structure layout, guarded against division by zero in mged_param with ZERO macro on viewscale, clamped input parameter count to RT_EDIT_MAXPARA, eliminated memory leaks of vls commands on early returns in get_sketch_name, ecmd_extrude_skt_name_clbk, and f_get_sedit_menus, replaced raw atof/atoi with bu_sscanf, verified bn_mat_inverse return in oedit_apply and f_oedit_apply, added primitive type bounds validation (ID_NULL < id <= ID_MAX_SOLID), and added extensive NULL guards on s, MEDIT(s), view_state, DMP, and bdata across all solid and object editing routines. |
| `SEC-0286` | `src/mged/f_db.c, src/mged/facedef.c` | `f_db.c:45-150, 155-165, 170-290, 295-305, 310-340, 345-355, 375-465, 475-515; facedef.c:75-135, 140-195, 210-305, 315-330, 340-350, 365-385, 395-425, 435-445` | Out-of-bounds Array / Buffer Access, Uninitialized Variables, Division by Zero, Resource Leaks, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 44 (f_db.c and facedef.c, 984 lines): in f_db.c, guarded against NULL pointer dereferences on s, gedp, ctx, argv, interpreter, and dbip across _post_opendb_failed, callbacks, f_opendb, and f_closedb, eliminated uninitialized buffer reads when bu_fgets returns EOF, checked Tcl result string validity before indexing, guarded curr_cmd_list before setting more_default, verified argc >= 2 before stripping trailing y/n database creation flags, and replaced all bu_vls_addr calls with bu_vls_cstr; in facedef.c, initialized plane equation index to -1 and added explicit range validation (plane >= 0 && plane < 6) to prevent out-of-bounds array writes, added upper and lower bounds checks on argc-derived array indexing into p_pleqn, p_3pts, p_rotfb, and p_nupnt arrays to prevent out-of-bounds reads, guarded against division by zero in get_pleqn using ZERO macro on vector magnitude before unitizing, replaced raw atof and atoi with bu_sscanf with return validation, added NULL pointer checks on arbo, s, MEDIT(s), and interp, freed error_msg VLS on all exit paths, and replaced bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0287` | `src/mged/fbserv.c, src/mged/grid.c` | `fbserv.c:59-64, 100-119, 137-208, 214-239, 246-273, 277-305, 325-330, 334-426, 432-441, 451-460, 469-502, 513-553, 557-631, 644-665, 669-709, 713-739, 743-786, 790-820, 824-864, 871-900, 904-924, 928-944, 948-976, 983-1002, 1009-1028, 1035-1053, 1058-1081, 1085-1102, 1106-1125, 1135-1163, 1167-1183, 1187-1193, 1201-1220; grid.c:69-85, 88-117, 120-140, 144-234, 238-291, 295-329, 333-353, 361-399, 403-426, 430-451, 455-477` | Buffer Over-read, Mismatched Framebuffer Routine, Division by Zero, Infinite Loop / UI Hang, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 45 (fbserv.c and grid.c, 1,754 lines): in fbserv.c, fixed critical bug in fb_server_fb_bwwriterect where fb_writerect (RGB, 3 bytes/pixel) was called instead of fb_bwwriterect (monochrome, 1 byte/pixel) causing out-of-bounds heap over-reads and image corruption; added packet length and payload dimension validation across all framebuffer network handlers (fb_clear, fb_read, fb_write, fb_readrect, fb_writerect, fb_bwreadrect, fb_bwwriterect, fb_cursor, fb_setcursor, fb_scursor, fb_window, fb_zoom, fb_view, fb_wmap, fb_help) preventing buffer over-reads on truncated or malformed network packets; clamped absurd pixel requests (up to 8192x8192); handled malloc failures with 0-length error packets to prevent client hangs; replaced bu_strlcpy with bounded memcpy for binary auth token packets; added NULL pointer checks on pcp, s, s->mged_curr_dm, DMP, and fbp across all routines; in grid.c, guarded divisions against zero in draw_grid, snap_to_grid, and round_to_grid using ZERO macro on scale and aspect ratio; guarded against integer division by zero and infinite loops when res_major_h or res_major_v <= 0; clamped maximum grid dots (nv_dots, nh_dots <= 2000) to prevent denial-of-service UI hangs; added NULL pointer checks on s, s->mged_curr_dm, s->dbip, grid_state, view_state, view_state->vs_gvp, color_scheme, and s->interp across all callbacks and snap routines; and replaced all read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0288` | `src/mged/history.c, src/mged/mater.c, src/mged/menu.c, src/mged/menu.h` | `history.c:53-83, 86-101, 109-156, 171-253, 257-274, 278-285, 288-311, 314-389, 392-401, 404-421; mater.c:49-56; menu.c:98-106, 112-137, 139-162, 164-234, 240-247, 252-257, 262-293, 298-335, 339-358, 362-398, 411-482, 496-538; menu.h:70-73` | Memory Leak, Out-of-bounds Array / Buffer Access, Dead / Unused Code, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 46 (history.c, mater.c, menu.c, and menu.h, 1,086 lines): in history.c, eliminated guaranteed memory leak in f_history by freeing dynamic VLS str across all normal and error exit paths; guarded against out-of-bounds buffer reads in f_journal by replacing single-byte string indexing with BU_STR_EQUAL(argv[1], "-d"); safely handled empty command string lengths in cmd_hist; added NULL pointer checks on cmdp, curr_cmd_list, curr_cmd_list->cl_cur_hist, journalfp, hptr, argv, and interp across history_record, history_journalize, f_journal, f_history, history_prev, history_cur, history_next, and cmd_hist; cleared dangling cl_cur_hist pointer in history_cleanup; replaced all read-only bu_vls_addr calls with bu_vls_cstr; in mater.c, added NULL pointer checks on s, s->gedp, ged_dl, dbip, and DMP in mged_color_soltab before dereferencing; in menu.c, eliminated dead/unused Tcl_DString variables in mged_mmenu_set and mmenu_set; added strict index bounds validation (index >= 0 && index < NMENU) in mmenu_set, mmenu_set_all, and cmd_mmenu_get to prevent out-of-bounds memory writes and reads; removed unsafe static storage duration from loop counters menu and item in mmenu_display and mmenu_select to prevent re-entrancy issues; added NULL checks on mptr->menu_string before indexing; added comprehensive NULL pointer guards on s, s->mged_curr_dm, DMP, menu_state, color_scheme, mged_variables, interp, and active_dm_set display managers across btn_item_hit, btn_head_menu, chg_l2menu, cmd_mmenu_get, mmenu_init, mged_menu_refresh, mged_mmenu_set, mmenu_set, mmenu_set_all, mged_highlight_menu_item, mmenu_display, and mmenu_select; and replaced all read-only bu_vls_addr calls with bu_vls_cstr; in menu.h, corrected header guard comment typo. |
| `SEC-0289` | `src/mged/mged.c` | `mged.c:357-360, 400, 415-420, 440-460, 490-500, 520-535, 545, 725, 840, 865, 900, 910, 925-975, 995, 1055-1100, 1115-1235, 1270-1360, 1370-1425, 1490, 1530-1765, 1780-1805, 1840-1925, 1970, 2075-2260, 2280, 2410, 2470, 3118, 3155-3165, 3258, 3335, 3390, 3458` | Division by Zero, Memory Leaks, Dead Variable, Out-of-bounds Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 47 (mged.c, 3,532 lines): eliminated floating-point division by zero in event_check when view_state->k.sca == 10.0 (where 1.0 / (1.0 - (view_state->k.sca / 10.0)) evaluated with 0.0 denominator) by validating denominator with ZERO macro; eliminated Tcl_DString memory leak in stdin_input on EOF return under non-cbreak mode; eliminated dead variable place and unused sprintf in mged_finish; guarded s->s_edit before rt_edit_destroy in mged_finish; guarded DMP and dm_bg before array indexing dm_bg[0..2] in main; guarded s->gedp before checking ged_subp table in main; added null pointer checks on s, s->s_edit, MEDIT(s), s->interp, view_state, view_state->vs_gvp, s->mged_curr_dm, DMP, curr_cmd_list, sd, and active display managers across mged_process_char, event_check, stdin_input, std_out_or_err, refresh, mged_finish, apply_cli_overrides, and main; added input_str_index bounds validation in mged_process_char; replaced raw sscanf with bu_sscanf in parse_debug_uint; and replaced all (~45) read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0290` | `src/mged/mged.h, src/mged/mged_dm.h, src/mged/mged_impl.cpp, src/mged/mged_impl.h, src/mged/mged_wdb.h` | `mged.h:418-429; mged_dm.h:465, 520-530; mged_impl.cpp:35-43, 45-94, 97-114, 144-151, 154-165, 167-179, 181-193, 196-220; mged_impl.h:22, 57; mged_wdb.h:38-44` | Uninitialized Memory, Missing Header Guards, Duplicate Code, Division by Zero, Resource Leak, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 48 (mged.h, mged_dm.h, mged_impl.cpp, mged_impl.h, mged_wdb.h, 1,610 lines): in mged_impl.cpp, zero-initialized allocated mged_state using memset to eliminate widespread uninitialized struct pointers and flags; refactored mged_state_create to call mged_state_init_internals, eliminating duplicate 18 callback registrations (DRY); in mged_state_destroy, guarded search_snapshot, dpy_string, s_edit, and s_edit->e before destroying and delegated internal destruction to mged_state_destroy_internals; cleared cmd_map in MGED_Internal destructor; guarded internal callback map lookups, registrations, and sync against null pointers and uninitialized state in mged_internal_clbk_map, mged_state_clbk_set, mged_state_clbk_get, and mged_edit_clbk_sync; in mged.h, guarded s, s->interp, and s->dbip in CHECK_DBI_NULL and CHECK_READ_ONLY macros to prevent null pointer crashes; in mged_dm.h, converted GET_MGED_DM macro to do-while(0) and guarded tp and tp->dm_dmp before dm_get_id to prevent null pointer dereference; guarded VIEWFACTOR against division by zero with ZERO macro; in mged_impl.h, added standard header guard #ifndef MGED_MGED_IMPL_H; in mged_wdb.h, wrapped extern declarations with __BEGIN_DECLS / __END_DECLS for standard C linkage when included in C++ translation units. |
| `SEC-0291` | `src/mged/mover.c, src/mged/overlay.c, src/mged/plot.c, src/mged/predictor.c, src/mged/rect.c` | `mover.c:43-65, 75-120; overlay.c:37-67; plot.c:49-265; predictor.c:47-51, 58-64, 73-114, 118-133, 176-200, 324-338; rect.c:66-82, 89-115, 122-127, 133-180, 185-228, 233-239, 243-288, 292-305, 309-380` | Double-Free, File Descriptor Double-Close / Leaks, Logic Bugs, Memory Leaks, Division by Zero, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 49 (mover.c, overlay.c, plot.c, predictor.c, rect.c, 1,179 lines): in mover.c, eliminated double-free in moveHobj and moveHinstance where rt_db_free_internal was called after rt_db_put_internal failure (which already frees internal database object on all outcomes), fixed memory leak in moveHinstance when combination tree is empty or object is not a combination by calling rt_db_free_internal, initialized internal database object with RT_DB_INTERNAL_INIT, and added null pointer checks on s, dbip, cdp, dp, xlate, and interp; in overlay.c, added null checks on ctp, s, gedp, mged_curr_dm, and DMP, replaced read-only bu_vls_addr with bu_vls_cstr, and explicitly returned TCL_OK; in plot.c, eliminated file descriptor double-close bug where close(fd1[1]) and close(fd3[0]) were executed after fclose(fp_w) and fclose(fp_r), fixed file descriptor leaks when subsequent pipe() calls fail, handled fork() failures gracefully, added _exit(1) after execlp calls to prevent child processes from continuing parent execution on exec failure, verified fp_w and fp_r after fdopen, guarded view_state and vs_gvp before matrix multiplication, replaced sprintf with snprintf, and replaced bu_vls_addr with bu_vls_cstr; in predictor.c, fixed logic bug in poly_trail where t1->t_nused <= 0 was checked twice instead of validating t2->t_nused, guarded division by zero in predictor_frame when frametime is zero using ZERO macro, and added null pointer checks across init_trail, push_trail, poly_trail, predictor_init, predictor_kill, predictor_frame, and predictor_hook; in rect.c, fixed critical crash in zoom_rect_area where rb_set_dirty_flag was passed NULL data causing MGED_CK_STATE abort, guarded against division by zero in rect_image2view when width <= 0, guarded against division by zero in adjust_rect_for_zoom, draw_rect, and zoom_rect_area when window aspect ratio is zero using ZERO macro, replaced bu_vls_addr with bu_vls_cstr, and added null pointer checks on s, mged_curr_dm, DMP, rubber_band, color_scheme, and interp. |
| `SEC-0292` | `src/mged/rtif.c, src/mged/scroll.c, src/mged/sedit.h, src/mged/set.c` | `rtif.c:66-85, 100-125, 151-168, 199-265, 281-356, 370-410, 415-440; scroll.c:98-115, 122-132, 134-148, 157-293, 303-332, 335-412, 415-468, 482-553, 561-611; sedit.h:44-67; set.c:132-147, 151-166, 177-198, 208-234, 245-268, 280-294, 323-346, 350-380, 384-415, 424-509, 513-534, 538-556, 565-598, 608-624` | Loop Index Typo / Premature DList Deallocation, File Descriptor Leaks on Interrupt, Array Out-of-Bounds, Division by Zero, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 50 (rtif.c, scroll.c, sedit.h, set.c, 1,762 lines): in set.c, fixed critical bug in set_dlist where inner loop searching for active display managers sharing display lists used outer index di instead of dj in BU_PTBL_GET and checked uninitialized dlp2, causing the search to always fail and prematurely free active display lists in other display managers; guarded display list scene object list against empty list reads when freeing display lists; guarded against division by zero in set_absolute_model_tran when view scale is zero using ZERO macro; clamped perspective_angle to valid table indices [0..3] in establish_perspective and toggle_perspective preventing out-of-bounds array reads; guarded s, s->s_edit, and MEDIT(s) before syncing mv_context; guarded multi-level pointers in unset_var before dereferencing; guarded active display managers and DMP in set_dirty_flag and set_scroll_private; in rtif.c, fixed file descriptor leak in f_rmats when interrupted via setjmp by ensuring fp is closed before returning; validated and guarded vector list vertices (vp->nused > 0) preventing negative array indexing; added null pointer checks on s, s->gedp, view_state, view_state->vs_gvp, and interp across cmd_rt, cmd_rrt, rt_read, f_rmats, f_nirt, and f_vnirt; replaced atoi with bu_sscanf; in scroll.c, zero-initialized all elements of dm_scroll_array in set_scroll to guarantee NULL termination and bounded scroll_array pointer traversal by array capacity in scroll_display and scroll_select, preventing out-of-bounds array reads; extracted apply_sl_tol helper to eliminate duplicated tolerance thresholding logic (DRY); added null pointer checks on s, s->interp, view_state, DMP, color_scheme, and mged_variables across all event handlers and display routines; in sedit.h, guarded s, s->s_edit, and s->s_edit->e in SEDIT_ROTATE, SEDIT_TRAN, SEDIT_SCALE, and SEDIT_PICK, and guarded s in OEDIT_ROTATE, OEDIT_TRAN, and OEDIT_SCALE macros, preventing null pointer dereference crashes throughout solid and object editing; and replaced all read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0293` | `src/mged/setup.c, src/mged/share.c, src/mged/tclsync.c, src/mged/tedit.c` | `setup.c:502-530, 536-578, 585-605, 610-745; share.c:47-70, 98-278, 320-382, 418-448, 452-478, 482-506; tclsync.c:42-59, 100-146, 178-205, 230-245, 275-296, 315-345, 386-425, 476-525; tedit.c:57-75, 78-129, 134-152, 155-184` | Resource Leaks, Wrong Memory Deallocation Bug, Double-Open / File Descriptor Leaks, Array Out-of-Bounds, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 51 (setup.c, share.c, tclsync.c, tedit.c, 1,978 lines): in share.c, fixed critical bug in usurp_all_resources where freeing a zero-refcount display list state freed MGED_STATE->mged_curr_dm->dm_dlist_state instead of dlp2->dm_dlist_state, corrupting active display manager memory and leaking dlp2 resources; added null checks on dlp1, dlp2, and resource pointers in SHARE_RESOURCE macro; guarded all resource pointers in free_all_resources before decrementing refcounts and freeing, and nullified pointers after cleanup; added null checks on ctp, s, interpreter, and argv in f_share and f_rset; guarded active display managers and pathname lookups in f_share and share_dlist against null pointers; guarded s->mged_curr_dm in f_rset; in tedit.c, fixed file descriptor leak and concurrent double-opening of temporary files by passing bu_temp_file's open file handle directly to writesolid, flushing and closing before invoking external editor; eliminated memory leak of vls buffer in writesolid; bounded primitive type idb_type between ID_NULL and ID_MAX_SOLID before indexing EDOBJ dispatch table in writesolid and readsolid to prevent out-of-bounds memory access; made writesolid, readsolid, and editit static to minimize scope; guarded s, gedp, s_edit, MEDIT(s), view_state, and interp; in setup.c, guarded ctp, s, interp, and ctp->tcl_func in mged_cmd_dispatch; guarded argv[0] in quit usage message; guarded s and interp in cmd_setup; guarded s and view_state before setting vs_flag in mged_refresh_handler_impl and allocating vs_gvp in mged_setup; in tclsync.c, guarded interp, objc, objv, snapshot, record, and strings across EvalWords, ResultCopy, QualifiedPattern, AppendRecord, AppendProc, AppendProcs, AppendVariable, AppendVariables, AppendNamespace, AppendAliases, BuildInterpSnapshot, ReplayRecord, and ReplayInterpSnapshot; and replaced all read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0294` | `src/mged/titles.c, src/mged/track.c, src/mged/update.c` | `titles.c:60-165, 175-207, 240-636; track.c:67-555, 558-572, 575-654, 658-691, 695-760, 764-803, 807-817, 821-842, 846-875, 879-903, 908-933; update.c:43-54, 57-79, 88-99, 105-118, 124-134, 142-270` | Division by Zero, Stack Buffer Overrun Risk, String Mutation Bug, Unbounded Array Access, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 52 (titles.c, track.c, update.c, 1,871 lines): in titles.c, eliminated floating-point division by zero in framerate calculation when frametime is zero using ZERO macro; eliminated in-place destructive mutation of caller's VLS buffer and dropped trailing lines in screen_vls by drawing lines via temporary buffer; bounded global_editing_state array indexing into state_str to prevent out-of-bounds reads; bounded solid type indexing into OBJ array and guarded ft_name before displaying keypoint; guarded MEDIT(s) against NULL before accessing model_changes and e_keypoint; guarded illump against NULL before checking s_old.s_Eflag; guarded s, s->mged_curr_dm, DMP, view_state, view_state->vs_gvp, and s->interp across create_text_overlay and dotitles; replaced sprintf with snprintf; replaced all read-only bu_vls_addr calls with bu_vls_cstr; in track.c, eliminated division by zero in slope when del[0] or slope is zero using ZERO macro and SMALL_FASTF; eliminated division by zero in crdummy when plano[0] - w[0] is zero using ZERO macro; eliminated multiple divisions by zero in top when magnitude of del is zero; clamped cosine values before acos in tancir to prevent NaN return; replaced unsafe custom track_itoa with snprintf; increased solid/region/group name buffers from 9-12 to 32 bytes to prevent name truncation; replaced raw atof with bu_sscanf; scoped all helper functions (crname, slope, crdummy, trcurve, bottom, top, crregion, track_itoa, wrobj, tancir) to static; guarded s, s->dbip, s->wdbp, and s->interp; in update.c, guarded s in mged_update and f_update against NULL pointer dereference; replaced raw sscanf with bu_sscanf; guarded donePtr and eventPtr in event callbacks; guarded clientData, s, interp, and argv[0..2] in f_wait; and replaced bu_vls_addr with bu_vls_cstr. |
| `SEC-0295` | `src/mged/usepen.c, src/mged/utility1.c, src/mged/vparse.c, src/mged/wdb_obj.c` | `usepen.c:50-87, 93-177, 184-196, 203-214, 228-337, 369-565; utility1.c:45-73, 78-95, 100-122, 128-149, 156-182, 185-293; vparse.c:34-58, 61-81; wdb_obj.c:66-74, 76-87, 94-127, 130-145, 154-162, 164-186, 188-255, 261-267, 273-281, 284-383, 394-402, 404-560, 570-578, 581-704, 715-722, 724-840, 847-855, 857-868, 879-887, 889-929, 938-945, 960-1074, 1081-1087, 1089-1269, 1279-1286, 1294-1308, 1310-1403, 1416-1424, 1426-1624, 1638-1646, 1648-1677, 1683-1690, 1692-1757, 1767-1775, 1777-1798, 1805-1813, 1912-1926, 1946-1985, 1992-2002, 2010-2027, 2035-2055, 2079-2154, 2161-2168` | Memory Leaks, Dangling Database Pointers, Dead Pre-libged Code, Out-of-bounds Array Access, Command Argument Parsing Bug, In-place String Mutation, and Null Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD mged Batch 53 (usepen.c, utility1.c, vparse.c, wdb_obj.c, 3,149 lines): completing all 55 files of src/mged (100% complete): in usepen.c, eliminated dangerous in-place mutation of argv[1] string in f_matpick by copying into a local buffer before splitting slash path; removed static storage duration from transformation matrices t1 and t2 in wrt_view to make the function re-entrant; guarded against null pointers in illump before accessing s_u_data in f_matpick; guarded s, s->mged_curr_dm, s->gedp, ged_dl(s->gedp), DMP, illump, and illum_gdlp across illuminate, f_aip, and f_matpick; guarded argv[1] against null/empty strings; replaced raw sprintf with snprintf; and replaced all read-only bu_vls_addr calls with bu_vls_cstr; in utility1.c, eliminated over 200 lines of dead pre-libged code, including obsolete unused global variables (path, identt, idbuf, operate, regflag, lastmemb, old_or_new, oper_ok, numsol, numreg, idfd, rd_idfd, tabptr, ctemp) and unused functions/structs (printcodes, Do_printnode, check, id_names, id_to_names); added null checks on s and s->gedp in f_edcolor, f_edcodes, f_edmater, and f_red; and replaced bu_vls_addr with bu_vls_cstr; in vparse.c, added null pointer guards on vls, how_to_parse, structp, argv, and argv[1] across mged_vls_struct_parse and mged_vls_struct_parse_old; in wdb_obj.c, eliminated memory leak of log_str in wdb_track_cmd by adding missing bu_vls_free; fixed database reopen bug in wdb_reopen_cmd where allocating a new wdbp reassigned the local parameter and leaked the new object while leaving callers with a dangling pointer to freed dbip, by updating wdbp->dbip in place; fixed argument index parsing bug in wdb_make_bb_cmd where passing -u caused the bounding routine to treat the new bounding box name as an input object to bound; fixed argument parity condition in wdb_tol_cmd that blocked single-tolerance queries (argc == 2); clamped perpendicularity tolerance to [-1.0, 1.0] before acos to prevent NaN return; fixed wrong return value (returning TCL_OK instead of TCL_ERROR) when object is not an ARB in wdb_move_arb_face_cmd and wdb_rotate_arb_face_cmd; fixed wrong argv indices in error messages in wdb_rotate_arb_face_cmd; dynamically allocated resource structures in wdb_rt_gettrees_cmd eliminating shared static resource state and freeing in wdb_deleteProc_rt; replaced raw sscanf and atof with bu_sscanf; checked floating-point tolerances with ZERO macro; replaced raw sprintf with snprintf; and replaced all (~52) read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0296` | `src/proc-db/bottest.c, src/proc-db/brep_cobb.cpp, src/proc-db/brep_cube.cpp, src/proc-db/brep_invalid.cpp, src/proc-db/brep_simple.cpp, src/proc-db/brep_surface.cpp` | `bottest.c:54-68,326-328; brep_cobb.cpp:226-278,285-328; brep_cube.cpp:174,242-295; brep_invalid.cpp:128-135,345-373,400-435; brep_simple.cpp:180,245-295; brep_surface.cpp:60-65,150-160,210-247` | Memory Leaks, Immediate NULL Pointer Dereference Crash, Resource Leaks, Wrong Memory Deallocation, and Missing Parameter Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 54 (bottest.c, brep_cobb.cpp, brep_cube.cpp, brep_invalid.cpp, brep_simple.cpp, brep_surface.cpp, 2,010 lines): in bottest.c, fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0] before bu_setprogname; checked outfp after wdb_fopen to prevent NULL dereference on write failure; fixed wrong memory deallocator by replacing bu_free with bu_bitv_free(face_mode); and replaced db_close(outfp->dbip) with wdb_close(outfp) to eliminate struct rt_wdb handle leak; in brep_cobb.cpp, eliminated persistent memory leak of 6 heap-allocated ON_NurbsSurface surfaces in Cobb_Sphere by using stack-allocated surfaces in a unified loop, and deleting ON_BezierSurface; guarded argv[0] before bu_setprogname; checked outfp after wdb_fopen; guarded brep before mk_brep; and replaced db_close(outfp->dbip) with wdb_close(outfp); in brep_cube.cpp, fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0]; checked outfp after wdb_fopen; eliminated internal database object memory leak by calling rt_db_free_internal(&ip); guarded brep allocation in MakeTwistedCube; and replaced db_close(outfp->dbip) with wdb_close(outfp); in brep_invalid.cpp, eliminated memory leaks in Cobb_Sphere by stack-allocating ON_NurbsSurface and deleting b1; added null check on c2 before appending to trimming loop; validated plate thickness with bu_sscanf; added standard help flags (-h, -?, --help); checked outfp after wdb_fopen; and replaced db_close(outfp->dbip) with wdb_close(outfp); in brep_simple.cpp, fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0]; checked outfp after wdb_fopen; eliminated internal database object memory leak by calling rt_db_free_internal(&ip); guarded brep allocation in MakeTwistedCube; replaced db_close(outfp->dbip) with wdb_close(outfp); and replaced raw printf with bu_log; in brep_surface.cpp, guarded brep and c2d curve allocations; validated thickness argument with bu_sscanf; added standard help flags; checked outfp after wdb_fopen; and replaced db_close(outfp->dbip) with wdb_close(outfp). |
| `SEC-0297` | `src/proc-db/brep_trimmed.cpp, src/proc-db/breplicator.cpp, src/proc-db/brickwall.c, src/proc-db/cchannel.c, src/proc-db/clutter.c, src/proc-db/common.c` | `brep_trimmed.cpp:548-552, 627-674; breplicator.cpp:40-45, 390-418, 458-470; brickwall.c:75-81, 90-165, 330, 364-370; cchannel.c:60-66, 120-135, 150-168, 211, 220-245, 348; clutter.c:90-115, 140-150, 188-192; common.c:68-72, 94-115` | Resource Leaks, Immediate NULL Pointer Dereference Crash, Division by Zero, Missing Argument Validation, and Memory Leaks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 55 (brep_trimmed.cpp, breplicator.cpp, brickwall.c, cchannel.c, clutter.c, common.c, 2,535 lines): in brep_trimmed.cpp, guarded ON_Brep allocation in MakeBrepFace against NULL return; guarded argv[0] before bu_setprogname; added standard help flags (-h, -?, --help); replaced unsafe atof with bu_sscanf with error checking; checked outfp after wdb_fopen; and replaced db_close(outfp->dbip) with wdb_close(outfp) to eliminate struct rt_wdb handle leak; in breplicator.cpp, added null check and size check (count >= 8) on points in generate_brep; guarded ON_Brep allocation; fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0]; and replaced db_close(wdbp->dbip) with wdb_close(wdbp); in brickwall.c, guarded av and *av in parse_args; guarded argv[0] before bu_setprogname; replaced raw sscanf with bu_sscanf; replaced raw sprintf with snprintf; validated units_conv to prevent division by zero; guarded against division by zero in standalone horizontal spacing when horiz_bricks <= 1; and supported standard clean exit on help flags; in cchannel.c, replaced raw sscanf with bu_sscanf with error validation; used ZERO macro for float zero comparisons; fixed infinite loop vulnerability in addHoles by verifying positive step; replaced sprintf with snprintf; guarded argv[0] before bu_setprogname; removed invalid colons requiring arguments from help options string and supported clean exit on -h/-?; checked outfp after wdb_fopen; guarded domain of sqrt calculation; and replaced db_close(db->dbip) with wdb_close(db); in clutter.c, fixed memory leak of bn_unif random buffer by calling bn_unif_free; guarded argv[0] before bu_setprogname; added help flag handling with clean exit; validated wdb_fopen; replaced sprintf with snprintf; and replaced db_close(outfp->dbip) with wdb_close(outfp); in common.c, added null pointer guard on rgb in get_rgb; added null pointer guards on name, pos, dir_at, headp, and outfp in do_light; and guarded against NaN from unitizing zero vectors. |
| `SEC-0298` | `src/proc-db/csgbrep.cpp, src/proc-db/donuts.c, src/proc-db/gaia.c, src/proc-db/gears.c` | `csgbrep.cpp:115-125,502-510,550-575; donuts.c:164-169,215,280-325,410-440,650-680,750-775,875-920; gaia.c:54-58,950-985,1020-1065; gears.c:128-132,245-265,305-325,358-410,445-520` | Memory Leaks, Double Free, Handle Leaks, and Missing Argument Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 56 (csgbrep.cpp, donuts.c, gaia.c, gears.c, 3,116 lines): in csgbrep.cpp, eliminated external buffer leak ext in write_out with bu_free_external; fixed ON_Brep leak by deleting brep and checking ON_Brep::New; guarded argv[0] before bu_setprogname; supported standard help flags (-h, -?, --help); checked outfp after wdb_fopen; freed extrude.sketch_name and revolve.sketch_name; and replaced db_close(outfp->dbip) with wdb_close(outfp); in donuts.c, replaced unbounded sprintf with snprintf across getName, createLights, createPlane, createEnvironMap, createScene, makeFlake; supported -h and -? in options; replaced raw sscanf with bu_sscanf; fixed inverted logic bug where empty material check tested == 0 instead of != 0; removed undefined fflush(stdin); guarded progname and argv[0]; checked wdb_fopen result fp; freed parameters.materialArray; and replaced db_close(fp->dbip) with wdb_close(fp); in gaia.c, added null pointer guard on path in open_raster_georef; guarded av[0] before bu_setprogname; supported clean help flag exit; replaced atoi and atof with bu_sscanf; and ensured GDAL datasets are closed on texture load failure paths; in gears.c, guarded make_gear against null db_fp and teeth <= 0; eliminated double free risk by freeing scratch arrays verts/lsegs/segments/reverse once and cleaning up gear_head wmembers; guarded av[0]; supported help flags (-h, -?, --help); replaced atof and atoi with bu_sscanf; cleaned up all_head wmembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0299` | `src/proc-db/globe.c, src/proc-db/gtimes.c, src/proc-db/helicoil.c, src/proc-db/kurt.c, src/proc-db/lattice.c, src/proc-db/lens.c` | `globe.c:42-46,67-86,115-148,165-179; gtimes.c:44-63,77-81,101-115; helicoil.c:92-105,190-222,370-381; kurt.c:64-75,124-145,212-218,238-245,268-275; lattice.c:228-235,299-335,530-552; lens.c:73-143,147-218,223-258,270-333` | Immediate NULL Pointer Dereference Crashes, Uninitialized Memory Access, Memory Leaks, Infinite Loop, and Handle Leaks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 57 (globe.c, gtimes.c, helicoil.c, kurt.c, lattice.c, lens.c, 1,910 lines): in globe.c, guarded progname and av[0]; added clean exit on help flags (-h, -?, --help); replaced atof with bu_sscanf; validated stepSize > 0 (eliminating infinite loop denial of service), initialSize > 0, and finalSize > initialSize (eliminating division by zero in shader params); replaced sprintf with snprintf; eliminated persistent leaks of wmember list nodes across loop iterations by calling mk_freemembers(&wm_hd.l) and mk_freemembers(&bigList.l); and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to fix struct rt_wdb handle leak; in gtimes.c, guarded av[0] before bu_setprogname; supported standard help options (-h, -?); replaced atoi with bu_sscanf; guarded against out-of-bounds pointer dereference when no file argument is given; guarded wdbp from wdb_dbopen against NULL; called ged_free(&ged) on every iteration to fix persistent ged container memory leaks; and replaced printf with bu_log; in helicoil.c, guarded build_helix against NULL head and non-positive turns; guarded av[0]; added clean help exit (-h, -?, --help); replaced atoi and atof with bu_sscanf; freed coil_hd and all_hd wmember lists with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in kurt.c, guarded argv[0] before bu_setprogname; added clean exit on help flags; checked outfp after wdb_fopen; in do_cell, guarded vp->v_n < 3 and fixed critical array index bug in sort loop that iterated over nroots instead of vp->v_n (which caused sorting of uninitialized memory); freed head wmembers in make_surface; guarded against division by zero in vector unitize in pnorms and do_light; and replaced db_close(outfp->dbip) with wdb_close(outfp); in lattice.c, guarded subdivide_face against freq < 1 or freq > MAX_FREQ; guarded av[0] before bu_setprogname; supported clean help exit; replaced atoi and atof with bu_sscanf; clamped frequency to MAX_FREQ; freed dome_head, light_head, and all_head wmembers with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in lens.c, fixed immediate SIGSEGV crash when run without filename where av[bu_optind] was NULL and passed to %s in bu_log; checked wdb_fopen return; guarded discriminant and radicand against negative values and ref_ind against zero; freed VLS buffers str, lens_type, and name; freed lensglass and lens wmembers; replaced sscanf with bu_sscanf; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0300` | `src/proc-db/loftwing.c, src/proc-db/masonry.c, src/proc-db/menger.c` | `loftwing.c:95-125,145-175,225-235,390-445,465-490,505-525,535-610; masonry.c:125-135,200-215,220-345,600-685,775-826,835-875,885-970,1000-1010,1020-1065; menger.c:63-68,267-330,355-425,450-465,480-565` | Division by Zero, Memory Leaks, Denial of Service via Unbounded Recursion, and Handle Leaks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 58 (loftwing.c, masonry.c, menger.c, 2,245 lines): in loftwing.c, guarded naca_eval against negative x and p >= 1.0 (preventing division by zero); guarded naca_outline against npts < 4 and non-positive nupper/nlower; guarded build_loft against NULL pointers and invalid counts; guarded av[0] before bu_setprogname; added clean exit on help flags (-h, -?, --help); replaced atoi and atof with bu_sscanf with error checks; clamped points, stations, blades, span, and chord to valid positive ranges; eliminated persistent memory leaks of wm_hd wmembers across wing and blade branches by calling mk_freemembers; ensured db_fp and allocated buffers are freed on error exits; and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to eliminate struct rt_wdb handle leak; in masonry.c, guarded set_translate and set_rotate with bu_sscanf and initialized coordinates; guarded av and *av in parse_args before bu_path_component; supported standard help exit (-h, -?); replaced raw sscanf and atof with bu_sscanf; guarded studs and span in frame_opening to prevent division by zero; freed s_hd boardseg head and wm_hd wmembers in frame; guarded sheetrock against non-positive dimensions and freed wm_hd wmembers; guarded mortar_brick against non-positive wall/brick dimensions (preventing division by zero) and freed wm_hd wmembers; freed wm_hd wmembers in brick; freed ol_hd opening list and trans_matrix in main; and replaced db_close(db_fd->dbip) with wdb_close(db_fd); in menger.c, guarded comb, depth, width, and height in slice against NULL/invalid extents; in mengerize, guarded against empty pattern or zero repeat; eliminated persistent leaks of levels[slot]->l and final->l wmembers by calling mk_freemembers; guarded av[0] before bu_setprogname; limited repeat to maximum 5 to eliminate denial-of-service memory exhaustion from recursive fractal generation; replaced heap allocation of menger, ground, light0, light1, sponge with stack allocation and freed their wmembers with mk_freemembers; freed boxes VLS container; and replaced db_close(fp->dbip) with wdb_close(fp). |
| `SEC-0301` | `src/proc-db/metaball.c, src/proc-db/molecule.c, src/proc-db/nmgmodel.c, src/proc-db/parashot.c, src/proc-db/pdb-g.cpp` | `metaball.c:64-70,88,118-120,135-163,165-170,205-210,230-265; molecule.c:39-46,75-94,105-188,190-230,235-280; nmgmodel.c:70-115,535-590; parashot.c:60-75,80-94,115-165,285-290; pdb-g.cpp:155-215,220-268,270-340` | Buffer Over-reads, Out-of-Bounds Memory Access, Memory Leaks, and Handle Leaks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 59 (metaball.c, molecule.c, nmgmodel.c, parashot.c, pdb-g.cpp, 1,761 lines): in metaball.c, guarded make_meatballs against NULL name and non-positive count (eliminating division by zero in sqrt); in mix_balls, called rt_db_free_internal to eliminate persistent internal object memory leaks for every input object; checked wdbp returned by wdb_dbopen; guarded av and av[0] before bu_setprogname; added clean exit 0 on help flags (-h, -?); replaced atoi with bu_sscanf with range validation [1, 1000000]; and replaced db_close(fp->dbip) with wdb_close(fp) to eliminate struct rt_wdb handle leak; in molecule.c, guarded argv[0] before bu_setprogname; supported standard help flags with exit 0 (-h, -?, --help); checked outfp from wdb_fopen against NULL; rewrote read_data to use line-by-line reading with bu_fgets and bu_sscanf to eliminate infinite loop denial of service on non-numeric input; added bounds checking on atom indices and types to eliminate out-of-bounds array reads in atom_list; replaced unsafe sprintf with snprintf; increased s_name buffer to prevent truncation; freed reg_head and head wmembers with mk_freemembers; freed allocated sphere linked list to fix memory leak; and replaced db_close(outfp->dbip) with wdb_close(outfp); in nmgmodel.c, guarded av and *av before bu_path_component; supported clean exit 0 on help flags (-h, -?); freed model m with nmg_km if wdb_fopen fails; and replaced db_close(fdmodel->dbip) with wdb_close(fdmodel); in parashot.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on help flags (-h, -?); replaced raw sscanf, atoi, and atof with bu_sscanf; validated step count and pipe diameter; and replaced db_close(fp->dbip) with wdb_close(fp); in pdb-g.cpp, fixed buffer over-read vulnerability when parsing fixed-column PDB records (ATOM/HETATM) on short lines by trimming newlines and padding lines up to 80 characters with spaces; replaced raw sscanf with bu_sscanf; supported clean help exit (-h, -?, --help); derived default output geometry file if omitted; freed allocated header string with bu_free; freed all_atoms wmembers with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0302` | `src/proc-db/pipe.c, src/proc-db/pipetest.c, src/proc-db/pix2g.c, src/proc-db/pyramid.c, src/proc-db/ringworld.c` | `pipe.c:169-173,248-251,320-335,465-475,477-485,508-540,579-605,607-640,683-748,755-765,789-805; pipetest.c:110-128,146-160,168-175,193-200; pix2g.c:63-70,147-164,170-198,201-225,254-270; pyramid.c:55-87,123-125,138-155,158-164; ringworld.c:66-78,82-111,126-146,148-154,160-170` | Free of Memory Not on Heap, Buffer Over-read, Race Condition, Unbounded Recursion, and Memory Leaks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 60 (pipe.c, pipetest.c, pix2g.c, pyramid.c, ringworld.c, 1,641 lines): in pipe.c, clamped Normals dot product to [-1.0, 1.0] before acos to prevent NaN; guarded tangent and cosine denominators against zero with ZERO(); fixed memory leaks and cumulative combination list corruption across pipe and elbow generations by calling mk_freemembers(&head.l) after every mk_lfcomb; guarded argv[0] before bu_setprogname; added clean exit 0 on -h and -?; replaced raw scanf with bu_fgets and bu_sscanf with validation; guarded against NULL pointer dereference in Names() and main() when fewer than two points are read; freed root points linked list; and replaced db_close(fdout->dbip) with wdb_close(fdout); in pipetest.c, fixed critical heap corruption crash (CWE-590: Free of Memory not on the Heap) by dynamically allocating pipe points via mk_pipe_init and mk_add_pipe_pnt instead of passing static array elements to mk_pipe which takes ownership and frees on export; guarded argv[0]; fixed unconditional usage message; supported clean exit 0 on help flags (-h, -?, --help); checked wdb_fopen return; added NULL guards in do_bending and pr_pipe; freed pipe points with mk_pipe_free; and replaced db_close(outfp->dbip) with wdb_close(outfp); in pix2g.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; replaced atoi and atof with bu_sscanf with range validation [1, 65536] on dimensions and positive checks on cell/object sizes; prevented buffer over-read (CWE-125) and crash when image buffer is smaller than width * height * 3 by halting with error instead of continuing to read past buffer end; eliminated critical race condition and list corruption across parallel worker threads by acquiring BU_SEM_GENERAL semaphore when modifying global allScanlineList; eliminated persistent leaks of hundreds of thousands of wmember list nodes by calling mk_freemembers on wm_hd, scanlineList, and allScanlineList; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in pyramid.c, removed unused dead function pnorms; guarded argv[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; replaced atoi with bu_sscanf and clamped recursion depth to [1, 8] to prevent denial of service from unbounded recursive branching; checked wdb_fopen return; eliminated persistent memory leaks in recursive tree generation by calling mk_freemembers(&head.l); and replaced db_close(outfp->dbip) with wdb_close(outfp); in ringworld.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on -h and -?; checked wdb_fopen return; eliminated wmember list node leaks in mk_sol, mk_ring, and main by calling mk_freemembers(&c.l); and replaced db_close(fp->dbip) with wdb_close(fp). |
| `SEC-0303` | `src/proc-db/seashell.c, src/proc-db/sketch.c, src/proc-db/specimen.c, src/proc-db/sphflake.c, src/proc-db/spltest.c` | `seashell.c:56-65,475-485,502-535,555-570,610-660; sketch.c:60-70,120-135,170-185; specimen.c:30-40,110-120,380-435; sphflake.c:95-105,150-165,190-230,285-365,370-385,470-490,575-585; spltest.c:55-65,75-85,145-175,190-205` | Memory Leaks, Handle Leaks, Unbounded Recursion Denial of Service, Division by Zero, and Input Validation | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 61 (seashell.c, sketch.c, specimen.c, sphflake.c, spltest.c, 2,106 lines): in seashell.c, guarded superformula against n1 == 0 with ZERO() to prevent division by zero in pow(); guarded argv[0] before bu_setprogname; added clean exit 0 on -h, -?, --help; replaced atof and atoi with bu_sscanf with range validation on --turns, --expand, and --res; eliminated persistent wmember list node leaks across combinations by calling mk_freemembers(&all_hd.l); and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to fix struct rt_wdb handle leak; in sketch.c, guarded argv[0] before bu_setprogname; removed dead option parsing block that caused unconditional abort on any argument; supported clean exit 0 on -h, -?, --help; checked outfp returned by wdb_fopen against NULL; freed all_head wmembers with mk_freemembers; and replaced db_close(outfp->dbip) with wdb_close(outfp); in specimen.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; replaced atof with bu_sscanf and validated spacing >= 100.0; freed reg_hd wmembers after every specimen shelf region and freed gnd_hd, lt_hd, and all_hd wmembers in main to eliminate widespread heap leaks; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in sphflake.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; clamped recursion depth to [0, 5] using bu_sscanf to eliminate denial of service from exponential tree explosion; checked fp returned by wdb_fopen against NULL; eliminated massive memory leak by freeing all wmemberArray entries with mk_freemembers before bu_free; removed undefined behavior fflush(stdin) calls; replaced unsafe sprintf and sscanf with snprintf and bu_sscanf; and replaced db_close(fp->dbip) with wdb_close(fp); in spltest.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; guarded make_face against NULL pointers and unsupported order; checked srf returned by nmg_nurb_new_snurb; and replaced db_close(fp->dbip) with wdb_close(fp). |
| `SEC-0304` | `src/proc-db/surfaceintersect.cpp, src/proc-db/surfaceintersect.h, src/proc-db/tea.c, src/proc-db/tea.h, src/proc-db/tea_nmg.c` | `surfaceintersect.cpp:32,75-80,325-354,374-405,444-450,595-605,655-685,965-985,1060-1145; tea.c:43-88,96-140; tea.h:42,352; tea_nmg.c:50-135,165-245` | Use-After-Free, Infinite Loops, Memory Leaks, File Descriptor Leak, Handle Leaks, and Missing Input Bounds Checks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 62 (surfaceintersect.cpp, surfaceintersect.h, tea.c, tea.h, tea_nmg.c, 2,014 lines): in surfaceintersect.cpp, corrected inverted SI_MIN macro; guarded against division by zero in Step when normal cross product magnitude is zero; eliminated unbounded memory leaks and fixed typo in CurveCurveIntersect by properly deleting split curve objects left1/right1/left2/right2 and intersecting right1 with right2; updated SetCurveCurveIntersectionDir to use reference parameter so intersection direction updates are not discarded on copy, enabled the negative dot product branch (dot < 0), fixed typo that wrote m_dirB[0] twice, and made curve parameters const; fixed arguments to SetCurveCurveIntersectionDir in Get_ON_X_Events; capped Jiggle iteration loops in WalkIntersection and GetStartPointsInternal to prevent infinite loop denial of service; in GetStartPointsInternal, eliminated 12 heap-allocated ON_Surface leaks per recursion node and corrected return value accumulator from &= to |=; cleaned up dynamically allocated curves in BrepBrepIntersect before returning; in main(), guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?/-help, checked wdb_fopen return, freed all wmembers with mk_freemembers, and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to fix struct rt_wdb handle leak; in tea.h, marked ducks and patches as static const to prevent multiple-definition linker collisions and inadvertent table modification; in tea.c, guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?, checked wdb_fopen return, added NULL check in dump_patch, added array bounds checks on patch indices before accessing ducks[], and replaced db_close(outfp->dbip) with wdb_close(outfp); in tea_nmg.c, fixed critical CWE-416 Use-After-Free vulnerability where nmg_m_to_vlist accessed model m after mk_nmg/wdb_export had already freed it by generating the vlist prior to exporting, fixed file descriptor leak by calling fclose(fp) on the plot3 file, freed vlist nodes with BV_FREE_VLIST, guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?, checked wdb_fopen return, checked nmg_mm() return, added bounds checks on patch indices, and replaced db_close(outfp->dbip) with wdb_close(outfp). |
| `SEC-0305` | `src/proc-db/terragen.c, src/proc-db/torii.c, src/proc-db/tube.c, src/proc-db/twistedcube.cpp, src/proc-db/twistedcube.h` | `terragen.c:120-145,280-305,335-415; torii.c:100-145,170-185,200-245; tube.c:125-155,205-245,265-295,400-470,485-500,510-530,535-555; twistedcube.cpp:35-45,120-130,165-175,210-220; twistedcube.h:1-71` | Memory Leaks, Handle Leaks, Combination List Corruption, File Descriptor Leaks, and Missing Input Bounds Checks | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 63 (terragen.c, torii.c, tube.c, twistedcube.cpp, twistedcube.h, 1,474 lines): in terragen.c, guarded av[0] before bu_setprogname, supported clean exit 0 on -h/-?/--help, replaced atoi and atof with bu_sscanf, added cleanup freeing hf and grid and calling wdb_close on sidecar write failure, freed combination members after terrain.r, water.r, sky.r, and all combs with mk_freemembers, and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in torii.c, guarded av[0] before bu_setprogname, supported clean exit 0 on -h/-?/--help, replaced atoi and atof with bu_sscanf, validated rows and cols (clamped 1..200) and major/minor radii to prevent denial-of-service memory/disk exhaustion, freed all_hd wmembers with mk_freemembers on error paths and normal completion, and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in tube.c, guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?/--help, checked outfp returned by wdb_fopen against NULL, closed pos_fp with fclose, eliminated combination list corruption and memory leaks across frames by freeing head.l after bg.r and both head.l and ghead.l on every frame iteration with mk_freemembers, freed head.l in build_cyl with mk_freemembers, checked npts <= 0 and bp in build_spline, added bounds check on nsamples (< 1022) to prevent sample array overflow and replaced sscanf with bu_sscanf in read_frame, replaced fscanf with bu_fgets and bu_sscanf in read_pos, guarded against division by zero in xfinddir with ZERO(denom), and replaced db_close(outfp->dbip) with wdb_close(outfp); in twistedcube.cpp, added array bounds checks on from and to vertex indices against brep.m_V.Count() in MakeTwistedCubeEdge, validated face.m_si and checked surface pointer in MakeTwistedCubeTrimmingLoop, checked edge index ei against brep.m_E.Count(), and added NULL check on bi in printPoints; in twistedcube.h, reviewed clean. |
| `SEC-0306` | `src/proc-db/vegetation.c, src/proc-db/vegetation.h, src/proc-db/voxelize.c, src/proc-db/wavy.c, src/proc-db/wdb_example.c` | `vegetation.c:200-230,590-645,750-800,810-850,885-985; vegetation.h:135-145,165-175; voxelize.c:235-265,380-430,445-505; wavy.c:60-95,115-125; wdb_example.c:50-65,130-140` | Memory Leaks, Handle Leaks, Combination List Corruption, Allocator Mismatches, Double Free, and Uninitialized Macro Member | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD proc-db Batch 64 (vegetation.c, vegetation.h, voxelize.c, wavy.c, wdb_example.c, 1,995 lines): completing all 55 files of src/proc-db (100% complete): in vegetation.h, fixed uninitialized branchMaxVariation bug in INIT_CHARACTERISTIC_T macro caused by setting dirMaxVariation twice; replaced unsafe sprintf with bu_strlcpy in INIT_OUTPUTCOUNTER_T; in vegetation.c, fixed memory leak of bigList on error in findIntersectors; replaced system free with bu_free on bu_calloc/BU_ALLOC buffers (segList, excluded, included, plant, and structure allocations) to eliminate allocator mismatch; fixed persistent leaks of included and excluded segment lists during growth retries; implemented recursive freeStructure helper to eliminate memory leaks of deeply nested substructures, branches, and segments in destroyPlant; freed oc->combination.l and oc->region.l wmembers with mk_freemembers; guarded argv[0] before bu_setprogname; supported clean exit 0 on -h/-?/--help; replaced atoi, atof, and atol with bu_sscanf with range validation and clamped age [1, 200] to prevent memory/CPU exhaustion; checked fp from wdb_fopen against NULL; and replaced db_close(fp->dbip) with wdb_close(fp); in voxelize.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h/-?/--help; replaced atoi with bu_sscanf; freed voldata and ebmdata buffers and closed db_fp on sidecar write and primitive creation failures; freed region_hd.l, ebm_hd.l, and all_hd.l wmembers with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in wavy.c, guarded argv[0] before bu_setprogname; fixed option parsing so -h and -? exit 0 cleanly with usage; replaced atof with bu_sscanf; checked outfp returned by wdb_fopen; documented ownership transfer where mk_bspline/wdb_export takes ownership and frees surfaces via rt_nurb_ifree, avoiding double free; and replaced db_close(outfp->dbip) with wdb_close(outfp); in wdb_example.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h/-?/--help; eliminated combination member leak by freeing wm_hd.l with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0307` | `src/qged/QgEdApp.cpp, src/qged/QgEdApp.h, src/qged/QgEdFilter.cpp, src/qged/QgEdFilter.h, src/qged/QgEdMainWindow.cpp, src/qged/QgEdMainWindow.h` | `QgEdApp.cpp:90-95,110-117,315-325,410-430,445-455,485-492,500-505,520-535,625-640; QgEdApp.h:1-119; QgEdFilter.cpp:33-40,70-75; QgEdFilter.h:1-44; QgEdMainWindow.cpp:90-100,105-110,238-245,375-385,410-415,440-445,455-505; QgEdMainWindow.h:50-55,60-65,107-115` | Allocator Mismatch, Memory Leaks, Uninitialized Pointers, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD qged Batch 65 (QgEdApp.cpp, QgEdApp.h, QgEdFilter.cpp, QgEdFilter.h, QgEdMainWindow.cpp, QgEdMainWindow.h, 1,604 lines): in QgEdApp.cpp, fixed allocator mismatch (CWE-762) by replacing C++ delete on bu_strdup strings with bu_free(tmp_av[i], "tmp_av str"); fixed memory leak of argv array av allocated with bu_calloc in QgEdApp::run_cmd; added cleanup loop in QgEdApp destructor to free any pending tmp_av strings; added NULL pointer checks on p->gedp, p->gedp->ged_io_data, ca->w, and ca->w->console before dereferencing in qt_create_io_handler and qt_delete_io_handler; guarded w and w->CurrentView() before dereferencing in run_cmd; guarded el, el->controls, and w->CurrentDisplay() in element_selected; added NULL guards on ctx and valp in raytrace_start and raytrace_done; in QgEdApp.h, audited clean; in QgEdFilter.cpp, added NULL pointer checks on event e and application model pointer c->mdl before accessing interaction_mode; in QgEdFilter.h, audited clean; in QgEdMainWindow.h, removed duplicate QgView.h include, and initialized pointer members console, cad_open, cad_save_settings, and cad_exit to NULL to prevent uninitialized memory reads (CWE-457); in QgEdMainWindow.cpp, added NULL pointer guards on c4 across isValid3D, isDisplayActive, CurrentDisplay, CurrentView, DisplayCheckpoint, DisplayDiff, QuadDisplay, SingleDisplay, and constructor mode switching; added NULL guards on vcw in IndicateRaytraceStart and IndicateRaytraceDone; added NULL guards on w and qApp in widget_active; and added NULL guards on ap->mdl and ap->mdl->gedp in CreateWidgets, ConnectWidgets, and do_dm_init. |
| `SEC-0308` | `src/qged/QgEdPalette.cpp, src/qged/QgEdPalette.h, src/qged/fbserv.cpp, src/qged/fbserv.h, src/qged/main.cpp` | `QgEdPalette.cpp:40-50,95-105,108-115,135-140; QgEdPalette.h:1-62; fbserv.cpp:50-95,120-135,178-204,208-223,225-245,260-270,280-290,315-375; fbserv.h:44-50,85-90; main.cpp:70-75,100-105,135-150` | Memory Leaks, Uninitialized Pointers, Out-of-bounds Array / Buffer Access, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD qged Batch 66 (QgEdPalette.cpp, QgEdPalette.h, fbserv.cpp, fbserv.h, main.cpp, 881 lines): in QgEdPalette.cpp, initialized filenames pointer to NULL before bu_file_list and guarded bu_argv_free, added NULL checks on cmd, cmd->i, cmd->i->tool_create, and returned tool element el before inserting into c_map and calling addElement, and guarded selected->button before setStyleSheet; in QgEdPalette.h, audited clean; in fbserv.h, initialized pointer and index members (s = nullptr, ind = -1, fbsp = nullptr) in QFBSocket and fbsp in QFBServer to prevent uninitialized memory access (CWE-457); in fbserv.cpp, guarded fbsp, s, ind bounds, and pkc in QFBSocket::client_handler, checked realloc return before updating pkc_inbuf to prevent NULL dereference on allocation failure, guarded buffer length and bounds (pkc_inend >= 0 && pkc_inend < pkc_inlen) before copying remaining data; in QFBServer::on_Connect, guarded nextPendingConnection return, fbsp, and validated socket descriptor fd >= 0 before pkg_adopt_socket; in qdm_is_listening and qdm_listen_on_port, checked fbsp against NULL; in qdm_open_server_handler and qdm_close_server_handler, guarded fbsp and listener channel nl, and cleared fbsl_chan and fbsl_fd to avoid dangling pointers; in qdm_open_client_handler and qdm_open_sw_client_handler, added client index bounds checks (0 <= i < fbs_max_clients) and guarded data, s->s, and fbsp->fbs_fbp; in qdm_close_client_handler, guarded client index and cleared fbsc_chan to NULL; in QFBIPCSocket::ipc_handler, guarded fbsp, ind bounds, notifier, and fbsc_pkg before client processing; in qdm_open_ipc_client_handler, qdm_open_ipc_sw_client_handler, and qdm_close_ipc_client_handler, added client index bounds checks and guarded fbsp->fbs_fbp; in main.cpp, guarded argc < 1, argv, and argv[0] before bu_setprogname to prevent NULL pointer dereference crashes on empty argument vectors, guarded argv[i] in option scanning loop, eliminated memory leaks of bu_vls msg on error paths and prior to QApplication launch by adding bu_vls_free(&msg). |
| `SEC-0309` | `src/qged/plugins/plugin.h, src/qged/plugins/edit/ell/QEll.cpp, src/qged/plugins/edit/ell/QEll.h, src/qged/plugins/edit/ell/ell_tool.cpp, src/qged/plugins/view/info/CADViewModel.cpp, src/qged/plugins/view/info/CADViewModel.h, src/qged/plugins/view/info/view_info.cpp` | `plugin.h:1-74; QEll.h:44-58; QEll.cpp:35-43,80-92,94-123,138-165,170-240,245-285,290-295; ell_tool.cpp:28-48; CADViewModel.h:1-63; CADViewModel.cpp:42-47,56-102; view_info.cpp:28-42` | Illegal Free of Non-Heap Member, Double Free, Memory Leaks, Uninitialized Pointers, Model Invariant Violations, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD qged Batch 67 (plugin.h, QEll.cpp, QEll.h, ell_tool.cpp, CADViewModel.cpp, CADViewModel.h, view_info.cpp, 777 lines): in plugin.h, audited clean; in QEll.h, initialized all pointer member variables (O_pnt, A_axis, B_axis, C_axis, ell_name, write_edit, make_sph, reset_values) to nullptr to prevent uninitialized pointer reads (CWE-457); in QEll.cpp, cleared struct rt_ell_internal ell with memset(&ell, 0, sizeof(ell)) in constructor; connected write_edit and reset_values buttons to their write_to_db and read_from_db slots; in destructor, set p = NULL after bv_obj_put(p); in read_from_db, guarded qApp against NULL and checked ellp against NULL before RT_ELL_CK_MAGIC; in write_to_db, fixed illegal free of non-heap C++ object member &ell (CWE-763/CWE-590) and subsequent double free (CWE-415) by dynamically allocating ellp via BU_ALLOC and relying on rt_db_put_internal's internal deallocation without redundant and dangerous rt_db_free_internal calls; in update_obj_wireframe, guarded qApp, gedp->dbip, p from bv_obj_get, wdbp from wdb_dbopen, child scene object s, and pl[i].str against NULL pointer dereferences; in update_viewobj_name, guarded qApp, gedp->dbip, p, and ell_name against NULL dereferences; in eventFilter, added NULL guard on event pointer e; in ell_tool.cpp, converted heap-allocated QIcon to stack allocation to eliminate memory leak (CWE-401); in CADViewModel.h, audited clean; in CADViewModel.cpp, guarded qApp and bview pointer v against NULL in refresh, and invoked beginResetModel before deleting m_root to preserve Qt model invariants and avoid use-after-free by attached views; set m_root = NULL in destructor; in view_info.cpp, converted heap-allocated QIcon to stack allocation and parented CADViewModel to vview to eliminate memory leaks (CWE-401). |
| `SEC-0310` | `src/qged/plugins/view/measure/CADViewMeasure.cpp, src/qged/plugins/view/measure/CADViewMeasure.h, src/qged/plugins/view/measure/measure.cpp, src/qged/plugins/view/select/CADViewSelector.cpp, src/qged/plugins/view/select/CADViewSelector.h, src/qged/plugins/view/select/select.cpp, src/qged/plugins/view/settings/CADViewSettings.cpp, src/qged/plugins/view/settings/CADViewSettings.h, src/qged/plugins/view/settings/view_settings.cpp` | `CADViewMeasure.h:26-55; CADViewMeasure.cpp:88-95,98-106,115-145,155-186; measure.cpp:30-46; CADViewSelector.h:44-94; CADViewSelector.cpp:144-146,193-221,220-246,244-271,269-290,286-320,313-350,341-408; select.cpp:31-47; CADViewSettings.h:40-64; CADViewSettings.cpp:41-55,185-226,228-267; view_settings.cpp:30-43` | Memory Leaks, Uninitialized Pointers, Argument Indexing Corruption, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD qged Batch 68 (CADViewMeasure.cpp, CADViewMeasure.h, measure.cpp, CADViewSelector.cpp, CADViewSelector.h, select.cpp, CADViewSettings.cpp, CADViewSettings.h, view_settings.cpp, 1,374 lines): in CADViewMeasure.h, removed duplicate QLineEdit include and initialized pointer members to nullptr to avoid uninitialized memory reads (CWE-457); in CADViewMeasure.cpp, freed f2d and f3d filters in destructor to fix memory leak (CWE-401); in adjust_text, eliminated persistent memory leak of QLabel on every event by reusing ma_label instead of repeatedly reallocating new QLabel instances; guarded qApp, gedp->ged_gvp, gedp->dbip, mf, and reports against NULL dereferences; in update_color and eventFilter, guarded mf, measure_3d, color_3d, color_2d, and filters; in measure.cpp, converted heap-allocated QIcon to stack allocation to prevent memory leak (CWE-401); in CADViewSelector.h, initialized all pointer members (including filter pointers pf, bf, rf) to nullptr; in CADViewSelector.cpp, freed pf, bf, and rf in destructor to fix memory leak (CWE-401); in select_objs and deselect_objs, guarded gedp, dbi_state, cf, and scene object s against NULL; in erase_objs, fixed indexing bug in av array where NULL scene objects created holes in the argv vector passed to ged_exec_erase, and checked scnt > 1 before execution; in do_draw_selections, do_erase_selections, and do_view_update, guarded dbis->pathstr return before calling bu_strdup and constructing std::string; in eventFilter, added NULL guards on event e, qApp, filters, and checkboxes; in select.cpp, converted heap-allocated QIcon to stack allocation to prevent memory leak (CWE-401); in CADViewSettings.h, initialized all pointer members to nullptr; in CADViewSettings.cpp, added NULL checks on cb in set_ckbx and ckbx_val; in checkbox_refresh and view_refresh, guarded qApp, gedp, bview v, v->gv_s, and fb_mode_combo against NULL pointer dereferences; in view_settings.cpp, converted heap-allocated QIcon to stack allocation to eliminate memory leak (CWE-401). |
| `SEC-0311` | `src/qged/plugins/polygon/QPolyCreate.cpp, src/qged/plugins/polygon/QPolyCreate.h, src/qged/plugins/polygon/QPolySettings.cpp, src/qged/plugins/polygon/QPolySettings.h, src/qged/plugins/polygon/polygon_tool.cpp` | `QPolySettings.h:35-57; QPolySettings.cpp:145-185,185-200,205-220,225-265; polygon_tool.cpp:29-50,53-80; QPolyCreate.h:40-75,98-106; QPolyCreate.cpp:155-215,225-265,270-315,335-375,410-440,442-455,458-480,485-502,505-545,555-665` | Memory Leaks, Uninitialized Pointers, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD qged Batch 69 (QPolyCreate.cpp, QPolyCreate.h, QPolySettings.cpp, QPolySettings.h, polygon_tool.cpp, 1,239 lines): in QPolySettings.h, initialized all pointer member variables to nullptr to eliminate uninitialized pointer access (CWE-457); in QPolySettings.cpp, added explicit QWidget parent to constructor, fixed severe memory leak in uniq_obj_name where ovname and vname were leaked on both collision early exit and success paths (CWE-401), guarded sketch_sync and sketch_name against NULL in sketch_sync_toggled, checked line_snapping and grid_snapping in signal handlers, and guarded p, p->s_i_data, and all UI controls against NULL in settings_sync; in polygon_tool.cpp, stack-allocated QIcon objects in polygon_tool_create and polygon_tool_modify to eliminate heap allocation leaks (CWE-401); in QPolyCreate.h, initialized all pointer member variables to nullptr (CWE-457); in QPolyCreate.cpp, added explicit QWidget parent to constructor, freed pcf in destructor to prevent filter memory leak (CWE-401), guarded qApp, gedp, gedp->dbip, p->s_i_data, and sketch widgets in finalize, guarded qApp, gedp, gedp->ged_gvp, and ps in do_vpoly_copy, guarded qApp, gedp, gedp->dbip, and ps in do_import_sketch, guarded gedp->dbip and sketch controls in sketch_sync to prevent NULL pointer dereferences on uninitialized databases, guarded v->gv_s and scene objects in toggle_line_snapping, toggle_grid_snapping, and checkbox_refresh, and in eventFilter guarded event pointer e, qApp, gedp, pcf, p->s_i_data, and ps settings controls. |
| `SEC-0312` | `src/qged/plugins/polygon/QPolyMod.cpp, src/qged/plugins/polygon/QPolyMod.h` | `QPolyMod.h:38-70,105-116; QPolyMod.cpp:35-40,170-174,180-216,218-250,252-285,293-334,336-367,369-408,410-525,528-581,583-608,610-635,670-745,747-814,816-838,840-861,863-895,897-913,915-937,945-1013` | Memory Leaks, Uninitialized Pointers, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD qged Batch 70 (QPolyMod.cpp, QPolyMod.h, 1,124 lines): completing all 34 files of src/qged (100% complete): in QPolyMod.h, initialized all pointer member variables to nullptr (ps, mod_names, select_mode, move_mode, update_mode, general_mode_opts, close_general_poly, append_pnt, select_pnt, csg_modes, apply_bool, viewsnap_poly, remove_poly, p, cf, puf, psf, ppf, pmf) to eliminate uninitialized pointer access (CWE-457); in QPolyMod.cpp, added explicit QWidget parent to constructor, freed mouse filter objects puf, psf, ppf, and pmf in destructor to eliminate memory leaks (CWE-401), guarded qApp and mod_names in mod_names_reset, guarded ip and all UI controls in poly_type_settings, guarded qApp, p, p->s_i_data, and ps settings controls in polygon_update_props, guarded qApp and gedp->ged_gvp in toplevel_config, guarded p and p->s_i_data in clear_pnt_selection, guarded qApp, gedp->ged_gvp, and ps in select, guarded p, p->s_i_data, close_general_poly, and boolean operation objects in toggle_closed_poly, guarded qApp, p, p->s_i_data, gedp->ged_gvp, and csg_modes in apply_bool_op, guarded qApp, p, p->s_i_data, and gedp->ged_gvp in align_to_poly, guarded qApp, p, p->s_i_data, and mod_names in delete_poly, guarded gedp->dbip and sketch controls in sketch_name_edit, checked existing sketch collision and guarded gedp->dbip in sketch_name_update, guarded qApp and ps in view_name_edit and view_name_update, guarded v->gv_s in toggle_line_snapping, toggle_grid_snapping, and checkbox_refresh, and in eventFilter guarded event pointer e, qApp, gedp, filters, p->s_i_data, and UI controls. |
| `SEC-0313` | `include/qtcad/defines.h, include/qtcad/QgSignalFlags.h, include/qtcad/QgAccordion.h, src/libqtcad/QgAccordion.cpp, include/qtcad/QgAppExecDialog.h, src/libqtcad/QgAppExecDialog.cpp, include/qtcad/QgAttributesModel.h, src/libqtcad/QgAttributesModel.cpp, include/qtcad/QgColorRGB.h, src/libqtcad/QgColorRGB.cpp, include/qtcad/QgDockWidget.h, src/libqtcad/QgDockWidget.cpp, include/qtcad/QgFlowLayout.h, src/libqtcad/QgFlowLayout.cpp` | `defines.h:56-88; QgSignalFlags.h:81-91; QgAccordion.h:40-78; QgAccordion.cpp:30-108; QgAppExecDialog.h:42-62; QgAppExecDialog.cpp:33-101; QgAttributesModel.h:43-70; QgAttributesModel.cpp:33-214; QgColorRGB.h:41-69; QgColorRGB.cpp:30-128; QgDockWidget.h:35-48; QgDockWidget.cpp:21-65; QgFlowLayout.h:74-81; QgFlowLayout.cpp:67-208` | Memory Leaks, Uninitialized Pointers, Off-by-one, Missing Header Guard, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libqtcad Batch 71 (14 files, 1,563 lines): in defines.h, wrapped QTCAD_SLOT and QTCAD_EVENT macro definitions in do-while(0) blocks for safe statement syntax and guarded slot_name and event_name against NULL; in QgSignalFlags.h, added missing #define QGSIGNALFLAGS_H include guard; in QgAccordion.h, made constructors explicit with default nullptr and initialized all pointer members to nullptr; in QgAccordion.cpp, reparented objscrollarea to this, guarded addObject against null pointers and prevented duplicate insertion and redundant signal-slot connections, and guarded against null objects in accordion display loop; in QgAppExecDialog.h, added explicit constructor and destructor declarations and initialized logfile, console, proc, and buttonBox to nullptr; in QgAppExecDialog.cpp, implemented destructor closing and deleting logfile to eliminate persistent memory leaks (CWE-401), deleted logfile on open failure, and guarded proc, console, and buttonBox in read_stdout, read_stderr, process_abort, and process_done to prevent NULL pointer dereferences (CWE-476); in QgAttributesModel.h, modernized constructors and initialized pointers; in QgAttributesModel.cpp, deleted m_root in destructor and prior to allocating a new root in update and do_dbi_update to eliminate severe memory leaks (CWE-401), replaced unsafe bu_avs_remove loop during iteration with canonical bu_avs_free and bu_avs_init_empty, fixed off-by-one error in beginInsertRows (inclusive cnt - 1 bound), guarded against out-of-bounds access in add_Children when color attribute has fewer than 3 components (CWE-125), guarded against NULL strings and nodes, properly nested data updates between beginResetModel and endResetModel, and validated QModelIndex in refresh; in QgColorRGB.h, removed unused dead member d and initialized pointers to nullptr; in QgColorRGB.cpp, reparented child widgets to this, zeroed bu_color structure, used bu_color_from_rgb_chars for direct color synchronization, and guarded against NULL text and button pointers; in QgDockWidget.h, initialized m to nullptr and made constructor explicit; in QgDockWidget.cpp, removed unused map and set headers, guarded event pointer against NULL in event() to prevent crash, and replaced C-style cast with static_cast; in QgFlowLayout.h, initialized spacing members; in QgFlowLayout.cpp, guarded addItem, minimumSize, and doLayout against NULL items, checked widget and style pointers before layoutSpacing to prevent NULL pointer dereference crashes (CWE-476), clamped negative spacing, and returned nullptr in takeAt. |
| `SEC-0314` | `include/qtcad/QgKeyVal.h, src/libqtcad/QgKeyVal.cpp, include/qtcad/QgUtil.h, src/libqtcad/QgUtil.cpp, src/libqtcad/bindings.h, src/libqtcad/bindings.cpp, include/qtcad/QgConsoleListener.h, src/libqtcad/QgConsoleListener.cpp, include/qtcad/QgEdit.h` | `QgKeyVal.h:39-102; QgKeyVal.cpp:45-150; QgUtil.h:58-60; QgUtil.cpp:28-148; bindings.h:23-40; bindings.cpp:73-368; QgConsoleListener.h:27-85; QgConsoleListener.cpp:36-91; QgEdit.h:46-113` | Memory Leaks, Division by Zero, Syntax / Declaration Errors, Missing Header Guards, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libqtcad Batch 72 (9 files, 1,422 lines): in QgKeyVal.h, initialized pointer members (m_root, parent) to nullptr, added explicit constructors, and added override specifiers; in QgKeyVal.cpp, initialized m_root to nullptr in model constructor to prevent undefined pointer dereferences (CWE-457), guarded curr_node against NULL in data and setData, ordered model reset correctly by calling beginResetModel before updating m_root in setRootNode, checked row bounds against child count before accessing children in index to prevent out-of-bounds reads (CWE-125), guarded node and parent pointers in parent, rowCount, NodeIndex, and NodeRow to prevent NULL pointer dereferences (CWE-476), and guarded string pointers in add_pair; in QgUtil.h, formatted header guard comment; in QgUtil.cpp, eliminated critical memory leak of bu_attribute_value_set in QgCombType by calling bu_avs_free before returning on all paths (CWE-401), guarded dp and dbip in get_arb_type, db_find_subregion, db_find_region, and QgCombType against NULL pointer dereferences, initialized intern structure with RT_DB_INTERNAL_INIT, replaced bu_bomb in db_find_subregion default case with non-fatal logging to prevent application crash on malformed CSG trees (CWE-755), and guarded comb pointer in db_find_region; in bindings.h, added standard QTCAD_BINDINGS_H header guard; in bindings.cpp, guarded against NULL event pointer in CADkeyPressEvent, CADmousePressEvent, CADmouseReleaseEvent, CADmouseMoveEvent, and CADwheelEvent, checked v->gv_s before accessing axes and ADC draw flags to prevent crash on uninitialized views (CWE-476), and prevented division by zero in CADmouseMoveEvent scaling calculation by clamping v->gv_height to a positive value (CWE-369); in QgConsoleListener.h, added standard QGCONSOLELISTENER_H header guard and initialized process, callback, data, and notifier members to nullptr; in QgConsoleListener.cpp, guarded process, process->gedp, and result string against NULL before checking string length or reading results, prevented unsigned integer underflow (CWE-191) on string length subtraction by verifying s2 > s1, safely disabled and disconnected notifier in destructor, and initialized members in constructor initialization list; in QgEdit.h, resolved syntax errors by adding missing semicolons to class declarations, corrected class name consistency (QgVectEdit), closed unclosed comment, made constructors explicit, and initialized pointer members (vx, vy, vz, dbip) to nullptr. |
| `SEC-0315` | `include/qtcad/QgConsole.h, src/libqtcad/QgConsole.cpp, include/qtcad/QgToolPalette.h, src/libqtcad/QgToolPalette.cpp, include/qtcad/QgTreeSelectionModel.h, src/libqtcad/QgTreeSelectionModel.cpp, include/qtcad/QgTreeView.h, src/libqtcad/QgTreeView.cpp` | `QgConsole.h:75; QgConsole.cpp:115-152,202-226,236-248,260-340,434-478,575-580,620-660,685-697,730-785; QgToolPalette.h:71,128-135,142-205; QgToolPalette.cpp:32-52,55-63,89-93,153-295; QgTreeSelectionModel.h:58-60; QgTreeSelectionModel.cpp:38-48,51-105,108-175; QgTreeView.h:53,84-90; QgTreeView.cpp:43-118,175-195,215-223,247-282,305-334,338-368,432-444` | Memory Leaks, Out-of-Bounds Access, Division by Zero, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libqtcad Batch 73 (QgConsole.h, QgConsole.cpp, QgToolPalette.h, QgToolPalette.cpp, QgTreeSelectionModel.h, QgTreeSelectionModel.cpp, QgTreeView.h, QgTreeView.cpp, 2,342 lines): in QgConsole.h, initialized gedp pointer to nullptr; in QgConsole.cpp, eliminated memory leak of ct and av in GEDShellCompleter when gedp or dbip is null (CWE-401), replaced unsafe C-style cast on parent() with qobject_cast, bounded completionModel indexing, fixed out-of-bounds history indexing in consolidateHistory (CWE-125), eliminated dangling pointer read from temporary toLocal8Bit buffer in historyAt using toStdString (CWE-416), guarded Completer popup against NULL in keyPressEvent, selectCompletion, and updateCompleter, added NULL checks on clipboard and mimeData before text extraction, bounded CommandPosition on Key_Up and Key_Down, guarded CommandHistory against empty back() access in commandBuffer, fixed off-by-one word replacement in insertCompletion, prevented listener memory leak in destructor and listen() (CWE-401), and clamped cursor offsets to document bounds in printStringBeforePrompt; in QgToolPalette.h, initialized all pointer and layout members to nullptr; in QgToolPalette.cpp, guarded iicon in QgToolPaletteButton constructor and setter to prevent NULL dereference crashes (CWE-476), guarded controls in QgToolPaletteElement constructor and setter, implemented destructor in QgToolPalette to delete palette elements and prevent memory leaks (CWE-401), eliminated division by zero in button_layout_resize when width is smaller than icon width (CWE-369), fixed typo in setIconWidth where icon_height was assigned to button width, guarded empty elements set in setAlwaysSelected and deleteElement to prevent out-of-bounds / end-iterator dereference crashes (CWE-125/CWE-476), and guarded controls, scrollbars, and buttons in palette_displayElement; in QgTreeSelectionModel.h, initialized treeview to nullptr; in QgTreeSelectionModel.cpp, added NULL pointer checks on treeview, m, gedp, and dbi_state in clear_all and select slots, checked sv[0] bounds, eliminated heap allocation memory leak of QModelIndexList on every selection event by using stack allocation (CWE-401), and guarded snode against NULL before accessing path_hash and path_items (CWE-476); in QgTreeView.h, initialized model and delegate pointers to nullptr; in QgTreeView.cpp, guarded painter and invalid QModelIndex in gObjDelegate::paint, clamped icon height to prevent invalid image scaling, parented draw_action and erase_action to QMenu in context_menu to eliminate action memory leaks on menu deletion (CWE-401), guarded index, cnode, gedp, and view states in do_draw_toggle, guarded against empty path_hashes before back() and pop_back(), guarded m and items in redo_expansions and redo_highlights, and added NULL checks on model m before emitting layoutChanged. |
| `SEC-0316` | `include/qtcad/QgView.h, src/libqtcad/QgView.cpp, include/qtcad/QgViewCtrl.h, src/libqtcad/QgViewCtrl.cpp, include/qtcad/QgGL.h, src/libqtcad/QgGL.cpp, include/qtcad/QgSW.h, src/libqtcad/QgSW.cpp, include/qtcad/QgQuadView.h, src/libqtcad/QgQuadView.cpp` | `QgView.h:84,115-120; QgView.cpp:80-95,308-356; QgViewCtrl.h:84-93; QgViewCtrl.cpp:94-147,149-166,168-215; QgGL.h:64-71; QgGL.cpp:74-83,108-114,150-154,249-255,326-346,366-369; QgSW.h:73-81; QgSW.cpp:78-87,88-93,95-185,275-281,350-370,395-407,445-475; QgQuadView.h:105-110; QgQuadView.cpp:61-75,111-125,130-145,163-195,208-316,392-425,436-522` | Memory Leaks, Uninitialized Pointers, Out-of-Bounds Access, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libqtcad Batch 74 (QgView.h, QgView.cpp, QgViewCtrl.h, QgViewCtrl.cpp, QgGL.h, QgGL.cpp, QgSW.h, QgSW.cpp, QgQuadView.h, QgQuadView.cpp, 2,910 lines): in QgView.h, audited clean; in QgView.cpp, replaced return in switch default with break, set canvas_gl and canvas_sw to NULL after deletion in destructor, guarded add_event_filter against NULL, and in clear_event_filter properly updated filters vector and curr_event_filter while ensuring event filters are removed from both GL and SW canvases; in QgViewCtrl.h, initialized QAction pointer members (sca, rot, tra, center, raytrace, fb_mode, fb_clear) to nullptr; in QgViewCtrl.cpp, guarded gedp in fbclear_cmd, fb_mode_cmd, do_view_update, and raytrace_cmd, checked v->gv_s in fb_mode_cmd and do_view_update to prevent NULL pointer dereferences (CWE-476), guarded callback context vctrl in rt_cmd_start and rt_cmd_done, and guarded raytrace before setIcon in raytrace_start and raytrace_done; in QgGL.h, audited clean; in QgGL.cpp, fixed critical memory leak in destructor by calling bv_free on local_v prior to deallocation and corrected struct name in BU_PUT from struct bv to struct bview (CWE-401), set pointers to NULL upon destruction, guarded fb_get_platform_specific return against NULL before dereferencing fbps->data, guarded dm_bg1 and dm_bg2 before dm_set_bg, checked dmp in mouseReleaseEvent before calling dm_set_dirty, guarded v before bv_hash in stash_hashes and diff_hashes, and checked for null QImage in save_image; in QgSW.h, audited clean; in QgSW.cpp, fixed memory leak in destructor by calling bv_free(local_v) and corrected BU_PUT struct name (CWE-401), guarded dmp against NULL in need_update and paintEvent before calling dm_set_dirty, checked width and height bounds before painting and image allocation, guarded fbps return before setup, guarded dm_bg1 and dm_bg2, checked dm_image against NULL in paintEvent and save_image, checked dmp in mouseReleaseEvent, guarded v before bv_hash in stash_hashes and diff_hashes, and guarded dmp and dm_image in save_image and get_viewport_image; in QgQuadView.h, initialized currentView and gedp to nullptr; in QgQuadView.cpp, guarded gedp and view pointers in constructor, createView, changeToSingleFrame, and changeToQuadFrame, clamped index bounds in createView to prevent out-of-bounds reads on VIEW_NAMES array (CWE-125), guarded chained pointers v->gv_s in changeToQuadFrame, guarded view objects in autoview and draw_scene loops, deleted old layout before creating a new one in createLayout to prevent layout leaks and Qt warnings, guarded currentView in view() and do_view_changed, eliminated unsafe parent geometry lookup in get(QPoint) by using widget-local rect and mapFromGlobal, guarded event e in get(QEvent), and guarded quadrant_id and spacer pointers in select. |
| `SEC-0317` | `include/qtcad/QgMeasureFilter.h, src/libqtcad/QgMeasureFilter.cpp, include/qtcad/QgPolyFilter.h, src/libqtcad/QgPolyFilter.cpp, include/qtcad/QgSelectFilter.h, src/libqtcad/QgSelectFilter.cpp, include/qtcad/QgSketchFilter.h, src/libqtcad/QgSketchFilter.cpp` | `QgMeasureFilter.h:35-45; QgMeasureFilter.cpp:45-55,80-90,95-105,120-130,135-145,150-165,190-210,240-270; QgPolyFilter.h:35-50,60-70,80-90,100-110; QgPolyFilter.cpp:60-75,100-120,130-150,180-210; QgSelectFilter.h:35-45; QgSelectFilter.cpp:70-85,90-110,130-150,165-190,210-240; QgSketchFilter.h:35-45; QgSketchFilter.cpp:50-70,80-105,120-145,160-205,220-250,270-305,320-350` | Memory Leaks, NaN Domain Errors, Use-After-Free, Division by Zero, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libqtcad Batch 75 (QgMeasureFilter.h, QgMeasureFilter.cpp, QgPolyFilter.h, QgPolyFilter.cpp, QgSelectFilter.h, QgSelectFilter.cpp, QgSketchFilter.h, QgSketchFilter.cpp, 2,899 lines): in QgMeasureFilter.h, declared virtual destructor in QgMeasureFilter; in QgMeasureFilter.cpp, implemented destructor releasing scene object s, fixed critical logic inversion bug in QgMeasureFilter::angle(bool radians) where radians and degrees were swapped, clamped dot product to [-1.0, 1.0] before acos to prevent NaN domain errors, guarded vector unitization against division by zero with ZERO(mag), added null checks on s after bv_obj_get and cleared s = NULL on reset to prevent use-after-free and null dereferences, guarded v in QMeasure2DFilter::get_point, implemented QMeasure3DFilter destructor to clean and free rt_resource, rtip, and application structures eliminating severe memory leaks (CWE-401), cleaned prior raytrace resources before allocating new ones on prep, guarded ray direction magnitude, and cleaned resources on tree loading failure; in QgPolyFilter.h and QgPolyFilter.cpp, added virtual destructors to base QgPolyFilter and derived classes (QPolyCreateFilter, QPolyUpdateFilter, QPolyMoveFilter) to free bu_ptbl containers bool_objs and move_objs eliminating memory leaks (CWE-401), guarded wp, checked contour existence before indexing contour 0, cleared wp->s_i_data = NULL on freeing unclosed polygon, and guarded bv_create_polygon return, wp->s_v, and wp->s_i_data across event handlers; in QgSelectFilter.h and QgSelectFilter.cpp, declared and implemented virtual destructor in QgSelectFilter to free selected_set with bu_ptbl_free (CWE-401), guarded sset and v in closest_obj_bbox and guarded ray direction unitization against division by zero, guarded v and v->gv_s in QgSelectBoxFilter::eventFilter and prevented division by zero when viewport dimensions are zero, removed debug logging spam, and ensured rt_clean_resource is called before destroying rtip and freeing resp/ap on all paths in QgSelectRayFilter; in QgSketchFilter.h and QgSketchFilter.cpp, added virtual destructor to base QgSketchFilter, guarded output parameters and verified sketch magic in screen_to_uv and snap_vertex_uv, guarded v and es against null in all event filters, verified valid ft_set_edit_mode function pointer before invocation, added bounds check on seg_idx against curve count and deg against RT_EDIT_MAXPARA in sketch_seg_sample, bounded all vertex indices against vert_count, guarded arc direction length against zero in sketch_arc_center_uv, bounded curr_seg and full-circle cs->end in QgSketchArcRadiusFilter, guarded event pointer in QgSketchCursorTracker, and safely extracted curr_seg without null dereference in QgSketchSetTangencyFilter. |
| `SEC-0318` | `include/qtcad/QgGeomImport.h, include/qtcad/QgModel.h, src/libqtcad/QgGeomImport.cpp, src/libqtcad/QgModel.cpp, src/libqtcad/tests/qgmodel.cpp, src/libqtcad/tests/qgview.cpp, src/libqtcad/tests/qsketch.cpp` | `QgGeomImport.h:51,72-137; QgModel.h:343; QgGeomImport.cpp:27-75,78-153,157-246,325-370; QgModel.cpp:90-140,237-275,362-392,485-508,627-680,789-812,883-1025; tests/qgmodel.cpp:78-135,286; tests/qgview.cpp:63-89; tests/qsketch.cpp:247-276,346,454-490,1939,2027-2120` | Memory Leaks, Uninitialized Pointers, Division by Zero, Model Invariant Violations, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libqtcad Batch 76 (QgGeomImport.h, QgModel.h, QgGeomImport.cpp, QgModel.cpp, tests/qgmodel.cpp, tests/qgview.cpp, tests/qsketch.cpp, 1,323 lines): in QgModel.h, initialized rootItem to NULL to prevent uninitialized pointer dereference (CWE-457); in QgModel.cpp, fixed severe memory leak in destructor by iterating through and deleting all QgItem allocations in items before deleting container, freed empty_gvp, and safely deleted gedp->dbi_state before calling ged_close (CWE-401), deleted existing rootItem and cleared items on g_update reset, guarded mdl, gedp, and dbi_state in QgItem_cmp to prevent SIGSEGV crashes during sorting, added comprehensive null checks in QgItem constructor and path_hash, guarded mdl, gedp, dbi_state, and dp in update callbacks, guarded node and index in NodeRow, canFetchMore, and fetchMore, guarded qi, gedp, dbi_state, and ged_gvp in data(), validated argc and argv in run_cmd, verified sender QAction cast and guarded cnode in draw/erase actions, and added bounds and null checks in item expand/collapse handlers; in QgGeomImport.h and QgGeomImport.cpp, explicitly marked constructors and initialized all pointer members to NULL across ASCImportDialog, RhinoImportDialog, and STEPImportDialog (CWE-457), reparented dialog widgets to this for proper Qt memory ownership, deleted out_win in exec_console_app_in_window to prevent persistent dialog leaks (CWE-401), guarded bu_dir return before QString construction, added null checks on dialog UI controls in options(), and fixed critical logic flaw in gfile() where canceling an import dialog still executed the converter by checking dialog.exec() != QDialog::Accepted; in tests/qgmodel.cpp, tests/qgview.cpp, and tests/qsketch.cpp, guarded path_hashes against empty underflow and validated argc/argv with clean help handling in qgmodel, validated argc/argv with clean help handling and corrected argv[1] model path in qgview, and in qsketch validated argc/argv, added clean db_close on error exit paths, guarded nteeth <= 0 in sketch_create_gear to prevent division by zero (CWE-369), verified dp and dbip in QSketchEditWindow constructor, and guarded vertex/segment arrays and view in table population and screenshot methods. |
| `SEC-0319` | `include/tclcad.h, include/tclcad/defines.h, include/tclcad/draw.h, include/tclcad/misc.h, include/tclcad/setup.h, src/libtclcad/tclcad_private.h, src/libtclcad/auto_path.c, src/libtclcad/cmdhist.c, src/libtclcad/command_io.cpp, src/libtclcad/eval.c, src/libtclcad/global.c, src/libtclcad/init.c, src/libtclcad/tests/check_itcl.cpp, src/libtclcad/tests/check_multi_interp.cpp, src/libtclcad/tests/check_tclcad_cmds.cpp` | `include/tclcad/draw.h:178; src/libtclcad/auto_path.c:45-139,201-255; src/libtclcad/cmdhist.c:75-92,94-111,115-184,188-213,217-276,281-302,306-329,333-360,365-401; src/libtclcad/command_io.cpp:48-55,113-132; src/libtclcad/eval.c:33-50,54-66; src/libtclcad/global.c:34-46,49-71,81-87; src/libtclcad/init.c:64-70,72-88,92-97,100-108,110-125,201-209,360-385; tests/check_itcl.cpp:34-45; tests/check_multi_interp.cpp:239-252; tests/check_tclcad_cmds.cpp:36-47` | Stack Out-of-Bounds Read, Memory Leaks, Resource Leaks, Uninitialized Memory, Path Detection Bugs, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libtclcad Batch 77 (include/tclcad.h, include/tclcad/defines.h, include/tclcad/draw.h, include/tclcad/misc.h, include/tclcad/setup.h, tclcad_private.h, auto_path.c, cmdhist.c, command_io.cpp, eval.c, global.c, init.c, tests/check_itcl.cpp, tests/check_multi_interp.cpp, tests/check_tclcad_cmds.cpp, 3,267 lines): in include/tclcad/draw.h, corrected header guard comment from TCLCAD_MISC_H to TCLCAD_DRAW_H; in auto_path.c, fixed critical path detection bugs where ITCL_LIBRARY and ITK_LIBRARY overrides appended filename (itcl.tcl/itk.tcl) and inserted file path instead of directory into auto_path, breaking subsequent file existence checks, fixed itk_set flag never being set to 1, eliminated capturing Tcl error message into paths when tcl_library is unset by replacing unchecked Tcl_Eval with Tcl_GetVar, and added _insert_unique_path helper to deduplicate path entries; in cmdhist.c, fixed severe memory leak of str on all exit paths of tclcad_cmdhist_history (CWE-401), closed fp before error returns to prevent file descriptor leaks, guarded against NULL argv and argv[0], guarded chop and argv[2] in tclcad_cmdhist_add, guarded chop, cho_curr, and BU_LIST boundaries in tclcad_cmdhist_prev/curr/next, guarded chop->cho_curr in cho_cmd before dereferencing, replaced redundant nested BU_LIST_NEXT calls with standard while (BU_LIST_WHILE(...)) dequeue loop in cho_deleteProc, and guarded objects and interp in cho_open/cho_open_tcl; in command_io.cpp, initialized interp to NULL and io_mode to 0 in tclcad_create_io_data eliminating uninitialized struct members (CWE-457), and guarded p->p in tclcad_delete_io_handler to prevent NULL pointer dereference in bu_process_fileno (CWE-476); in eval.c, validated interp and command, guarded args against NULL, and ensured individual argument strings are non-null in tclcad_eval and tclcad_eval_noresult; in global.c, guarded clientData against NULL in tclcad_interp_objects_delete, guarded interp and key in tclcad_interp_objects, and guarded state in tclcad_current_top; in init.c, guarded clientData, interp, and cmds in tclcad_init_state_delete, tclcad_init_state, and tclcad_register_cmds, guarded ctp and ct_func in wrapper_func, guarded filename in tclcad_source_file, verified non-null state in tclcad_init, and fixed critical out-of-bounds stack read (CWE-125) in tclcad_set_argv where !argv caused cast of a single-char stack variable to (const char **) passed into Tcl_Merge, handling empty/non-positive argc cleanly without invalid memory access; in tests/check_itcl.cpp, tests/check_multi_interp.cpp, and tests/check_tclcad_cmds.cpp, validated argv and argv[0] before bu_setprogname/Tcl_FindExecutable and added standard -h/-?/--help usage output with clean exit 0. |
| `SEC-0320` | `src/libtclcad/view/view.h, src/libtclcad/view/arrows.c, src/libtclcad/view/autoview.c, src/libtclcad/view/axes.c, src/libtclcad/view/draw.c, src/libtclcad/view/faceplate.c, src/libtclcad/view/labels.c, src/libtclcad/view/lines.c, src/libtclcad/view/refresh.c, src/libtclcad/view/util.c` | `view.h:26-30,141-177; arrows.c:45-66,82-124,198-212,225-242,282-318; autoview.c:37-58,72-91,96-105; axes.c:41-86,181-197,281-394,456-476,492-517,527-537,595-634,699-725,730-750,757-785; draw.c:42-68,71-125,128-212,238-305,330-350,355-368; faceplate.c:43-65,89-100,128-140,167-179,206-218; labels.c:35-51,55-76,92-117,127-137,235-275,290-305,348-378; lines.c:45-78,92-132; refresh.c:37-60,136-140,149-163,165-177,180-190,195-212,220-230,238-265,270-282,285-296; util.c:41-71` | Memory Leaks, Stack Out-of-Bounds Reads, Uninitialized Memory, Missing Include Guards, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libtclcad Batch 78 (view.h, arrows.c, autoview.c, axes.c, draw.c, faceplate.c, labels.c, lines.c, refresh.c, util.c, 2,912 lines): in view.h, added include guards, C++ extern C wrappers, and extern specifier on to_data_lines; in util.c, guarded gdvp, gdvp->dmp, current_top, and current_top->to_interp in to_is_viewable (CWE-476), initialized result_int to 0 (CWE-457), and prevented Tcl_Obj reference count memory leak on evaluation error by restoring and decrementing saved_result before early return (CWE-401); in autoview.c, fixed out-of-bounds argv[1] read in to_autoview by validating argc < 2 || argc > 3 (CWE-125), guarded tvd, tvd->gedp, current_top, and interp in to_autoview_view, and guarded top, top->to_gedp, and views in to_autoview_all_views; in arrows.c, fixed severe memory leak in points parsing where odd point count returned BRLCAD_ERROR without calling Tcl_Free((char *)av) (CWE-401), guarded current_top->to_gedp->u_data before disabling refresh_on, guarded gedp, gdvp, argv, and interp across go_data_arrows, to_data_arrows, and to_data_arrows_func, and added negative bounds validation on line_width, tip_length, and tip_width; in axes.c, guarded to_axes against argc < 3, NULL gedp, gdvp, gasp, and argv[2], validated non-negative values for axes_size, line_width, tick_interval, tick_length, tick_major_length, and ticks_per_major, guarded current_top, gdvp, and interp across go_data_axes and to_data_axes, and guarded gdvp->gv_s in to_model_axes, go_view_axes, and to_view_axes preventing NULL pointer crashes on uninitialized views (CWE-476); in draw.c, guarded hash table, udata, s_fpath, and dbip in key_matches_paths, guarded tvd->gedp, gedp->u_data, gedp->dbip, and sp->s_os in go_draw_solid, guarded gedp, ged_dl, and sp->s_os in go_draw_dlist, checked gdvp->dmp in go_draw, and in to_edit_redraw guarded dbip, ged_dl, verified !BU_LIST_IS_HEAD before dereferencing sp->s_os, and ensured last_gdlp is not head before dequeue and insert; in faceplate.c, guarded gedp, gdvp, and gdvp->gv_s in to_faceplate, and added RGB color range validation [0, 255] across center_dot, prim_labels, view_params, and view_scale; in labels.c, implemented _free_data_labels helper to safely free all allocated label strings and point buffers on Tcl_SplitList parsing failure, eliminating memory leaks on malformed input lists (CWE-401), guarded current_top, gedp, gdvp, and interp in go_data_labels, to_data_labels, and to_data_labels_func, validated non-negative label size, and in to_prim_label guarded current_top, gedp, and argv, prevented negative list size corruption on argc == 0, and safely reset list when argc == 1; in lines.c, guarded current_top, gedp, gdvp, and argv across go_data_lines and to_data_lines; in refresh.c, guarded gedp, gdvp, dbip, gdvp->gv_s, and current_top in go_refresh_draw, eliminated duplicate dm_draw_viewobjs call, guarded gdvp->u_data and dmp in go_refresh, guarded gdvp, top, and views in to_refresh_view and to_refresh_all_views, guarded gedp and current_top in to_refresh, to_refresh_all, and to_refresh_on, and added NULL checks in to_handle_refresh and to_refresh_handler. |
| `SEC-0321` | `src/libtclcad/bu.c, src/libtclcad/fbserv.c, src/libtclcad/rt.c, src/libtclcad/tkImgFmtPIX.c, src/libtclcad/wrapper.c` | `bu.c:52-56,97-157,172-205,219-251,257-260,333-350,356-373,380-408,414-420,424-441; fbserv.c:45-50,78-98,103-113,116-145,148-156,158-170,173-188,191-201,260-293,297-308,310-322,347-383; rt.c:80-110,114-159,170-200,204-240,244-267,303-336,345-369,378-402,413-433,444-502,516-583,587-621,631-699,702-707,715-737,741-751,755-778,782-792; tkImgFmtPIX.c:148-170,210-286,308-350; wrapper.c:38-83,103-201,210-215,220-234,250-316,368-408` | Type Confusion, Double Free, Premature Object Deallocation, Memory Leaks, Heap Buffer Underflow, Division by Zero, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libtclcad Batch 79 (bu.c, fbserv.c, rt.c, tkImgFmtPIX.c, wrapper.c, 2,388 lines): in tkImgFmtPIX.c, fixed critical type confusion vulnerability in FileWritePIX where Tcl_Obj * format was passed directly into Tcl_AppendResult (which expects const char * strings), causing illegal pointer dereferences and application crashes (CWE-843), guarded format against NULL in FileReadPIX to prevent NULL pointer dereference in Tcl_GetStringFromObj (CWE-476), checked widthPtr and heightPtr before writing in FileMatchPIX, validated image dimensions and pixelSize in FileWritePIX, added integer overflow protection on fileWidth * pixelSize pitch calculation, bounded srcX and srcY, and matched bu_malloc/bu_free allocation labels; in rt.c, eliminated critical double-free / premature object deallocation bugs in tcl_obj_to_int_array and tcl_obj_to_fastf_array where Tcl_DecrRefCount was erroneously called on list elements returned by Tcl_ListObjGetElements (corrupting Tcl object refcounts and causing use-after-free and crash when lists are accessed or freed, CWE-416/CWE-415), fixed severe memory leaks in tcl_list_to_int_array and tcl_list_to_fastf_array by properly incrementing and decrementing the temporary Tcl_Obj wrapper (CWE-401), eliminated division by zero in tclcad_rt_parse_ray by verifying direction vector magnitude with ZERO() macro before unitizing (CWE-369), guarded against array out-of-bounds reads on xyz in tclcad_rt_pr_cutter, replaced undefined variable rayp with NULL in RT_HIT_NORMAL, replaced sprintf/sscanf/atoi with snprintf/bu_sscanf across all command wrappers, and added comprehensive NULL checks on clientData, interp, and argv; in wrapper.c, fixed heap buffer underflow (CWE-125) in to_more_args_func where trimming an empty first element decremented ac_more to 0, causing avmp[ac_more-1] to access avmp[-1], eliminated memory leaks in to_view_func_common and to_dm_func by allocating av only after argument validation, help checks, and view lookup, guarded gdvp->gv_s and gdvp->dmp before accessing view state and setting perspective, guarded tgd and current_top->to_interp, and replaced bu_vls_addr with bu_vls_cstr; in fbserv.c, guarded clientData, fbslp, fbsp, and string pointers in comm_error and new_client_handler, added index bounds checks (0 <= i/sub < MAX_CLIENTS) in open/close client handlers and Windows IPC handlers, validated port range [0, 65535], and replaced unsafe sprintf with snprintf; in bu.c, guarded ctp and ct_func in lwrapper_func, guarded interp and argv in tcl_bu_get_value_by_keyword, prevented string truncation underflow on short lists, replaced raw sscanf with bu_sscanf in color converters, guarded dirkey in _tclcad_bu_dir_print, checked conv_factor with ZERO() macro in tcl_bu_units_conversion, and replaced all bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0322` | `src/libtclcad/bn.c, src/libtclcad/fb.c` | `bn.c:38-42,126-170,185-230,240-275,340-420,440-520,530-580,600-680,690-750,770-850,860-930,940-1010,1020-1090,1100-1170,1180-1250,1260-1374; fb.c:60-95,110-140,165-220,245-290,310-380,410-470,500-560,580-640,660-720,740-800,820-890,900-960,980-1040,1060-1150` | Out-of-Bounds Reads, Memory Leaks, Parameter Swaps, Division by Zero, Integer Overflow / Dimension Guards, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libtclcad Batch 80 (bn.c, fb.c, 2,535 lines): in fb.c, fixed critical out-of-bounds argument vector read in fbo_clear_tcl where argc == 3 erroneously accessed argv[6] instead of argv[2], causing invalid memory reads and segmentation crashes (CWE-125); added integer overflow protection and dimension clamping (<= 32768) in fbo_cell_tcl and fbo_rect_tcl preventing excessive memory allocation and heap buffer overflow (CWE-190/CWE-789); validated rectangle bounds against framebuffer dimensions (xmin + width <= fb_w and ymin + height <= fb_h) in fbo_cell_tcl and fbo_rect_tcl preventing memory corruption outside framebuffer bounds (CWE-125/CWE-787); validated port range (<= 65535) in fbo_listen_tcl and to_listen; corrected return code mapping in fbo_cmd from raw BRLCAD_ERROR to TCL_ERROR; added comprehensive NULL guards on gdvp, tvd, fbop, fbp, interp, gedp, and argv across fbo_coords_ok, fbo_deleteProc, fbo_close_tcl, fbo_clear_tcl, fbo_cursor_tcl, fbo_getcursor_tcl, fbo_refresh_tcl, fbo_listen_tcl, fbo_pixel_tcl, fbo_cell_tcl, fbo_flush_tcl, fbo_getheight_tcl, fbo_getwidth_tcl, fbo_getsize_tcl, fbo_rect_tcl, fbo_configure_tcl, to_fbs_callback, to_close_fbs, to_open_fbs, to_set_fb_mode, and to_listen; replaced unsafe sscanf with bu_sscanf and bu_vls_addr with bu_vls_cstr; in bn.c, fixed swapped parameter bug in tclcad_bn_eigen2x2 where matrix element b was parsed into c and c into b; prevented division by zero in tclcad_bn_mat_lookat by verifying hypot_xy with ZERO() macro before passing to bn_mat_lookat (CWE-369); corrected broken logic in bn_cmd_noise_slice which misread argv indices, discarded loop computations, and fell through to invalid noise types, replacing it with proper index reading, dimension validation (<= 4096), and returning the formatted noise list; fixed memory leak in tclcad_bn_mat_arb_rot on double conversion failure by routing to error label (CWE-401); added missing error messages on bn_decode_vect failures in vector functions; replaced unsafe atof with Tcl_GetDouble in bn_cmd_noise_perlin and bn_cmd_noise; replaced sscanf with bu_sscanf; guarded snprintf buffer sizes; and added comprehensive NULL checks on interp, argv, and clientData across all 35 math command wrappers. |
| `SEC-0323` | `src/libtclcad/polygons.c, src/libtclcad/dm.c` | `polygons.c:45-80,110-180,210-260,310-360,480-530,620-680,810-860,1020-1080,1210-1260,1350-1410,1520-1580,1710-1760; dm.c:140-205,210-240,260-355,380-415,430-485,510-575,600-645,670-800,830-870,900-925,970-1015,1020-1050,1055-1077,1080-1110,1120-1155,1160-1190,1205-1255,1280-1335,1340-1375,1390-1455,1470-1520,1535-1580,1590-1640,1655-1680,1695-1730,1745-1785,1790-1835,1840-1890,1900-1940,1950-2020,2030-2070,2080-2110,2140-2180,2190-2225,2235-2270,2280-2335,2350-2375,2410-2430,2440-2460,2480-2525,2530-2575,2600-2660,2695-2850,2865-2900,2905-2935,2940-2955,3035-3045` | Use-After-Free, Memory Leaks, Buffer Underflow / Out-of-Bounds Reads, Wrong Argument Indexing, Port Range Validation, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libtclcad Batch 81 (polygons.c and dm.c, 4,781 lines): in dm.c, fixed critical use-after-free vulnerability in fb_cmd_common_file_size where dynamic string zerr was passed to Tcl_SetResult with TCL_STATIC and immediately freed with bu_free, leaving Tcl pointing to freed heap memory (CWE-416); fixed critical out-of-bounds argument vector read in dmo_logfile_tcl where argc == 3 erroneously accessed argv[3] instead of argv[2] (CWE-125); guarded out-of-bounds vector reads in error and help handlers across 28 display manager command callbacks; guarded vector index decodes in dmo_parseAxesArgs, dmo_parseDataAxesArgs, and dmo_parseModelAxesArgs; added port range validation (<= 65535) in dmo_listen_tcl; mapped return codes in dmo_cmd from BRLCAD_OK to TCL_OK/TCL_ERROR; replaced sprintf with snprintf; replaced raw atof/atoi with sscanf/bu_sscanf; replaced all bu_vls_addr calls with bu_vls_cstr; added comprehensive NULL checks on dmop, interp, dmo_dmp, and dmo_dmp->i across all 38 display manager routines; in polygons.c, implemented _free_partial_poly and _free_partial_polygon_state cleanup helpers to eliminate severe memory leaks on parse/split failures (CWE-401); freed contour_av on replace_poly success; freed allocated bg_polygon in import; fixed off-by-one out-of-bounds indexing in target_poly (CWE-125); prevented size_t underflow in clip when num_polygons == 0 and state corruption when num_polygons < 2; checked bg_clip_polygon result for NULL; guarded gdvp->dmp, current_top->to_gedp->u_data, current_top->to_interp, and gv_s across all polygon commands; and replaced bu_vls_addr with bu_vls_cstr. |
| `SEC-0324` | `src/libtclcad/mouse.c` | `mouse.c:60-70,85-95,110-120,230-310,320-380,395-440,455-500,530-610,630-655,700-725,770-795,840-865,910-935,970-1040,1050-1120,1130-1170,1260-1360,1380-1490,1510-1590,1660-1730,1740-1840,1890-1980,2000-2080,2100-2215,2250-2275,2285-2310,2320-2390,2400-2425,2435-2460,2475-2530,2540-2565,2575-2600,2615-2715,2730-2755,2765-2790,2805-2890,2995-3050,3060-3135,3150-3225,3255-3315,3325-3400,3415-3450,3470-3550,3560-3645,3660-3740,3750-3830` | Memory Leaks, Uncomputed Model Coordinates Logic Bug, Buffer Overflow / Missing NULL-terminator, Division by Zero, Uninitialized Pointers, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libtclcad Batch 82 (mouse.c, 3,594 lines): fixed critical logic bug in to_mouse_otranslate where model point was declared with VINIT_ZERO and never transformed by the inverse rotation matrix before printing into tran_x_vls, tran_y_vls, tran_z_vls and passing to ged_exec_otranslate (which caused all mouse translations to pass 0, 0, 0); eliminated persistent memory leaks of brep_name and bindings bu_vls on failure paths in to_mouse_brep_selection_append and to_mouse_brep_selection_translate (CWE-401); eliminated memory leaks of joint_name and bindings bu_vls on failure paths in to_mouse_joint_select and to_mouse_joint_selection_translate (CWE-401); fixed buffer allocation and missing NULL terminator in to_mouse_move_bot_pnts where allocating ac elements resulted in av[ac-1] being overwritten by the loop and leaving no NULL termination (CWE-125/CWE-787), allocating ac + 1 and properly terminating; fixed uninitialized gedp->ged_gvp pointer dereference and wrong view rotation matrix inversion in to_mouse_brep_selection_append, to_mouse_joint_select, to_mouse_poly_circ_func, to_mouse_poly_ell_func, to_mouse_poly_rect_func, and to_data_scale (CWE-476); prevented division by zero across to_mouse_constrain_trans, to_mouse_move_arb_edge, to_mouse_move_arb_face, to_mouse_move_bot_pnt, to_mouse_move_bot_pnts, to_mouse_move_pnt_common, to_mouse_oscale, to_mouse_otranslate, TO_COMMON_MOUSE_SCALE, to_mouse_pscale, to_mouse_ptranslate, and to_mouse_trans by clamping width <= 0 to 1 before calculating inv_width (CWE-369); corrected error messages in to_mouse_constrain_rot and to_mouse_constrain_trans on invalid axis; guarded wdbp returned from wdb_dbopen in to_mouse_move_bot_pnt; guarded gdvp->dmp in to_mouse_rect before calling dm_get_height; guarded current_top, current_top->to_interp, current_top->to_gedp, and u_data across all callback executions and polygon functions; and modernized all (~38) bu_vls_addr calls to bu_vls_cstr. |
| `SEC-0325` | `src/libtclcad/commands.c` | `commands.c:30-40,85-115,140-155,170-195,250-280,310-330,340-360,540-565,650-675,700-725,830-860,1110-1135,1190-1225,1245-1270,1315-1340,1400-1425,1460-1490,1540-1580,1650-1685,1770-1815,1900-1940,2010-2050,2130-2165,2215-2240,2290-2340,2460-2495,2570-2640,2680-2715,2760-2830,2870-2900,3110-3160,3320-3360,3410-3445,3550-3580,3690-3740,3810-3840,3920-3950,4040-4075,4160-4190,4280-4320,4410-4445,4550-4585,4670-4710,4800-4840,4950-5030,5040-5140,5170-5240,5260-5300,5320-5360,5370-5385,5390-5415,5430-5450,5480-5525,5540-5585,5600-5645,5660-5705,5750-5795,5810-5845,5860-5895,5910-5940,5960-6010,6020-6045,6050-6075,6090-6130,6145-6180,6195-6225,6235-6285,6295-6340,6350-6390,6400-6450,6460-6545,6555-6600,6610-6655,6665-6700,6705-6715,6720-6730,6735-6750,6755-6765,6770-6840` | Inverted Logic / Crasher, Resource Leaks, Buffer Overflow / Unchecked sprintf, Division by Zero, Type Confusion, Memory Leaks, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libtclcad Batch 83 (commands.c, 6,748 lines): completing all 31 files of src/libtclcad (100% complete): fixed critical inverted logic bug in to_pix where dm_make_current returning BRLCAD_OK (0) was treated as failure via !make_ret and aborted; fixed persistent resource leaks of PNG write structures in to_png on error and exit paths by properly invoking png_destroy_write_struct; fixed memory leak of callback_cmd bu_vls in to_rt_end_callback_internal; fixed severe buffer overflow vulnerability and memory leak in to_dplot where fixed stack buffer av[256] lacked bounds check on split list length, had an off-by-one indexing error on NULL terminator, and leaked memory on Tcl_Eval failure; fixed type confusion bug in free_path_edit_params by using correct struct dm_path_edit_params; fixed division-by-zero vulnerabilities in to_bounds, to_data_move_func, to_data_pick_func, to_view2screen, and to_vslew by validating clip boundaries and clamping non-positive width/height before computing scale factors and aspect ratios; prevented negative array indexing in to_make, to_mirror, to_bot_edge_split, and to_bot_face_split by enforcing argument count bounds; preserved ged_exec command output in to_bot_edge_split and to_bot_face_split before invoking redraw; replaced unchecked sprintf with snprintf in to_vmake; added NULL pointer guards across all commands validating gedp, gdvp, dmp, dbip, current_top, to_gedp, and to_interp; and modernized all (~60) bu_vls_addr calls to bu_vls_cstr. |
| `SEC-0326` | `src/libicv/asciiart.cpp, src/libicv/bw.c, src/libicv/color_space.c, src/libicv/crop.c, src/libicv/dpix.c, src/libicv/encoding.c, src/libicv/icv_private.h, src/libicv/operations.c, src/libicv/pix.c, src/libicv/ppm.c, src/libicv/stat.c` | `asciiart.cpp:34-51; bw.c:33-100,104-177,180-215; color_space.c:38-78,81-194; crop.c:41-86,98-167; dpix.c:63-108,112-161,165-204,207-237,240-275; encoding.c:33-51,55-115; icv_private.h:20-30; operations.c:40-59,61-81,83-102,104-126,128-148,150-179,181-210,212-241,244-273,275-314,316-385; pix.c:34-67,70-100,103-167,170-211; ppm.c:36-78,81-144,147-196,214-226,228-291; stat.c:31-45,49-74,78-102,106-129,133-148,152-176,180-209,213-242,246-277,281-297` | Division by Zero, Premature Dereference / NULL Pointer Crashes, Integer Overflow on Dimensions & Buffers, Out-of-Bounds Reads, and Unhandled Floating-Point NaNs | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libicv Batch 84 (asciiart.cpp, bw.c, color_space.c, crop.c, dpix.c, encoding.c, icv_private.h, operations.c, pix.c, ppm.c, stat.c, 2,400 lines): in stat.c, fixed critical premature NULL dereference in icv_hist where img->width and img->data were accessed prior to the ICV_IMAGE_VAL_PTR(img) check (CWE-476); eliminated multiple division-by-zero vulnerabilities in icv_mean, icv_var, and icv_skew when image width/height are zero (CWE-369); guarded against NULL bins, zero n_bins, and zero channels across all statistical routines; prevented out-of-bounds reads and NaN propagation in icv_max, icv_min, and icv_sum; in operations.c, fixed premature NULL dereference in icv_add_val by checking ICV_IMAGE_VAL_INT before accessing img->data; prevented division-by-zero crashes in icv_divide_val and icv_divide; fixed multi-channel desynchronization / out-of-bounds corruption in icv_saturate by advancing by img->channels instead of hardcoded 3; guarded img dimensions and scale factors against division by zero in icv_fit; in crop.c, fixed division-by-zero crash in icv_crop when img->channels is zero; added integer overflow checks on row byte calculations in icv_crop_rect and icv_crop (CWE-190); in color_space.c, guarded against out-of-bounds reads in icv_rgb2gray when channels < 3 (CWE-125); added integer overflow protection on dimensions and buffer allocations in icv_gray2rgb and icv_rgb2gray; in encoding.c, guarded against NULL data and integer overflows in icv_uchar2double and icv_data2uchar, and prevented division-by-zero and domain errors on negative or zero gamma; in dpix.c, safely handled NaNs/Infs during normalization to prevent divide-by-zero and infinite loops, replaced raw POSIX read/write with stdio fread/fwrite to eliminate short-read and buffering bugs, and added integer overflow validation on sample counts; in pix.c and bw.c, guarded against NULL data conversion pointers, checked dimensions against size_t overflow, eliminated truncation from int casts, and checked realloc limits on stream reads; in ppm.c, clamped RGB float values before lrint to avoid undefined integer conversions, replaced sprintf with snprintf for PPM headers (CWE-120), guarded against numeric overflow in parse_ppm_int, and validated buffer limits in ppm_read_mem; in asciiart.cpp, validated image pointer, data, channels, dimensions, and brightness multiplier; and in icv_private.h, properly positioned include guards. |
| `SEC-0327` | `src/libicv/fileformat.c, src/libicv/filter.c, src/libicv/jpeg.c, src/libicv/pixcii.hpp, src/libicv/rot.c, src/libicv/size.c` | `fileformat.c:179,211,273-286,341,380-401,407-427,647-653,683-690; filter.c:38-40,133-135,322-345,385-405,455-480; jpeg.c:54-55,80-84,117-120,141-145,171-177,212-215,238-241,250-255,263-268,284-289,310-313,332-337,358-363,383-386; pixcii.hpp:78-96,125-157,162-171; rot.c:98-115,130-136,150-153,292-295,355-385,392; size.c:181-190,220-247,309-354,368-395,401-411` | Division by Zero, Resource & Memory Leaks, NULL Pointer Dereference, Setjmp/Longjmp Undefined Behavior, Integer Overflow on Dimensions & Buffers, and Out-of-Bounds Access | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libicv Batch 85 (fileformat.c, filter.c, jpeg.c, pixcii.hpp, rot.c, size.c, 2,925 lines): in fileformat.c, fixed memory leak of ofilename on validation failure and fopen error paths in icv_write (CWE-401); prevented closing stdin on unsupported format; guarded against NULL bif->data, 0 width/height/channels, and integer overflows in icv_write, icv_write_mem, icv_writeline, and icv_writepixel; added NULL data check in icv_zero and invalidated magic in icv_destroy to prevent use-after-free; in jpeg.c, declared setjmp-lived pointers volatile to eliminate undefined behavior across longjmp; checked icv_data2uchar return values against NULL before scanline processing; eliminated memory leak of libjpeg buffer mem_buf on write failure; guarded dimensions against 0/invalid sizes and checked double-converted buffer allocations in jpeg_read and jpeg_read_mem; in rot.c, guarded argc/argv before calling bu_setprogname; validated pixel size, square size, and width/height options with strtol; set stdout to binary mode for piping binary image streams on Windows; added integer overflow checks on scanline bytes and buffer allocations in arbrot and icv_rot; hardened arbrot coordinates to size_t; supported negative rotation angles via !ZERO(angle); in size.c, guarded icv_image_size against NULL widthp/heightp and zero unit conversions; guarded shrink_image and under_sample against NULL image data, 0 channels, and integer overflows on realloc; removed truncating int casts on dimensions; prevented division by zero in resize_output_valid; in filter.c, validated kernel and offset pointers in get_kernel and get_kernel3; guarded icv_filter, icv_filter3, and icv_fade against NULL data, 0 channels/dimensions, NaN fraction multipliers, and integer overflows; and in pixcii.hpp, guarded against empty ascii character maps, handled NaN brightness boosts, converted signed int pixel indexing to size_t with overflow guards, and clamped double pixel color values safely. |
| `SEC-0328` | `src/libicv/PImgHash.cpp, src/libicv/PImgHash.h, src/libicv/diff.cpp, src/libicv/diff_approx.cpp, src/libicv/png.cpp` | `PImgHash.cpp:51-57,134-137,216-224,241-255,265-285; PImgHash.h:66,81,87,130,145,151,164-190,224-239,287-325; diff.cpp:177-185,193,210-215,320-333,358-370,408-445,459-482,492,525; diff_approx.cpp:51-70,75-81,135-146,176-177,217; png.cpp:198-203,219,228-232,287-302,320-324,346-350,392,459-468,523-529,548,563,586-590,668-675,685` | Division by Zero, Setjmp/Longjmp Undefined Behavior, Resource & Memory Leaks, Buffer Bounds & Out-of-Bounds Reads, Integer Overflow on Dimensions & Buffers, and Undefined Float-to-Int Conversions | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libicv Batch 86 (PImgHash.cpp, PImgHash.h, diff.cpp, diff_approx.cpp, png.cpp, 2,233 lines): in png.cpp, validated bif pointer, bif->data, dimensions, and channels in png_write and png_write_mem; declared setjmp-spanning local pointers volatile to prevent undefined behavior across longjmp (CWE-398); eliminated memory leak of converted pixel buffer data on write errors and used icv_destroy in setjmp handlers to prevent leaks of bif->render_info (CWE-401); prevented integer overflow in user_read_data bounds calculation (CWE-190); validated rowbytes against width * 3 in png_read to prevent heap out-of-bounds writes (CWE-122); validated rowbytes and buffer allocations in png_read and png_read_mem; in diff.cpp, guarded write_nirt_shots_for_ri against division by zero on aspect, width, height, and viewsize (CWE-369); guarded icv_diff_nirt_shots against NULL data, mismatched channel counts (< 3), and buffer allocation overflow; prevented heap out-of-bounds reads in icv_diff by indexing per-image channel counts instead of hardcoded 3 and guarded against signed integer overflow on off_by_many; validated 3-channel input, integer overflow on dimensions, and clean buffer freeing in icv_diffimg; in diff_approx.cpp, made load_icv static, guarded against NULL data, unsigned underflow when rows == 0, and integer overflow; validated image pointers and dimensions in pdiff_dct; guarded ssim_calc against NULL data, zero dimensions/channels, and sanitized non-finite NaN/Inf pixel values; in PImgHash.cpp and PImgHash.h, clamped float pixel values to [0.0, 1.0] with NaN check in convert_pix to prevent undefined float-to-int cast conversions (CWE-190/CWE-681); guarded DCTHasher::apply against zero dimensions; prevented out-of-bounds vector writes in tile_size when b == 0 or j >= b; guarded Preprocess::start and Preprocess::stop against division by zero and out-of-bounds histogram access; prevented NULL pointer dereferences and integer overflows in Image class; and guarded resize_row, resize, and add_row against division by zero on tile size. |
| `SEC-0329` | `src/libicv/anim.cpp, src/libicv/apngmini.hpp, src/libicv/rle.cpp, src/libicv/rle.hpp` | `anim.cpp:115-155,238-265,286-290,320-341,446-494,519-523,539-550,589-638; apngmini.hpp:539-548,577-612,647-650,700-705,760-766,775-790,1060-1085,1122-1135,1152-1158,1322-1335,1346-1350,1423-1433; rle.cpp:42-47,222-230,246-254,277-289,301-309,327-338; rle.hpp:235-245,941-965,983-990,1015-1020,1050-1055,1096-1100,1133-1138` | Integer Overflow on Dimensions & Buffers, Unsigned Underflow, Heap Buffer Overflows & Overreads, CPU Exhaustion DoS, Undefined Float Conversions, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libicv Batch 87 (anim.cpp, apngmini.hpp, rle.cpp, rle.hpp, 3,778 lines): in anim.cpp, validated bif pointer, bif->data, dimensions, and channels in icv_to_apng preventing heap out-of-bounds reads on unexpected channel layouts (CWE-125); clamped float pixel values in float_to_u8 with std::isfinite check to prevent undefined float-to-uint8 cast conversions (CWE-190/CWE-681); guarded read_mjpeg_avi against chunk size underflow and unbounded memory allocation (CWE-191/CWE-400); guarded write_mjpeg_avi against 32-bit integer arithmetic overflows on data rate, frame bytes, and index blocks; validated image pointers and non-empty dimensions across icv_anim_write, icv_anim_add_frame, icv_anim_insert_frame, icv_anim_replace_frame, and icv_anim_get_frame; in apngmini.hpp, enforced maximum pixel limits, non-zero dimensions, and rowbytes buffer bounds in LibpngBackend decode/encode routines; guarded write_chunk against size_t overflow; ensured valid pixel bounds and buffer sizes before cropping and over-compositing; eliminated unsigned underflow and heap buffer corruption during background disposal in Animation::compose when frame.x_offset >= canvas_width (CWE-191/CWE-122); guarded chunk peeking against integer overflow and enforced minimum 4-byte length on fdAT chunks; capped maximum file read size to 512MB in read_file; in rle.cpp, sanitized double-to-uint8 conversions in dbl_to_u8 against non-finite NaN/Inf values; validated image data and dimensions in rle_write and rle_write_mem; guarded memory stream buffer allocation; in rle.hpp, implemented a per-row opcode counter in Decoder::read to prevent CPU exhaustion DoS attacks (CWE-400); clamped scanline and pixel skips to image boundaries to prevent unsigned integer wrap-around and out-of-bounds buffer writes (CWE-122/CWE-190); validated image buffer capacity before colormap transformations; ensured non-null buffer and positive dimensions in write_rgb; and prevented integer overflow in MemReadStream::tell. |
| `SEC-0330` | `src/libicv/tests/apngmini.cpp, src/libicv/tests/demo.c, src/libicv/tests/fileformat.c, src/libicv/tests/icv_diff_test.c, src/libicv/tests/icv_png_json_test.cpp, src/libicv/tests/pimghash.cpp, src/libicv/tests/rle.cpp, src/libicv/tests/robustness.c` | `apngmini.cpp:45-55,83-93,138-144,157-165; demo.c:49-75,104-106,120-122,153-163,187-195,220-235,240-252; fileformat.c:48-58,92-95,151-155; icv_diff_test.c:63-75,85-93,112-118,137-145,238-245,304-320,333-339,392-405,486-499,532-550,572-576; icv_png_json_test.cpp:94-105,131-185,204-208,319-323,412-416,462-466; pimghash.cpp:48-52,222-232,235-240; rle.cpp:104-125,134-138,187-210,686-695,738-745,760-770,1605-1610; robustness.c:60-148,654-690,1111-1185,1211-1220,1339-1342` | Memory Management Mismatch, Unchecked Vector & Buffer Bounds, Temporary File Leaks, Unbounded Allocation & Integer Overflows, Division by Zero, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libicv Batch 88 (tests/apngmini.cpp, tests/demo.c, tests/fileformat.c, tests/icv_diff_test.c, tests/icv_png_json_test.cpp, tests/pimghash.cpp, tests/rle.cpp, tests/robustness.c, 4,882 lines, completing src/libicv to 100%): in rle.cpp, resolved allocator mismatch (CWE-762) by changing create_test_image from libc calloc to bu_calloc to match bu_free in free_test_image; guarded against arithmetic overflow in image data size calculation; added null data checks in pixels_match; ensured temporary test files in rle_roundtrip, test_write_invalid_channels, and test_write_oversized_dimensions are deleted on error and completion; and exercised null file stream handling in test_invalid_file; in apngmini.cpp, validated frame dimensions in make_frame to prevent integer overflow and excessive allocation; verified vector bounds before indexing composed frame pixels to prevent out-of-bounds reads (CWE-125); and ensured roundtrip temporary files are deleted via RAII cleanup; in demo.c, validated image creation and buffer allocations in demo_rgb and prevented division by zero when dimensions sum to zero; guarded against dimension overflow and null pointers in clone_image; added null checks across demo_memory_io, demo_file_io, demo_crop_filter_ascii, and demo_diffs; and ensured temporary animation test files are cleaned up unconditionally; in fileformat.c, validated image data allocation in make_pixel and guarded path parameter in write_auto_pix; in icv_diff_test.c, validated dimensions and arithmetic overflow in make_solid; added null data checks in test_icv_diff_counts and test_icv_diffimg_colors; and validated render_info pointers before dereferencing in test_png_metadata_roundtrip, test_diff_render_info, and test_nirt_shots; in icv_png_json_test.cpp, validated dimensions and data pointers in make_solid; capped maximum file read size to 100MB in png_read_text_chunk; guarded chunk parsing against 32-bit integer overflow; and verified render_info allocations before dereferencing; in pimghash.cpp, sanitized floating-point comparisons with std::isfinite in nearly_equal; and checked vector size before indexing hash bytes in test_hashing; in robustness.c, validated dimensions and memory allocations across all make_* helper functions; prevented division by zero in make_unit_rgb; checked statistics pointers (minv, maxv, sumv, meanv, bins, mode, median, var, skew) for null before access in test_crop_filters_and_stats; and guarded metadata and frame allocations in test_ascii_render_info_and_diff and test_animation_frame_management; and across all test harnesses, safely validated argc > 0 && argv && argv[0] before calling bu_setprogname. |
| `SEC-0331` | `src/libnmg/bool.c, src/libnmg/ck.c` | `bool.c:165-215,220-245,260-290,440-475,540-580,660-685,730-845,860-930; ck.c:60-700,708-735,740-755,760-833,870-882,885-905,908-940,976-994,1008-1028,1031-1082,1104-1149,1159-1205,1217-1244,1285-1339,1357-1375,1394-1493,1506-1540,1551-1563,1577-1627,1643-1678,1682-1710` | Buffer Overlapping Undefined Behavior, Stack & Heap Buffer Truncation / Overflow, Division by Zero, Unsigned Integer Underflow, Memory Leaks, Dangling / Unchecked Pointers, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libnmg Batch 89 (bool.c, ck.c, 2,801 lines): in ck.c, resolved critical undefined behavior (UB) and buffer corruption across all topological consistency check routines (nmg_ck_e, nmg_ck_vu, nmg_ck_eu, nmg_ck_lg, nmg_ck_l, nmg_ck_lu, nmg_ck_fg, nmg_ck_f, nmg_ck_fu) by replacing unsafe fixed-length heap allocations and overlapping snprintf calls (where the destination buffer was also passed as the %s source argument) with dynamically sized struct bu_vls formatting; fixed CWE-369 division-by-zero vulnerability in nmg_ck_eg_verts by guarding edge direction magnitude against zero before calling VUNITIZE; eliminated NULL pointer dereferences when logging or checking without parent strings by guarding string pointers; in nmg_ck_lueu, fixed backward/forward edge logging mismatch bug, corrected routine name typo in logs, and guarded circular list navigation against empty list heads; hardened all 17 nmg_v* validator routines (nmg_vvg, nmg_vvertex, nmg_vvua, nmg_vvu, nmg_veg, nmg_vedge, nmg_veu, nmg_vlg, nmg_vloop, nmg_vlu, nmg_vfg, nmg_vface, nmg_vfu, nmg_vsshell, nmg_vshell, nmg_vregion, nmg_vmodel) with comprehensive NULL checks, magic identification guards, and coordinate validation; in nmg_eu_2s_orient_bad, guarded radial and mate pointers during circular traversal; in nmg_ck_closed_surf and nmg_ck_closed_region, checked pointer validity before recursive verification; in nmg_ck_v_in_2fus and nmg_ck_vs_in_region, ensured vertex geometry and model pointers are valid and sanitized visited array allocation against negative or zero maxindex; in bool.c, guarded nmg_plot_open_edges against NULL magic, checked vertex coordinate pointers, and ensured plot_file_name bu_vls is unconditionally freed at exit; validated model and shell pointers in nmg_has_dangling_faces; eliminated unsigned integer underflow vulnerability in nmg_kill_anti_loops during loop deletion; safely bounded buffer formatting in nmg_show_each_loop; guarded edgeuse mate pointers in nmg_classify_shared_edges_verts; removed obsolete #if 0 dead code block; ensured bounding boxes exist before disjoint tests in nmg_bool; and guarded model maxindex against non-positive sizes before calloc/memcpy in boolean evaluation. |
| `SEC-0332` | `src/libnmg/class.c, src/libnmg/copy.c` | `class.c:337-343,366-390,485-584,588-592,648-656,860-935,1292-1410,1546-1570,1630-1725,1780-1825,2032-2135,2345-2440; copy.c:38-51,54-72,77-107,110-130,132-192,195-247,250-278,280-320,323-355,357-390,393-425,427-447,449-479,482-566,574-590,593-614,617-680,682-727,729-745,748-815,821-869` | Off-by-One Heap Buffer Overflows, Union Type Confusion, Division by Zero, Broken Radial Circular Loops, Dead Code Blocks, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libnmg Batch 90 (class.c, copy.c, 3,392 lines): in copy.c, resolved critical off-by-one heap buffer overflow in nmg_clone_model by allocating maxelem = original->maxindex > 0 ? (size_t)original->maxindex + 1 : 1 instead of original->maxindex, preventing out-of-bounds writes and corruptions when elements with index == maxindex are cloned; introduced safe index-checked structArray accessor helpers get_struct and set_struct validating index >= 0 && (size_t)index < maxelem; fixed union type confusion in nmg_construct_face where case NMG_FACE_G_SNURB_MAGIC accessed original->g.plane_p->index instead of original->g.snurb_p->index; hardened all 20 structure constructors (nmg_construct_region_a, nmg_construct_region, nmg_construct_face_g_plane, nmg_construct_face_g_snurb, nmg_construct_face, nmg_construct_vertex_g, nmg_construct_vertex, nmg_construct_vertexuse_a_plane, nmg_construct_vertexuse_a_cnurb, nmg_construct_vertexuse, nmg_construct_edge, nmg_construct_edge_g_lseg, nmg_construct_edge_g_cnurb, nmg_construct_edgeuse, nmg_construct_loop_a, nmg_construct_loop, nmg_construct_loopuse, nmg_construct_faceuse, nmg_construct_shell_a, nmg_construct_shell) with input NULL checks, safe structArray index bounds validation, and non-null child insertion guards; validated knot vector sizes (u.k_size, v.k_size, k_size) and ctl_points array allocations before copying in SNURB and CNURB constructors; removed dead unused tolerance variable in nmg_clone_model; in class.c, fixed CWE-369 division-by-zero vulnerability in nmg_class_pnt_e by checking MAGSQ(ptvec) < SMALL_FASTF before calling VUNITIZE; eliminated off-by-one heap underallocations in nmg_class_pnt_e debug plot bits buffer, nmg_class_pnt_s faces_seen array, and class_lu_vs_s b buffer by allocating (size_t)maxindex + 1; replaced unsafe sprintf calls with snprintf across debug plot generators; deleted two large obsolete #if 0 dead code blocks (~200 lines: nmg_class_lu_fu and nmg_get_interior_pnt); guarded against NULL shell attributes (s->sa_p) before bounding box dereferences in nmg_class_pnt_s, class_eu_vs_s, and nmg_classify_s_vs_s by ensuring attributes via nmg_shell_a; hardened radial and mate pointer cycles against NULL dereference and infinite loops in class_eu_vs_s, class_shared_lu, and class_lu_vs_s; and prevented crashes and type confusion on empty or vertex loops in class_shared_lu and nmg_classify_s_vs_s by validating list emptiness, checking child magic, and ensuring vertex geometry pointers are non-null. |
| `SEC-0333` | `src/libnmg/eval.c, src/libnmg/extrude.c` | `eval.c:43-52,89-125,203-275,282-355,435-460,505-525,535-555,568-605,608-625,630-660; extrude.c:45-68,75-84,90-170,180-255,263-289,298-388,505-778,827-918,930-1090,1148-1328,1347-1524` | Heap Buffer Overflows / OOB Writes, Memory Leaks, Copy-Paste Edge Intersection Defects, Denial of Service / Aborts, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libnmg Batch 91 (eval.c, extrude.c, 2,024 lines): in extrude.c, resolved critical Cat 1 heap buffer overflow / OOB write vulnerabilities (CWE-122 / CWE-787) in nmg_hollow_shell and nmg_extrude_shell by allocating maxelem = (m->maxindex > 0) ? (size_t)m->maxindex + 1 : 1 instead of m->maxindex, preventing memory corruption when elements with index == maxindex are processed by NMG_INDEX_TEST_AND_SET; fixed critical copy-paste bug in nmg_fix_overlapping_loops where edge splitting on intersection endpoints incorrectly referenced eu2 instead of eu1 on dist[0] == 1.0, and nmg_esplit was erroneously confined to the interior-only else branch, leaving crossing edges completely unsplit when touching existing vertex endpoints; fixed multiple persistent memory leaks: loop_tab allocations in nmg_fix_overlapping_loops when tables were empty, outfaces in nmg_extrude_face on early error returns, and the verts table in nmg_extrude_shell when vertex recalculation failed before out: (CWE-401); replaced fatal bu_bomb abort in nmg_extrude_face on parallel extrusion with graceful error return (-1) and moved angle calculation before nmg_dup_face to prevent orphaned/leaked duplicated geometry; added loop bounds and magic number validation in nmg_start_new_loop to guard against infinite loops and type confusion; hardened verts_in_nmg_loop, verts_in_nmg_face, nmg_translate_face, nmg_find_vertex_in_lu, nmg_break_crossed_loops, and nmg_extrude_cleanup with comprehensive NULL checks, empty loop guards, and coordinate validation; in eval.c, hardened nmg_eval_action with classification table bounds checking (bs_maxindex) to prevent negative array indexing or heap out-of-bounds reads (CWE-125); added NULL guards, parent magic verification, and planar face geometry checks in nmg_ck_lu_orientation to avoid illegal dereferences on non-faceuse parents or SNURB faces; hardened nmg_eval_shell against crashing on empty loops or malformed wire edgeuse parents in BACTION_KILL; replaced unsafe sprintf with snprintf in debug plot file naming; and replaced fatal bu_bomb on plot file write failure with a non-fatal bu_log warning. |
| `SEC-0334` | `src/libnmg/fcut.c` | `fcut.c:64-100,105-180,230-310,345-420,430-490,500-680,685-780,785-840` | Stack & Heap Uninitialized Memory / Sizeof Pointer, Persistent Memory Leaks, Division by Zero, Unsigned Underflow, Dead Code Elimination, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libnmg Batch 92 (fcut.c, 3,809 lines): in nmg_face_rs_init, resolved critical Cat 1 sizeof-pointer memory initialization defect (CWE-467) where memset((char *)rs, 0, sizeof(rs)) only zeroed 8 bytes (pointer size) leaving the remaining 90% of the nmg_ray_state structure filled with uninitialized stack memory; resolved multiple persistent memory leaks (CWE-401) in find_loop_to_cut and nmg_fcut_face where dynamically allocated struct loop_cuts objects in the cuts table were removed via bu_ptbl_rm or left in cuts when freeing the table without ever calling bu_free; fixed CWE-369 division-by-zero vulnerabilities across VUNITIZE calls on rs->left in nmg_face_rs_init, x_dir and y_dir in find_loop_to_cut, and x_dir and y_dir in nmg_eu_angle by guarding vector magnitude against zero before normalization; fixed CWE-191 unsigned integer underflow and infinite loop vulnerability in ptbl_vsort bubble sort loop bounds by using safe i + 1 < b->end comparison; eliminated type confusion crashes on lone vertex loops in find_best_vu by verifying parent magic (*vu->up.magic_p == NMG_EDGEUSE_MAGIC) before treating parents as edgeuses; eliminated out-of-bounds pointer reads and potential null dereferences in nmg_fcut_face traversal loops (prior_start, prior_end, next_end) by enforcing array bounds against rs->nvu; guarded ptbl_vsort against division by zero on dist_tol <= 0; added retry iteration limits and safe return paths in nmg_ck_vu_ptbl and nmg_face_cutjoin to prevent infinite loops; restored active exported implementations of nmg_sanitize_fu and nmg_wedge_class from dead code blocks; replaced fatal bu_bomb aborts across active routines with error logging and graceful failure returns; and eliminated ~2,500 lines of obsolete #if 0 dead code blocks from 1993/2017. |
| `SEC-0335` | `src/libnmg/fuse.c` | `fuse.c:127-160,297-343,355-401,413-552,556-620,624-658,778-894,906-1025,1044-1157,1180-1382,1398-1491,1702-1765,1784-1872,2013-2074,2158-2328,2401-2500,2544-2656,2665-2799,2863-2928,3081-3175,3183-3305` | Persistent Memory Leaks, Division by Zero, Control Point Misalignment, Infinite Loops, Denial of Service / Aborts, and NULL Pointer Dereferences | 2 | `CONFIRMED` | `FIXED` | In BRL-CAD libnmg Batch 93 (fuse.c, 3,468 lines): resolved multiple persistent memory leaks (CWE-401) by freeing dynamic sort_idx_xyp allocation in nmg_edge_g_fuse which was previously never deallocated, freeing etab table on zero-count exit in nmg_edge_g_fuse, and freeing tmp table on empty-length exits in nmg_vertex_fuse and nmg_edge_fuse; fixed control points stride misalignment and buffer bounds defects in nmg_cnurb_is_linear (CWE-125 / CWE-129) where ctl_points was indexed by i instead of i * coords and compared using 3D VEQUAL instead of dimension-aware coords comparisons with EQUAL macro, as well as fixing the loop upper bound to cnrb->c_size - 1; fixed multiple CWE-369 division-by-zero vulnerabilities: guarded rise-over-run slopes (dx and dy) in nmg_edge_g_fuse across XY, XZ, and YZ planes, guarded srf->s_size[0] * srf->s_size[1] <= 0 and plane normal magnitude MAGSQ(pl) <= SMALL_FASTF in nmg_snurb_is_planar, and guarded rational weights (xyz1[coords-1] and uvw[coords-1]) in nmg_eval_linear_trim_curve and nmg_eval_trim_curve; fixed potential infinite loop hangs (CWE-835) in nmg_radial_implement_decisions and nmg_do_radial_join by adding pass progress tracking (progress++) to prevent infinite looping when skipped elements make no forward progress; eliminated 43 fatal bu_bomb aborts (CWE-400 / DoS) across topological fusing, crack classification, and radial edge joining (nmg_region_v_unique, nmg_vertex_fuse, nmg_snurb_is_planar, nmg_split_trim, nmg_cnurb_lseg_coincident, nmg_cnurb_is_on_crv, nmg_edge_fuse, nmg_ck_fu_verts, nmg_break_all_es_on_v, nmg_radial_verify_pointers, nmg_radial_verify_monotone, nmg_radial_build_list, nmg_is_crack_outie, nmg_find_radial_eu, nmg_radial_mark_cracks, nmg_radial_find_an_original, nmg_radial_mark_flips, nmg_radial_join_eu_NEW), replacing them with informative error/debug logging and graceful non-fatal fallback returns; and hardened against NULL pointer dereferences and out-of-bounds reads (CWE-476 / CWE-125) in nmg_edge_fuse, nmg_edge_g_fuse, nmg_break_all_es_on_v, nmg_break_e_on_v, and radial utilities with comprehensive parameter validation and geometry checks. |
-465
View File
@@ -1,465 +0,0 @@
# BRL-CAD RMF/STIG Cat 1 Security Audit Dashboard
**Last Updated:** 2026-10-04 17:30:00 UTC
## Overall Progress
- **Total C/C++ Files:** 3493
- **Files Reviewed:** 1595 (45.7%)
- **Files Pending Review:** 1898
- **Total Issues Identified:** 356
### Issues by Severity Potential
| Severity Level | Count | Description |
|:---:|:---:|:---|
| **3 (High)** | 23 | Likely exploit or crash potential; widespread/library exposure |
| **2 (Medium)** | 281 | Possible exploit or crash under specific circumstances |
| **1 (Low)** | 52 | Localized / low-impact vulnerability |
### Issues by Verification Status
- **Confirmed:** 0
- **Fixed (Committed):** 356
- **Pending Verification:** 0
- **Disproven:** 0
## Subsystem Review Progress
| Subsystem | Total Files | Reviewed | Progress | Issues Found |
|:---|:---:|:---:|:---:|:---:|
| `bench` | 5 | 5 | 100.0% | 1 |
| `doc` | 19 | 0 | 0.0% | 0 |
| `include` | 315 | 34 | 10.8% | 8 |
| `misc` | 55 | 0 | 0.0% | 0 |
| `regress` | 21 | 0 | 0.0% | 0 |
| `src/adrt` | 51 | 0 | 0.0% | 0 |
| `src/archer` | 1 | 0 | 0.0% | 0 |
| `src/art` | 6 | 6 | 100.0% | 1 |
| `src/brlman` | 1 | 0 | 0.0% | 0 |
| `src/bwish` | 3 | 3 | 100.0% | 1 |
| `src/conv/3dm` | 1 | 0 | 0.0% | 0 |
| `src/conv/asc` | 5 | 0 | 0.0% | 0 |
| `src/conv/bot_dump.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/comgeom` | 7 | 0 | 0.0% | 0 |
| `src/conv/conv-vg2g.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/csg` | 2 | 0 | 0.0% | 0 |
| `src/conv/dbupgrade.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/dxf` | 3 | 0 | 0.0% | 0 |
| `src/conv/enf-g.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/fast4-g.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-acad.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-dot.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-egg.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-nff.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-obj.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-shell-rect.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-var.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-vdb.cpp` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-voxel.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-vrml.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-x3d.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-xxx.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g-xxx_facets.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g4-g5.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/g5-g4.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/gcv` | 1 | 0 | 0.0% | 0 |
| `src/conv/gltf` | 1 | 0 | 0.0% | 0 |
| `src/conv/iges` | 2 | 0 | 0.0% | 0 |
| `src/conv/intaval` | 8 | 0 | 0.0% | 0 |
| `src/conv/jack` | 2 | 0 | 0.0% | 0 |
| `src/conv/k-g` | 19 | 0 | 0.0% | 0 |
| `src/conv/nastran-g.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/nmg` | 1 | 0 | 0.0% | 0 |
| `src/conv/obj-g.c` | 1 | 0 | 0.0% | 0 |
| `src/conv/off` | 2 | 0 | 0.0% | 0 |
| `src/conv/patch` | 3 | 0 | 0.0% | 0 |
| `src/conv/ply` | 2 | 0 | 0.0% | 0 |
| `src/conv/raw` | 6 | 0 | 0.0% | 0 |
| `src/conv/shp` | 4 | 0 | 0.0% | 0 |
| `src/conv/step` | 600 | 0 | 0.0% | 0 |
| `src/conv/stl` | 2 | 0 | 0.0% | 0 |
| `src/conv/tankill` | 1 | 0 | 0.0% | 0 |
| `src/conv/vdeck` | 5 | 0 | 0.0% | 0 |
| `src/conv/walk_example.c` | 1 | 0 | 0.0% | 0 |
| `src/external` | 17 | 0 | 0.0% | 0 |
| `src/fb` | 29 | 0 | 0.0% | 0 |
| `src/fbserv` | 4 | 4 | 100.0% | 2 |
| `src/gtools` | 40 | 0 | 0.0% | 0 |
| `src/isst` | 9 | 9 | 100.0% | 1 |
| `src/launcher` | 8 | 8 | 100.0% | 1 |
| `src/libanalyze` | 40 | 0 | 0.0% | 0 |
| `src/libbg` | 232 | 232 | 100.0% | 79 |
| `src/libbn` | 41 | 41 | 100.0% | 31 |
| `src/libbrep` | 50 | 50 | 100.0% | 5 |
| `src/libbu` | 176 | 176 | 100.0% | 101 |
| `src/libbv` | 19 | 19 | 100.0% | 1 |
| `src/libdm` | 80 | 80 | 100.0% | 1 |
| `src/libfft` | 8 | 8 | 100.0% | 1 |
| `src/libgcv` | 111 | 111 | 100.0% | 1 |
| `src/libged` | 509 | 509 | 100.0% | 35 |
| `src/libicv` | 34 | 34 | 100.0% | 5 |
| `src/libnmg` | 54 | 8 | 14.8% | 5 |
| `src/liboptical` | 46 | 0 | 0.0% | 0 |
| `src/libpc` | 6 | 6 | 100.0% | 1 |
| `src/libpkg` | 10 | 10 | 100.0% | 3 |
| `src/libqtcad` | 29 | 29 | 100.0% | 6 |
| `src/librt` | 373 | 0 | 0.0% | 0 |
| `src/libtclcad` | 31 | 31 | 100.0% | 7 |
| `src/libtermio` | 2 | 2 | 100.0% | 1 |
| `src/libwdb` | 27 | 27 | 100.0% | 2 |
| `src/mged` | 55 | 55 | 100.0% | 16 |
| `src/nirt` | 2 | 2 | 100.0% | 1 |
| `src/proc-db` | 55 | 55 | 100.0% | 11 |
| `src/qged` | 34 | 34 | 100.0% | 6 |
| `src/remrt` | 7 | 7 | 100.0% | 2 |
| `src/rt` | 33 | 0 | 0.0% | 0 |
| `src/rtwizard` | 1 | 0 | 0.0% | 0 |
| `src/shapes` | 15 | 0 | 0.0% | 0 |
| `src/sig` | 39 | 0 | 0.0% | 0 |
| `src/util` | 90 | 0 | 0.0% | 0 |
## Identified Issues Summary
| ID | Severity | Category | File & Location | Verification | Nature of Issue |
|:---|:---:|:---|:---|:---:|:---|
| `SEC-0001` | **Sev 3** | Invalid Free / Crasher | `src/libpkg/pkg.c:1876-1923` | `FIXED` | pkg_waitfor fails to clear pc->pkc_buf on excess message length, causing subsequent pkg_close to call free on caller stack memory. |
| `SEC-0002` | **Sev 2** | Uninitialized Memory Access | `src/libpkg/pkg.c:1960-1968` | `FIXED` | pkg_bwaitfor returns uninitialized heap buffer instead of NULL when network read fails or disconnects prematurely. |
| `SEC-0003` | **Sev 1** | NULL Pointer Dereference / Crasher | `src/libpkg/example_qt/server.cpp:46-59` | `PENDING` | PKGServer destructor unconditionally dereferences NULL client pointer and frees uninitialized pkc_inbuf. |
| `SEC-0004` | **Sev 3** | Heap Out-of-Bounds Read / Crasher | `src/fbserv/server.c:432-540` | `FIXED` | fbserv packet handlers fail to validate packet payload length against pixel count before calling fb_write, causing heap out-of-bounds read. |
| `SEC-0005` | **Sev 3** | Integer Overflow / Heap Buffer Overflow | `src/fbserv/server.c:476-580` | `FIXED` | Integer multiplication overflow in width*height in fb_readrect and fb_bwreadrect leads to heap buffer overflow during pixel read. |
| `SEC-0006` | **Sev 2** | Integer Signedness / Out-of-Bounds Memory Access | `src/remrt/rtsrv.c:891-971` | `FIXED` | ph_lines fails to validate pixel range bounds, causing signed integer underflow in (b-a+1)*3 to wrap to huge size_t in pkg_2send, triggering out-of-bounds heap reads, and leaks buffer. |
| `SEC-0007` | **Sev 2** | Unhandled Input Validation / Denial of Service | `src/remrt/remrt.c:3803-3806` | `FIXED` | ph_pixels parses incoming MSG_PIXELS without checking packet length or magic header, allowing malformed network packets to trigger out-of-bounds reads or terminate remrt via bu_bomb. |
| `SEC-0008` | **Sev 2** | Out-of-Bounds Memory Access / Buffer Underflow | `src/libbu/parse.c:87-118` | `FIXED` | bu_struct_wrap_buf and PARSE_CK_GETPUT do not verify buffer length is at least 8 bytes, causing negative index access and out-of-bounds read on buffers with small or zero length. |
| `SEC-0009` | **Sev 2** | Format String / Type Confusion | `src/libbu/vls_vprintf.c:186-226` | `FIXED` | vls_vprintf uses bitwise XOR (^=) instead of bitwise AND NOT (&= ~) to clear length modifiers, corrupting flags and causing incorrect type extraction from va_list. |
| `SEC-0010` | **Sev 2** | Off-by-One / Buffer Corruption | `src/libbu/vls.c:433-465` | `FIXED` | bu_vls_substr calls bu_vls_putc with NUL, embedding an unwanted NUL byte and off-by-one corrupting vls_len. |
| `SEC-0011` | **Sev 2** | Integer Overflow / Heap Overflow | `src/libbu/malloc.c:84-145,375-388` | `FIXED` | alloc() and bu_pool_alloc() lack integer multiplication overflow checks on cnt*size, which can cause undersized memory allocations and subsequent heap buffer overflows. |
| `SEC-0012` | **Sev 2** | Buffer Underflow / Out-of-bounds Pointer | `src/libbu/argv.c:97,175,268-295` | `FIXED` | bu_argv_from_string computed pointer at strlen(lp)-1 on potentially empty string causing integer underflow and out-of-bounds pointer arithmetic. |
| `SEC-0013` | **Sev 2** | Buffer Over-read | `src/libbu/str.c:61-75` | `FIXED` | bu_strlcatm uses unbounded strlen on dst to detect un-terminated buffers, causing out-of-bounds read. |
| `SEC-0014` | **Sev 2** | Null Pointer Dereference / Integer Overflow | `src/libbu/b64.c:216-284` | `FIXED` | bu_b64 encode and decode functions lacked null pointer checks on input/output and cast lengths to signed 32-bit int. |
| `SEC-0015` | **Sev 2** | Format String / Scanset Parser Bug | `src/libbu/sscanf.c:312-320,365-375` | `FIXED` | bu_vsscanf omitted literal ] and ^] from partFmt when extracting scanset specifiers, causing malformed format strings and scan failure. |
| `SEC-0016` | **Sev 2** | Null Pointer Dereference / Integer Overflow | `src/libbu/bitv.c:95-105,285-295,440-445,625-630` | `FIXED` | bu_hex_to_bitv and bu_binary_to_bitv2 crashed on NULL input, and bu_bitv_shift_vector had integer overflow UB on INT_MIN. |
| `SEC-0017` | **Sev 2** | Null Pointer Dereference / Memory Safety | `src/libbu/hash.c:125-135,180-190,270-280` | `FIXED` | bu_hash_get crashed on NULL key in _nhash_keycmp, and bu_hash_create/bu_hash_set lacked allocation failure handling. |
| `SEC-0018` | **Sev 3** | Memory Access Violation / Buffer Overflow / Out-of-bounds Pointer | `include/bu/ptbl.h, src/libbu/ptbl.c:105,119-120; 63,99,214,240,266,290` | `FIXED` | BU_PTBL_FOR macro and BU_PTBL_LASTADDR cause out-of-bounds pointer calculation and segfault on empty tables with NULL buffers, and table reallocations lack integer multiplication overflow checks. |
| `SEC-0019` | **Sev 2** | Out-of-bounds Bit Array Access / Resource Leak / Undefined Behavior | `src/libbu/affinity.c:74,90-104,108` | `FIXED` | parallel_set_affinity permitted negative cpu indexing into CPU_SET and negative bitshift on Windows, leaked Mach thread port rights, and passed wrong policy type for Mach thread affinity. |
| `SEC-0020` | **Sev 2** | NULL Pointer Dereference / Process Signal Safety | `src/libbu/backtrace.c:324,596,659-661,742` | `FIXED` | bu_backtrace_app called bu_strlcpy on potentially NULL gdb_path, used negative file descriptors in write, and reaped arbitrary child processes via wait(NULL). |
| `SEC-0021` | **Sev 2** | NULL Pointer Dereference / Buffer Underflow / Crasher | `src/libbu/cmd.c:50-66` | `FIXED` | bu_cmd lacked null checks on cmds, argv, and argv[cmd_index], allowed negative cmd_index causing buffer underflow, and executed unverified function pointers. |
| `SEC-0022` | **Sev 2** | Integer Multiplication Overflow / Crasher | `src/libbu/damlevlim.cpp:68-159` | `FIXED` | bu_editdist computed buffer allocation size as (n+1)*(m+1) using signed 32-bit int, causing signed integer multiplication overflow, out-of-bounds access, and std::length_error crash on large strings. |
| `SEC-0023` | **Sev 2** | Heap Buffer Overflow / NULL Pointer Dereference / TOCTOU | `src/libbu/dirent.c, src/libbu/datetime.cpp:36-88; 173-197` | `FIXED` | bu_file_list called opendir(NULL) when path is NULL and suffered from heap buffer overflow if directory entries were added concurrently between passes; bu_utctime crashed on NULL vls_gmtime. |
| `SEC-0024` | **Sev 2** | Buffer Overflow / Underflow / NULL Pointer Dereference / Infinite Loop | `src/libbu/dir.c:69-75, 108, 169, 186, 248, 254, 395-405, 480-535, 656-665, 684-740` | `FIXED` | dir routines passed caller buffer len to fixed stack arrays risking stack buffer overflow, permitted underflow pointer reads in _bu_dir_join_path, crashed on NULL result in vdir, and risked infinite loop or crash in bu_mkdir/bu_dirclear on invalid paths. |
| `SEC-0025` | **Sev 3** | Heap Use-After-Free / Double-Free / Thread Safety | `src/libbu/dylib.c:38-40, 70-87, 105-120` | `FIXED` | bu_dlunload freed the global handles table without resetting handles to NULL or max_handles to 0, leading to dangling pointer use-after-free heap writes on subsequent bu_dlclose calls and double-free on subsequent bu_dlunload calls; routines lacked thread synchronization. |
| `SEC-0026` | **Sev 1** | Invalid File Descriptor / Parameter Validation | `src/libbu/fchmod.cpp:62-75` | `FIXED` | bu_fchmod passed unvalidated negative file descriptors to OS handles routines triggering CRT parameter validation errors or unexpected failures. |
| `SEC-0027` | **Sev 2** | Memory Leak / Resource Leak / NULL Pointer Dereference / Logic Flaw | `src/libbu/file.cpp:79-110, 126-166, 193, 227-240, 360, 603-640` | `FIXED` | bu_file_same leaked allocated realpath strings on match and crashed on NULL paths, file_compare_info had an assignment instead of comparison operator bug, bu_file_exists leaked file descriptors, and stream seek/tell functions crashed on NULL streams. |
| `SEC-0028` | **Sev 2** | NULL Pointer Dereference / Crasher | `src/libbu/fnmatch.c:308-311` | `FIXED` | bu_path_match immediately dereferenced pattern and string without NULL pointer checks, causing immediate SIGSEGV crashes on NULL inputs. |
| `SEC-0029` | **Sev 2** | Invalid Pointer Cast / NULL Pointer Dereference / Buffer Overflow | `src/libbu/gethostname.c:49, 81-84, 89` | `FIXED` | bu_gethostname passed constant (LPDWORD)MAXPATHLEN as pointer to GetComputerName causing invalid pointer crash, left procfs file pointer unchecked causing null stream crash, and lacked entry bounds validation. |
| `SEC-0030` | **Sev 2** | NULL Pointer Dereference / Buffer Over-read / Logic Flaw | `src/libbu/getopt.c:34-39, 48-56, 65-72, 84, 98` | `FIXED` | bu_getopt dereferenced NULL nargv elements and NULL *nargv in tell macro, read out of bounds on '\0' matched in ostr via strchr, and misidentified bare '-' as an option. |
| `SEC-0031` | **Sev 2** | NULL Pointer Dereference / Crasher | `src/libbu/glob.c:63, 84, 110, 161, 195, 240, 259, 286` | `FIXED` | bu_glob internal helpers and callbacks dereferenced NULL pattern, path, directory entry, or stat buffer pointers without checking for NULL. |
| `SEC-0032` | **Sev 2** | Out-of-bounds Array Access / Integer Underflow | `src/libbu/heap.c:136, 200-216, 255` | `FIXED` | bu_heap_get bypassed allocation size range check when DEBUG was not defined causing out-of-bounds heap bin indexing and underflow to SIZE_MAX when sz == 0, and lacked cpu id bounds clamping. |
| `SEC-0033` | **Sev 2** | Out-of-bounds Memory Write / NULL Pointer Dereference | `src/libbu/hist.c:52, 82-100, 117-128` | `FIXED` | bu_hist_range permitted negative or out-of-bounds 'a' indexing on NaN inputs causing heap write access violation, and bu_hist_init/bu_hist_pr crashed on NULL inputs. |
| `SEC-0034` | **Sev 2** | Signal Handler Leak / Out-of-bounds Array Access / Logic Flaw | `src/libbu/interrupt.c:78-83, 100-116, 137-163` | `FIXED` | interrupt_restore_signal never restored signal handlers when no signal was received leaving temporary handler active indefinitely, checked wrong handler pointer, and lacked bounds check on signum. |
| `SEC-0035` | **Sev 2** | Buffer Underflow / Integer Overflow UB / Out-of-bounds Read | `src/libbu/num.c:35-58, 87-90, 106` | `FIXED` | bu_num_print read out-of-bounds at tbl_start[-1] due to reversed condition ordering in trailing newline scan and crashed on empty strings; char_length had signed integer overflow UB on INT64_MIN and truncated 64-bit int to long. |
| `SEC-0036` | **Sev 2** | NULL Pointer Dereference / Integer Overflow | `src/libbu/log.c:148, 156, 204, 222, 335` | `FIXED` | bu_flog lacked null pointer and empty string checks on fmt and fp, causing NULL pointer dereference crashes in fwrite, and bu_log helper routines lacked null pointer guards. |
| `SEC-0037` | **Sev 2** | NULL Pointer Dereference / Integer Underflow | `src/libbu/mappedfile.c:360, 544-550, 577` | `FIXED` | bu_open_mapped_file_with_path crashed with SIGSEGV on NULL name or path, bu_free_mapped_files suffered from unsigned integer underflow on index removal, and bu_open_mapped_file allowed invalid file sizes. |
| `SEC-0038` | **Sev 2** | NULL Pointer Dereference / Memory Safety | `src/libbu/observer.c:36, 58, 110, 168, 194, 215` | `FIXED` | bu_observer_cmd and helper routines dereferenced NULL argv or NULL observer lists without validation, and bu_observer_free left dangling pointers in the observer list. |
| `SEC-0039` | **Sev 2** | Integer Underflow / NULL Pointer Dereference | `src/libbu/lex.c:42, 131, 155, 257, 268` | `FIXED` | lex_getone allowed negative *used integer underflow on number fallback, and bu_lex crashed on NULL token, rtstr, or NULL key strings. |
| `SEC-0040` | **Sev 2** | Buffer Underflow / Concurrency Hazard / Integer Bounds | `src/libbu/path_normalize.c:47, 86-88, 95` | `FIXED` | bu_path_normalize used non-thread-safe static buffer, lacked lower-bound check in backward component scan allowing pointer underflow before resolved buffer, and used unchecked signed pointer arithmetic for MAXPATHLEN bounds check. |
| `SEC-0041` | **Sev 2** | NULL Pointer Dereference / Undefined Bitshift / Out-of-bounds Read | `src/libbu/printb.c:36, 40-52` | `FIXED` | bu_vls_printb dereferenced NULL vls and bits strings, shifted signed 1L by negative or out-of-range bit numbers causing undefined behavior, and read out-of-bounds on strings ending after bit numbers. |
| `SEC-0042` | **Sev 2** | NULL Pointer Dereference / Path Truncation Flaw | `src/libbu/path.c:177-180, 211-218, 242-258` | `FIXED` | bu_path_to_argv dereferenced NULL ac pointer causing crash, and bu_path_component corrupted file paths by stripping directories when a dot appeared in directory names under BU_PATH_EXTLESS and BU_PATH_EXT. |
| `SEC-0043` | **Sev 2** | Crash / Unhandled Exception / NULL Function Pointer Dereference | `src/libbu/parallel_cpp11thread.cpp:28-51` | `FIXED` | parallel_cpp11thread crashed on NULL func callback and caused std::terminate() aborts if thread creation threw an exception while previous threads remained joinable. |
| `SEC-0044` | **Sev 2** | Concurrency Hazard / Unchecked Buffer Overflow | `src/libbu/progname.c:74-79, 140-143, 155-190` | `FIXED` | bu_argv0_full_path and bu_getprogname returned static non-thread-safe buffers and accessed bu_progname unsynchronized with concurrent bu_setprogname writes, and bu_argv0_full_path unchecked bu_getcwd return and appended with potential buffer overflow. |
| `SEC-0045` | **Sev 2** | NULL Pointer Dereference / Crash | `src/libbu/realpath.c:38-66` | `FIXED` | bu_file_realpath dereferenced NULL path pointer into realpath, GetFullPathName, and bu_strlcpy fallback causing immediate SIGSEGV crashes. |
| `SEC-0046` | **Sev 2** | Format String Flaw / Uninitialized Variable Memory Corruption | `src/libbu/scan.c:38, 58-60, 68-73, 89-93` | `FIXED` | bu_scan_fastf_t constructed dynamic scanf format strings from user delimiter allowing format string injection, and read uninitialized stack variable 'len' into offset when sscanf failed to reach %n specifier. |
| `SEC-0047` | **Sev 2** | Out-of-bounds Array Access / Concurrency Race Condition | `src/libbu/semaphore.c:260-286, 298-301, 340-343` | `FIXED` | bu_semaphore_acquire and bu_semaphore_release lacked upper bounds checks on semaphore index causing out-of-bounds array access and integer overflow on UINT_MAX, and bu_semaphore_free destroyed mutexes without synchronizing on bu_init_lock. |
| `SEC-0048` | **Sev 2** | NULL Pointer Dereference / Memory Safety | `src/libbu/sha1.c:53, 110, 126, 150` | `FIXED` | SHA1Transform, SHA1Init, SHA1Update, and SHA1Final lacked NULL pointer validation on context, data, digest, state, and buffer pointers causing SIGSEGV crashes. |
| `SEC-0049` | **Sev 1** | Integer Overflow UB / Logic Flaw | `src/libbu/snooze.cpp:35-42` | `FIXED` | bu_snooze lacked upper bound clamping on 64-bit useconds causing integer overflow when converted to nanoseconds internally in std::chrono durations. |
| `SEC-0050` | **Sev 2** | Memory Access Flaw / Divide by Zero | `src/libbu/sort.c:156-189, 381-402` | `FIXED` | bu_sort lacked checks for NULL a, NULL cmp, zero element size es == 0 (causing division by zero in introsort), and min(a, b) macro lacked parameter parentheses. |
| `SEC-0051` | **Sev 2** | Buffer Underflow / Pointer Overflow | `src/libbu/tbl.c:381-432` | `FIXED` | bu_tbl_printf suffered from backward scan buffer underflow dereferencing buf[-1] and unbounded runaway pointer increment last += 2 over-reading memory. |
| `SEC-0052` | **Sev 2** | Null Pointer Dereference / Memory Management | `src/libbu/tc.c:33-200, 428-456` | `FIXED` | bu_thrd_create dereferenced NULL thr pointer and lacked guard on NULL func; mutex and condition variable routines lacked NULL checks; used raw malloc/free. |
| `SEC-0053` | **Sev 2** | Buffer Over-read / Null Pointer Dereference | `src/libbu/tcllist.c:538, 554-565` | `FIXED` | bu_argv_from_tcl_list crashed on NULL arguments; _bu_tcl_copy_collapse passed strlen(src) instead of remaining count to _bu_tcl_parse_backslash, allowing read out of bounds past list element. |
| `SEC-0054` | **Sev 3** | Uninitialized Memory / Heap Corruption / Concurrency | `src/libbu/temp.c:85-151, 155-175` | `FIXED` | temp_add_to_list failed to copy initial_temp_files when reallocating from 8 to 16 elements, reading uninitialized memory and calling close() on garbage file descriptors at exit; global temp list lacked thread synchronization. |
| `SEC-0055` | **Sev 2** | Buffer Underflow / Null Pointer Dereference | `src/libbu/units.c:237-244, 256-270, 390-440` | `FIXED` | units_name_matches underflowed bu_vls_strlen - 1 to SIZE_MAX on empty strings/whitespace, causing out-of-bounds heap read; bu_units_conversion, bu_mm_value, and bu_mm_cvt crashed on NULL pointers. |
| `SEC-0056` | **Sev 1** | Null Pointer Dereference / Integer Overflow UB | `src/libbu/units_dehumanize.c:80-92, 131-137` | `FIXED` | bu_dehumanize_number crashed on NULL str or size and performed signed multiplication without pre-overflow bounds check. |
| `SEC-0057` | **Sev 2** | Null Pointer Dereference / Integer Overflow UB | `src/libbu/units_humanize.c:74-82, 128-133` | `FIXED` | bu_humanize_number dereferenced buf[0] before validating buf != NULL, causing crash when called with a NULL buffer; negation of INT64_MIN caused signed integer overflow UB. |
| `SEC-0058` | **Sev 2** | Buffer Overflow / Null Pointer Dereference / Logic Flaw | `src/libbu/uuid.c:56, 89, 118-124, 134-161` | `FIXED` | bu_uuid_decode suffered critical 16-byte buffer overflow writing 32 bytes to a 16-byte array on non-adjacent hex strings; bu_uuid_create crashed on NULL uuid and corrupted UUIDv5 bits with 0x5F instead of 0x50; bu_uuid_encode crashed on NULL pointers. |
| `SEC-0059` | **Sev 2** | File Descriptor Leak / Uninitialized Data / Null Dereference | `src/libbu/vfont.c:42, 60-100, 140-150, 184-196, 201-207` | `FIXED` | vfont_get passed potential NULL from bu_dir() to snprintf %s, left 256th dispatch entry uninitialized (i < 255), leaked file descriptors on read failures in get_font, and vfont_free crashed on NULL pointer. |
| `SEC-0060` | **Sev 2** | Integer Overflow / Null Pointer Dereference | `src/libbu/vlb.c:34-160` | `FIXED` | bu_vlb_write lacked integer overflow protection on capacity addition and crashed when given NULL start; bu_vlb_init, bu_vlb_initialize, bu_vlb_free, and bu_vlb_print crashed on NULL pointers. |
| `SEC-0061` | **Sev 2** | Undefined Behavior / Memory Leak / Null Pointer Dereference | `src/libbu/cache.cpp:110-140, 220-250, 480-510` | `FIXED` | bu_cache_close freed bu_cache_impl containing std::mutex with BU_PUT instead of delete causing destructor bypass and undefined behavior; bu_cache_keys leaked keystr memory; bu_cache_write_commit underflowed mv_size on negative lengths; NULL txn crashed transactions. |
| `SEC-0062` | **Sev 2** | Null Pointer Dereference / Float Validity | `src/libbu/color.cpp:52-95, 120-160` | `FIXED` | bu_color_from_str, bu_rgb_to_hsv, and bu_hsv_to_rgb dereferenced NULL pointers unconditionally without validation; bu_color_from_rgb_floats lacked bounds and finite checks. |
| `SEC-0063` | **Sev 2** | Buffer Overflow / Unsigned Underflow | `src/libbu/convert.c:120-160, 200-240` | `FIXED` | bu_cv_fmt_cookie decremented buflen below zero on small buffers (1-2 bytes), wrapping to SIZE_MAX and writing out of bounds; bu_cv_w_cookie and byte swap routines crashed on NULL or empty input. |
| `SEC-0064` | **Sev 2** | File Descriptor Leak / Null Pointer Dereference | `src/libbu/crashreport.c:110-140, 210-230` | `FIXED` | bu_crashreport leaked file descriptor when ferror(fp) was true, and formatted potential NULL return from ctime(). |
| `SEC-0065` | **Sev 2** | Memory Leak / Null Pointer Dereference / Unchecked Input | `src/libbu/env.c:140-190, 240-270` | `FIXED` | editor_not_compatible leaked component vls and dereferenced NULL candidate; editor_file_check lacked NULL checks; bu_setenv lacked POSIX environment variable name validation. |
| `SEC-0066` | **Sev 2** | Null Pointer Dereference / Buffer Over-read / Type Mismatch | `src/libbu/opt.c:215-260, 480-520` | `FIXED` | opt_describe_internal_ascii crashed when arg_helpstr or help_string was NULL; docbook describe had curr vs d typo; opt_process over-read empty candidate; bu_opt_color had unsigned char type mismatch. |
| `SEC-0067` | **Sev 2** | Out-of-Bounds Memory Access | `src/libbu/parallel.c:280-310` | `FIXED` | PARALLEL_PUT accessed mapping[id] without validating 0 <= id < MAX_PSW*MAX_PSW, causing out-of-bounds memory corruption. |
| `SEC-0068` | **Sev 2** | Null Pointer Dereference / Memory Leak / Buffer Overflow | `src/libbu/process.c:350-380, 520-560, 1220-1250` | `FIXED` | bu_process_read unconditionally dereferenced *count = ... even if caller passed NULL; bu_process_exec leaked heap av on every execution; bu_interactive passed unchecked fd to FD_SET causing buffer overflow. |
| `SEC-0069` | **Sev 2** | Null Pointer Dereference | `src/libbu/uce-dirent.h:348-354, 578-583, 608-612` | `FIXED` | opendir, rewinddir, and _initdir relied solely on assert() in debug mode, crashing with NULL pointer dereference in release builds when given NULL dirname or DIR stream. |
| `SEC-0070` | **Sev 2** | Unhandled Exception / Denial of Service Crash | `src/libbu/vls_incr.cpp:136-155, 180-188` | `FIXED` | bu_vls_incr accessed ivar.str(1) and nvar.str(1) without verifying match group count, throwing std::out_of_range which bypassed catch (const std::regex_error&) and crashed the application. |
| `SEC-0071` | **Sev 2** | Null Pointer Dereference | `src/libbu/whereami.c:95-135` | `FIXED` | _bu_getExecutablePath dereferenced pname[0] without checking if _bu_progname_raw() returned NULL, and copied memory into out when out == NULL. |
| `SEC-0072` | **Sev 2** | Infinite Loop / Denial of Service | `src/libbu/whereis.c:135-155` | `FIXED` | bu_whereis bypassed pointer advancement on dirlen > MAXPATHLEN-2 with continue;, causing an infinite loop hanging the process at 100% CPU. |
| `SEC-0073` | **Sev 2** | Infinite Loop / Memory Leak | `src/libbu/which.c:91-115` | `FIXED` | which_path suffered infinite loop on oversized directories and empty matches, and leaked initial_path every time an executable was not found. |
| `SEC-0074` | **Sev 2** | Null Pointer Dereference | `src/libbu/xdr.c:31-88` | `FIXED` | bu_pshort, bu_gshort, bu_plong, bu_glong, and bu_plonglong dereferenced msgp without validating msgp != NULL, causing immediate segmentation fault. |
| `SEC-0075` | **Sev 2** | Memory Leak / Null Pointer Dereference | `src/libbu/tests/dylib/dylib.c:35-85` | `FIXED` | bu_file_list allocated filenames and bu_vls plugin_pattern allocated memory which was never freed; dylib_close_plugins dereferenced NULL pointer when called with plugins == NULL. |
| `SEC-0076` | **Sev 2** | Null Pointer Dereference | `src/libbu/tests/dylib/plugin_1.cpp:22-28` | `FIXED` | calc dereferenced *result without checking if *result == NULL, causing crash on NULL buffer pointer. |
| `SEC-0077` | **Sev 2** | Null Pointer Dereference | `src/libbu/tests/dylib/plugin_2.cpp:22-28` | `FIXED` | calc dereferenced *result without checking if *result == NULL, causing crash on NULL buffer pointer. |
| `SEC-0078` | **Sev 2** | Stack Buffer Overflow / Format String UB | `src/libbu/tests/test_dirname.c:58-82` | `FIXED` | bu_strlcpy used strlen(input)+1 instead of destination buffer size, causing stack buffer overflow on strings exceeding 1000 bytes; passed NULL to printf format string. |
| `SEC-0079` | **Sev 1** | Undefined Behavior / Crash | `src/libbu/tests/test_encode.c:70-90` | `FIXED` | Passed NULL str directly to %*s and %s in printf when testing test_encode(NULL), causing undefined behavior and potential crash. |
| `SEC-0080` | **Sev 1** | Memory Leak / Unchecked Return | `src/libbu/tests/test_datetime.c:243-345` | `FIXED` | result VLS was allocated and never freed across multiple date/time tests, leaking memory; sscanf return value was unvalidated. |
| `SEC-0081` | **Sev 2** | Null Pointer Dereference / Crash | `src/libbu/tests/test_basename.c:55-65, 130-140` | `FIXED` | get_system_output(NULL) called basename(NULL) which causes segmentation fault on glibc implementations; passed NULL input to bu_log format strings. |
| `SEC-0082` | **Sev 2** | Heap Buffer Overflow / Off-by-one | `src/libbu/tests/test_progname.c:63-71, 107-115, 149-157, 189-197` | `FIXED` | Allocated strlen(path) bytes via bu_calloc without space for null terminator before calling bu_strlcpy, causing buffer overflow; leaked allocated buffer. |
| `SEC-0083` | **Sev 2** | Use-After-Free / Memory Leak / Float Comparison | `src/libbu/tests/test_mappedfile.c:70-74, 385-397` | `FIXED` | Accessed mfp->buf after closing mapped file via bu_close_mapped_file, performed raw float equality on double num, and leaked fname VLS. |
| `SEC-0084` | **Sev 2** | Process Resource Leak / NULL Pointer Dereference | `src/libbu/tests/test_process.c:172-184, 521-536, 680-705` | `FIXED` | Failed to wait on or close process handles on error paths leaking processes, and attempted to close/read NULL file handles when fopen failed. |
| `SEC-0085` | **Sev 2** | Array Out-of-Bounds / Crash | `src/libbu/tests/test_parallel.c:70-80, 115-125` | `FIXED` | Indexed counter array with cpu ID up to ncpu in tally without bound check, and omitted NULL data check in parallel recursion callback. |
| `SEC-0086` | **Sev 2** | Out-of-Bounds Memory Read / Pointer Type-Punning | `src/libbu/tests/test_opt.c:58-64, 492-498` | `FIXED` | Read av[-1] when av was decremented without checking bounds, and type-punned unsigned int array to unsigned char pointer violating strict aliasing. |
| `SEC-0087` | **Sev 2** | NULL Pointer Dereference / Memory Leak | `src/libbu/tests/test_hook.c:45-55, 120-145` | `FIXED` | Callback dereferenced clientdata pointer without NULL check and hook list structures were allocated and never freed across tests. |
| `SEC-0088` | **Sev 2** | Out-of-Bounds Read / NULL Pointer Dereference | `src/libbu/tests/test_glob.c:95-110, 195-205` | `FIXED` | Read buffer out of bounds when checking trailing slash on short paths and called glob operations without validating NULL context pointers. |
| `SEC-0089` | **Sev 1** | Resource Leak / Unchecked Return Value | `src/libbu/tests/test_env.c:80-92, 128-135` | `FIXED` | Did not check fopen return value before writing and failed to validate bu_strdup return value leaking memory on error. |
| `SEC-0090` | **Sev 1** | NULL Pointer Dereference / Format Flaw | `src/libbu/tests/test_escape.c:72-85, 140-150` | `FIXED` | Passed unverified pointer to %s format specifier in printf calls and omitted explicit return code in test helper. |
| `SEC-0091` | **Sev 1** | Format String Flaw / NULL Dereference | `src/libbu/tests/test_path_component.c:62-75` | `FIXED` | Passed NULL pointer to %24s in bu_log formatting calls, which crashes strict C runtime environments. |
| `SEC-0092` | **Sev 1** | Memory Leak | `src/libbu/tests/test_humanize_number.c:115-135` | `FIXED` | Allocated string representations of flags and scale inside loop iterations without freeing them, causing repeated memory leaks. |
| `SEC-0093` | **Sev 1** | Memory Leak / NULL Pointer Dereference | `src/libbu/tests/test_file.c:70-75, 233-241` | `FIXED` | cleanup() function leaked fname VLS allocation on return, and realpath test did not check if rpath was NULL before comparing. |
| `SEC-0094` | **Sev 1** | Unchecked Return Value / Array Bounds | `src/libbu/tests/test_file_mime.c:45-56` | `FIXED` | Did not check sscanf return count allowing uninitialized integer use, and allowed negative context index causing out-of-bounds array access. |
| `SEC-0095` | **Sev 1** | NULL Pointer Dereference | `src/libbu/tests/test_observer.c:45-55` | `FIXED` | Missing NULL check on observer callback event structure pointer before dereferencing. |
| `SEC-0096` | **Sev 1** | NULL Pointer Dereference | `src/libbu/tests/test_parallel_concurrency.cpp:40-48` | `FIXED` | Thread worker function dereferenced user data pointer without checking for NULL. |
| `SEC-0097` | **Sev 1** | Resource Leak / Empty String Check | `src/libbu/tests/test_path_match.cpp:38-52` | `FIXED` | ifstream remained open without explicit close and empty lines were parsed without validation. |
| `SEC-0098` | **Sev 2** | POSIX/Darwin API Resolution / Failure to Canonicalize | `src/libbu/realpath.c:20-27` | `FIXED` | Under strict POSIX/XOPEN flags on macOS without _DARWIN_C_SOURCE, realpath bound to legacy conformance symbol which failed with EPERM, breaking path canonicalization across libbu. |
| `SEC-0099` | **Sev 2** | Memory Management / Resource Leak | `src/libbu/tests/test_realpath.c:47-79` | `FIXED` | Heap memory leak of allocated path string, unchecked sscanf return value, and potential NULL printf argument in test_realpath.c. |
| `SEC-0100` | **Sev 1** | Memory Access / NULL Pointer Dereference | `src/libbu/tests/test_semaphore.c:48-62` | `FIXED` | Unchecked callback argument pargs in multi-threaded function increment_thread could lead to NULL pointer dereference. |
| `SEC-0101` | **Sev 2** | Memory Access / Out-of-bounds Read | `src/libbu/tests/test_semaphore_registry.cpp:60-63` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0102` | **Sev 2** | Error Handling / Logic Error | `src/libbu/tests/test_semchk.cpp:40-75` | `FIXED` | Undeclared identifier av[0] passed to bu_setprogname, unhandled file stream failure in process_file, and unguarded argv dereference. |
| `SEC-0103` | **Sev 2** | Memory Access / Out-of-bounds Read | `src/libbu/tests/test_snooze.c:44-48` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0104` | **Sev 1** | Integer Wraparound / Underflow | `src/libbu/tests/test_sort.c:45-95` | `FIXED` | Integer subtraction bug in comparison function comp_1 (*(unsigned int *)num1 - *(unsigned int *)num2) caused unsigned underflow and reversed sort order; comp_4 lacked NULL pointer checks; sscanf return was unchecked. |
| `SEC-0105` | **Sev 2** | Memory Access / Out-of-bounds Read | `src/libbu/tests/test_static_init.cpp:44-48` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0106` | **Sev 2** | Memory Management / Resource Leak | `src/libbu/tests/test_str.c:115-180` | `FIXED` | Memory leaks of allocated dst buffer across test_bu_strlcatm, test_bu_strlcpym, and test_bu_strdupm, unchecked sscanf, and negative integer cast to size_t. |
| `SEC-0107` | **Sev 2** | Format String / NULL Pointer Dereference | `src/libbu/tests/test_str_isprint.c:70-98` | `FIXED` | Passing NULL string pointer to %10s format specifier in bu_log caused undefined behavior / crash; unchecked sscanf. |
| `SEC-0108` | **Sev 2** | Uninitialized Memory Access | `src/libbu/tests/test_subprocess.cpp:45-55` | `FIXED` | Stack buffer char line[25] was uninitialized before std::cin.get(line, 25), leading to uninitialized memory read if stream was empty or in error state. |
| `SEC-0109` | **Sev 1** | Concurrency / Out-of-bounds Memory Access | `src/libbu/tests/test_temp_filename.c:45-78` | `FIXED` | Passed &names (char ***) instead of names (char **) to bu_parallel, causing worker threads with cpu > 1 to read and write invalid stack memory outside the array; names[cpu - 1] caused underflow on cpu = 0; off-by-one heap allocation len + 1 caused string truncation. |
| `SEC-0110` | **Sev 2** | Memory Access / NULL Pointer Dereference | `src/libbu/tests/test_units.c:48-58` | `FIXED` | Missing NULL pointer validation for csv and token in helper function units_csv_has_token. |
| `SEC-0111` | **Sev 2** | Logic Error / False-Pass Test Suite Flaw | `src/libbu/tests/test_uuid.c:55-90` | `FIXED` | Typo in expected UUID string paired with inverted condition !bu_strcmp caused test suite to return 0 (PASS) on mismatch while returning 1 (FAIL) if it matched; missing error logging. |
| `SEC-0112` | **Sev 2** | Memory Access / Out-of-bounds Read | `src/libbu/tests/test_version.c:35-48` | `FIXED` | Missing common.h include and unguarded av[0] dereference passed to bu_setprogname. |
| `SEC-0113` | **Sev 2** | Memory Access / Out-of-bounds Read | `src/libbu/tests/test_vlb.c:42-46` | `FIXED` | Unguarded argv[0] dereference passed to bu_setprogname when argv could be NULL or empty. |
| `SEC-0114` | **Sev 2** | Memory Management / Resource Leak | `src/libbu/tests/test_vls.c:115-680` | `FIXED` | Heap memory leaks across 13 test functions using bu_vls_strdup solely for comparison without freeing the returned string; out-of-bounds argv access in test_bu_vls_substr; unchecked sscanf. |
| `SEC-0115` | **Sev 2** | Input Validation / Integer Parsing | `src/libbu/tests/test_vls_incr.c:58-85` | `FIXED` | Unguarded argv dereference and unvalidated strtol conversion where invalid characters or out-of-range counts were unhandled. |
| `SEC-0116` | **Sev 2** | Memory Management / Resource Leak | `src/libbu/tests/test_vls_incr_uniq.cpp:50-93` | `FIXED` | Memory leak of struct bu_vls name on exit; heap allocation leak of std::set on early exit; potential NULL pointer dereference in StrCmp. |
| `SEC-0117` | **Sev 2** | Memory Access / Out-of-bounds Read | `src/libbu/tests/test_vls_simplify.c:56-85` | `FIXED` | Unguarded argv dereference before bu_setprogname, potential NULL pointer dereference in bu_log format string. |
| `SEC-0118` | **Sev 1** | Buffer Overflow / Stack Vulnerability | `src/libbu/tests/test_vls_vprintf.c:55-175` | `FIXED` | Unbounded vsprintf into fixed 1024-byte stack buffer buffer[1024] created an unconstrained stack buffer overflow vulnerability; unchecked sscanf and unguarded argv. |
| `SEC-0119` | **Sev 1** | Numerical Stability / NaN Generation | `src/libbn/anim.c:304-332` | `FIXED` | anim_mat2quat negative square root NaN generation caused by floating-point rounding when testing !ZERO(square); passed minute negative numbers into sqrt() resulting in NaN quaternion components. |
| `SEC-0120` | **Sev 1** | Buffer Overflow | `src/libbn/anim.c:153-176` | `FIXED` | anim_mat_printf stack buffer overflow risk with fixed 128-byte character buffer when formatting 16 double-precision float values with custom prefix strings. |
| `SEC-0121` | **Sev 2** | Null Pointer Dereference | `src/libbn/anim.c:180-680` | `FIXED` | Missing NULL pointer checks across anim_mat_print, anim_dir2mat, anim_dirn2mat, anim_steer_mat, anim_v_permute, anim_v_unpermute, anim_tran, anim_mat2zyx, and anim_mat2ypr. |
| `SEC-0122` | **Sev 2** | Null Pointer Dereference | `src/libbn/complex.c:54-85` | `FIXED` | bn_cx_div and bn_cx_sqrt dereferenced destination and operand pointers without validating against NULL. |
| `SEC-0123` | **Sev 1** | Stack Buffer Overflow | `src/libbn/mat.c:1544-1578` | `FIXED` | bn_opt_mat looped up to argc when argc > 15, writing into fixed 16-element stack array fastf_t mtmp[16], overflowing the stack frame on excess arguments. |
| `SEC-0124` | **Sev 1** | Out-of-bounds Read | `src/libbn/mat.c:1500-1540` | `FIXED` | bn_opt_mat out-of-bounds read when checking trailing closing brace with bu_vls_addr(&str)[bu_vls_strlen(&str)-1] without verifying bu_vls_strlen > 0. |
| `SEC-0125` | **Sev 1** | Buffer Overflow | `src/libbn/mat.c:80-140` | `FIXED` | bn_mat_print_guts wrote into fixed obuf array without checking remaining capacity against bu_vls length, leading to potential buffer overflow. |
| `SEC-0126` | **Sev 1** | Concurrency Data Race / Logic Bug | `src/libbn/mat.c:1000-1060` | `FIXED` | bn_wrt_point_direc declared transformation matrices as static local variables, causing data corruption across concurrent raytracing threads, and had inverted translation vector origin_to_pt. |
| `SEC-0127` | **Sev 2** | Division by Zero | `src/libbn/mat.c:1100-1200` | `FIXED` | persp_mat and deering_persp_mat performed division by near_plane, right-left, and bottom-top without checking for zero denominators. |
| `SEC-0128` | **Sev 2** | Memory Access / Use-After-Free Prevention | `src/libbn/msr.c:120-135` | `FIXED` | bn_gauss_free lacked NULL pointer guard and failed to clear magic identifier before freeing heap structure. |
| `SEC-0129` | **Sev 3** | Dead Code | `src/libbn/mt19937ar.c:170-257` | `FIXED` | Dead #if 0 code block with test main function embedded within shared library source file. |
| `SEC-0130` | **Sev 1** | Heap Memory Corruption | `src/libbn/multipoly.c:80-101` | `FIXED` | bn_multipoly_grow realloc corruption passing outer pointer array P->cf instead of row array P->cf[i] with sizeof(double*) instead of sizeof(double), overwriting row pointers with pointer array address. |
| `SEC-0131` | **Sev 1** | Out-of-bounds Access | `src/libbn/multipoly.c:80-101` | `FIXED` | bn_multipoly_grow failed to update P->dgrs and P->dgrt dimensions after growing, leaving stale dimensions that caused subsequent operations to access out of bounds or fail to allocate. |
| `SEC-0132` | **Sev 1** | Out-of-bounds Read | `src/libbn/multipoly.c:120-132` | `FIXED` | bn_multipoly_add out-of-bounds read when polynomials had differing degrees, reading beyond allocated row bounds, and dimension calculation typo Max(p1->dgrt, p2->dgrs) instead of p2->dgrt. |
| `SEC-0133` | **Sev 1** | Logic / Numerical Error | `src/libbn/multipoly.c:140-155` | `FIXED` | bn_multipoly_mul overwrote accumulated product terms using = instead of +=, destroying earlier polynomial term contributions sharing identical combined powers. |
| `SEC-0134` | **Sev 1** | Resource Leak | `src/libbn/multipoly.c:70-75` | `FIXED` | Missing bn_multipoly_free function causing 100% memory leak of all 2D dynamically allocated bivariate polynomial matrices. |
| `SEC-0135` | **Sev 2** | Null Pointer Dereference / Dead Code | `src/libbn/noise.c:248-430` | `FIXED` | Missing NULL pointer validation on point and result in bn_noise_perlin, bn_noise_vec, and spectral functions; 22 lines of dead #if 0 code in bn_noise_mf. |
| `SEC-0136` | **Sev 1** | Out-of-bounds Access / Allocation Flaw | `src/libbn/noise.c:460-545` | `FIXED` | build_spec_tbl and find_spec_wgt allowed negative or zero octaves, leading to invalid memory allocation size (int)(octaves+1) <= 0 and out-of-bounds weight table indexing. |
| `SEC-0137` | **Sev 1** | Resource Leak / Typo | `src/libbn/numgen.c:52-72` | `FIXED` | bn_numgen_create allocated generator on the heap before validating dim > 0 and seed < 0, leaking the allocated structure on early return; nperiodic typo in flag check. |
| `SEC-0138` | **Sev 1** | Memory Corruption / Pointer Aliasing | `src/libbn/poly.c:50-168` | `FIXED` | In-place pointer aliasing in bn_poly_mul, bn_poly_add, and bn_poly_sub when destination pointer equaled one of the operand polynomials caused coefficients to be overwritten before being read. |
| `SEC-0139` | **Sev 1** | Buffer Overflow / Unsigned Underflow | `src/libbn/poly.c:170-197` | `FIXED` | bn_poly_synthetic_division assigned -1 to unsigned size_t quo->dgr when divisor degree exceeded dividend degree, underflowing to SIZE_MAX and triggering an unbounded loop writing past the 7-element coefficient array. |
| `SEC-0140` | **Sev 2** | Null Pointer Dereference | `src/libbn/poly.c:200-488` | `FIXED` | Missing NULL pointer checks in bn_poly_quadratic_roots, bn_poly_cubic_roots, bn_poly_quartic_roots, bn_pr_poly, and bn_pr_roots. |
| `SEC-0141` | **Sev 2** | Memory Access Violation / Numerical Robustness | `src/libbn/qmath.c:84-331` | `FIXED` | In quat_mat2quat, negative diagonal difference caused NaN and division-by-zero on non-orthogonal matrices; acos() called on unconstrained dot products causing NaN domain errors; missing NULL pointer checks across quaternion math operations. |
| `SEC-0142` | **Sev 2** | Denial of Service / Memory Access Violation | `src/libbn/randsph.c:50-120` | `FIXED` | Potential infinite loop in _bn_unit_sph_sample when bn_randmt() yields exactly 0.5; possible NaN from sqrt(1 - S) when S slightly exceeds 1 due to floating-point rounding; unchecked return value from bn_sobol_next in _bn_unit_sph_sample_sobol. |
| `SEC-0143` | **Sev 2** | Null Pointer Dereference | `src/libbn/sobol.c:148-325` | `FIXED` | bn_sobol_create did not check the return status of sobol_init, creating partially initialized structures with NULL member pointers when sdim was invalid; rightzero32 had undefined behavior if invoked with 0xffffffffU; _sobol_urand and bn_sobol_next lacked NULL pointer checks. |
| `SEC-0144` | **Sev 1** | Buffer Overflow / Resource Leak | `src/libbn/sphmap.c:35-315` | `FIXED` | Heap buffer overflow in bn_spm_pix_load which allocated nx*nx*3 bytes instead of nx*ny*3 while reading nx*ny*3 bytes; permanent memory leak of buffer on fread failure; out-of-bounds array reads and writes in bn_spm_read, bn_spm_write, and bn_spm_get when u or v >= 1.0 or negative; bn_spm_free checked magic number before checking for NULL pointer. |
| `SEC-0145` | **Sev 2** | Uninitialized Memory Read | `src/libbn/str.c:42-177` | `FIXED` | bn_decode_mat, bn_decode_quat, and bn_decode_vect copied uninitialized stack memory into destination buffers when sscanf matched fewer items than required or failed; missing NULL pointer checks across decode and encode routines. |
| `SEC-0146` | **Sev 2** | Null Pointer Dereference / Resource Leak | `src/libbn/tabdata.c:35-1215` | `FIXED` | Second pass fopen in bn_read_table_and_tabdata was unchecked, causing NULL pointer dereference in bu_fgets if reopening failed; memory leak of allocated table/tabdata on read failure; unsigned integer underflow in bn_table_delete_sample_pnts when i > j; NULL pointer dereference in bn_table_free and bn_tabdata_free. |
| `SEC-0147` | **Sev 2** | Undefined Behavior | `src/libbn/ulp.c:118-204` | `FIXED` | Referenced non-existent union member d in union flt_bits (val.d += 1 and minVal.d = 1 << 23); undefined behavior in signed 32-bit shift 1 << 52 when setting 64-bit exponent. |
| `SEC-0148` | **Sev 1** | Resource Leak | `src/libbn/wavelet.c:170-625` | `FIXED` | Permanent memory leaks in make_wlt_haar_2d_decompose, make_wlt_haar_2d_reconstruct, and make_wlt_haar_2d_decompose2 when tbuffer/tbuf is NULL because allocated buffers were never freed; missing NULL buffer and zero dimension validation across wavelet routines. |
| `SEC-0149` | **Sev 1** | Null Pointer Dereference | `src/libbn/tests/test_util.c:48-265` | `FIXED` | Missing NULL pointer checks in test helper and test dispatch functions (mat_close, vect_close, hvect_close, finite_vec, orthonormal_rotation, normalize_quat, make_table, make_tabdata, bn_api_single, and bn_api_dispatch) when called with NULL pointers or empty argument lists. |
| `SEC-0150` | **Sev 1** | Out-of-Bounds Read | `src/libbg/pca.cpp:55-80` | `FIXED` | bg_pca computed Thin U on a 3xnpnts matrix using JacobiSVD. When npnts < 3, Thin U has fewer than 3 columns, causing out-of-bounds column reads and assertions when indexing svd.matrixU()(row, 1) and svd.matrixU()(row, 2). |
| `SEC-0151` | **Sev 2** | Logic / Format String Flaw | `src/libbg/pointgen.c:35-60` | `FIXED` | bg_sph_sample referenced undeclared variable sample instead of pnts[i], used %d format specifier for size_t integers in bu_log, checked sample instead of center for translation offset, and lacked defensive NULL pointer validation on pnts. |
| `SEC-0152` | **Sev 2** | NULL Pointer Dereference | `src/libbg/sat.cpp:44-175` | `FIXED` | bg_sat_line_aabb, bg_sat_line_obb, bg_sat_tri_aabb, bg_sat_tri_obb, bg_sat_aabb_obb, and bg_sat_obb_obb called v3_from_array and axis_and_extent_from_vect without verifying point_t and vect_t pointer arguments, leading to null pointer dereferences. |
| `SEC-0153` | **Sev 2** | NULL Pointer Dereference | `src/libbg/lseg_lseg.cpp:37-45` | `FIXED` | bg_distsq_lseg3_lseg3 unpacked input point arrays without null pointer validation and lacked extern C linkage in its C++ definition. |
| `SEC-0154` | **Sev 2** | NULL Pointer Dereference | `src/libbg/lseg_pt.cpp:36-45` | `FIXED` | bg_distsq_lseg3_pt indexed point coordinates without checking for null pointers. |
| `SEC-0155` | **Sev 2** | NULL Pointer Dereference / Domain Error | `src/libbg/tri_pt.cpp:37-60` | `FIXED` | bg_tri_closest_pt indexed triangle vertices and sample points without null pointer checks and computed std::sqrt(result.sqrDistance) without non-negative clamping. |
| `SEC-0156` | **Sev 2** | NULL Pointer Dereference | `src/libbg/tri_ray.cpp:43-70` | `FIXED` | intersect_triangle and vec3_from_array dereferenced point and vector arguments without checking for null pointers. |
| `SEC-0157` | **Sev 2** | Divide by Zero / NULL Pointer Dereference | `src/libbg/util.c:50-145` | `FIXED` | coplanar_2d_coord_sys scaled origin by 1.0/n without verifying n >= 3, leading to division by zero if n <= 0 and undefined behavior for degenerate point sets. coplanar_3d_to_2d and coplanar_2d_to_3d lacked null checks on pointer parameters and count validation. |
| `SEC-0158` | **Sev 3** | NULL Pointer Dereference / Deprecated Keyword | `src/libbg/aabb_ray.c:31-143` | `FIXED` | bg_ray_invdir lacked null check on dir; bg_isect_aabb_ray lacked null checks on invdir, aabb_min, aabb_max, and opt; wrote into *r_min and *r_max without verifying destination pointers were non-null; used deprecated register storage class keywords. |
| `SEC-0159` | **Sev 3** | Validation Flaw | `src/libbg/obr.cpp:95-100` | `FIXED` | bg_3d_coplanar_obr accepted point count < 3 even though a 3D coplanar coordinate system requires at least 3 points to determine a plane normal. |
| `SEC-0160` | **Sev 1** | Buffer Overflow / Stack Buffer Corruption & Divide by Zero | `src/libbg/polygon.c:144-205` | `FIXED` | Operator precedence flaw in bg_3d_polygon_centroid where *cent[1] and *cent[2] evaluate to *(cent[1]) and *(cent[2]), writing 24 and 48 bytes out of bounds past caller's point_t stack/heap memory; uninitialized accumulation; division by zero when polygon is perpendicular to XY or XZ projection planes. |
| `SEC-0161` | **Sev 2** | Out-of-bounds Read / Memory Leak | `src/libbg/chull.c:50-185` | `FIXED` | Out-of-bounds read and negative deque index in bg_polyline_2d_chull when vertex count n < 3; permanent memory leaks in bg_3d_coplanar_chull of points_tmp and overwritten hull_2d pointer; missing NULL checks. |
| `SEC-0162` | **Sev 2** | Out-of-bounds Read / Memory Leak | `src/libbg/chull2.cpp:50-230` | `FIXED` | Out-of-bounds read and negative deque index in bg_polyline_2d_chull2 for n < 3; permanent memory leak of polyline in bg_2d_chull2; missing NULL parameter checks. |
| `SEC-0163` | **Sev 2** | Divide by Zero / Thread-Safety Race Condition | `src/libbg/clip.c:60-140` | `FIXED` | Division by zero in bg_lseg_clip for vertical or horizontal line segments; thread-safety race condition in bg_ray_vclip due to static local variables diff, sv, st, mindist, maxdist causing concurrent raytracing thread conflicts. |
| `SEC-0164` | **Sev 2** | Memory Leak / Unchecked Return Value | `src/libbg/polygon_triangulate.cpp:873-970` | `FIXED` | Unchecked return value of fopen in bg_tri_plot_2d causing NULL pointer dereference; permanent memory leaks of holes_array container and tri_out_pts in bg_polygon_triangulate; missing validation on polygon contour points. |
| `SEC-0165` | **Sev 2** | NULL Pointer Dereference | `src/libbg/tri_tri.c:180-715` | `FIXED` | bg_tri_tri_isect_with_line unconditionally wrote to *coplanar, *isectpt1, and *isectpt2 without verifying destination pointers were non-null; missing NULL vertex validation across all triangle-triangle intersection routines. |
| `SEC-0166` | **Sev 2** | NULL Pointer Dereference / Divide by Zero | `src/libbg/polygon_op.cpp:45-470` | `FIXED` | Unchecked NULL pointer dereferences in bg_find_polygon_area, bg_polygons_overlap, load_polygon, and clipping routines; potential division by zero on zero scale factor. |
| `SEC-0167` | **Sev 2** | Integer Underflow / Out-of-bounds Read | `src/libbg/polygon_point_in.c:40-51` | `FIXED` | bg_pnt_in_polygon underflows j = nvert - 1 when nvert == 0 and allows nvert < 3 which is geometrically invalid for polygons; missing NULL pointer checks on pnts and test. |
| `SEC-0168` | **Sev 3** | Out-of-bounds Read / Degenerate Buffer Access | `src/libbg/chull3d.cpp:115-210` | `FIXED` | bg_3d_chull and bg_3d_chull2 did not check for empty vertexBuffer or undersized indexBuffer before allocating and indexing; out-of-bounds access in bg_3d_chull2 if face index exceeded vmap size. |
| `SEC-0169` | **Sev 3** | Spatial Partitioning Stride Corruption / Resource Leak | `src/libbg/vert_tree.c:140-180, 260-430` | `FIXED` | Stride indexing corruption in bg_vert_tree_add_w_norm where vertex coordinate data was accessed with stride 3 instead of stride 6 (ptr->vleaf.index * 3 vs index * 6), causing spatial partitioning corruption and reading wrong coordinate/normal data; permanent memory leaks in bg_vert_tree_destroy which failed to free the_array when the_tree was NULL and failed to free the bg_vert_tree container structure. |
| `SEC-0170` | **Sev 2** | Truncated Integer Division / Overflow | `src/libbg/decimate.cpp:55-70, 160-175` | `FIXED` | Truncated integer division in trimesh_decimate_simple (1/cbin.size()) where 1 / cbin.size() evaluated to integer 0 for any bin with >1 point, collapsing the point accumulator to world origin [0,0,0] instead of the bin centroid; missing n_ifaces integer overflow guard. |
| `SEC-0171` | **Sev 2** | Out-of-bounds Read / Unhandled Exception | `src/libbg/delaunator.hpp:40-55, 240-305` | `FIXED` | Out-of-bounds vector read in sum() on empty vector (indexing x[0]); out-of-bounds vector read and crash in Delaunator constructor when n < 3 or when seed points i0 or i1 are uninitialized (accessing coords[2 * INVALID_INDEX]); unhandled exception in bg_polygon_triangulate when Delaunator encounters degenerate collinear input. |
| `SEC-0172` | **Sev 2** | Unchecked Error Code / Parameter Validation | `src/libbg/ballpivot.cpp:30-75` | `FIXED` | Unchecked negative return code in bg_3d_ballpivot (if (nfaces == 0) instead of if (nfaces <= 0)), allowing negative face count to be passed into bg_trimesh_3d_gc; missing validation for radii_cnt < 0 or radii_cnt > 0 with NULL radii; missing initial NULL assignment to output pointers. |
| `SEC-0173` | **Sev 1** | Unchecked File Operation / Null Dereference | `src/libbg/RTree.h:465-480, 1740-1800` | `FIXED` | Unchecked fopen() return value in RTree::plot() and RTree::plot2d() leading to NULL pointer dereference on file write failure; missing NULL check on filename in RTFileStream::OpenRead and RTFileStream::OpenWrite; unguarded VertexDataSource count on NULL pointer in QuickHull.hpp. |
| `SEC-0174` | **Sev 1** | Defensive Parameter Validation | `src/libbg/polygon_triangulate.cpp:560-585` | `FIXED` | Missing parameter validation in bg_detria for faces, num_faces, poly, poly_pnts, pts, holes_array, holes_npts, and steiner, which could cause segmentation faults when called with NULL or undersized inputs. |
| `SEC-0175` | **Sev 3** | Pointer Corruption / Memory Leak / Logic Error | `src/libbg/trimesh.cpp:368-379, 458-465, 754, 789` | `FIXED` | In get_unmatched_edges, &unmatched was passed instead of unmatched to bg_trimesh_unmatched_edges with bg_trimesh_edge_gather, corrupting pointer memory; unmatched->count was used uninitialized in bu_calloc; edge_list was leaked permanently. In bg_trimesh_hanging_nodes, unmatched was leaked on all paths and memcpy was undersized (num_edges * 2 bytes instead of num_edges * 2 * sizeof(int)). In bg_trimesh_solid, a false positive solid result occurred when unmatched edges were zero but misoriented or excess edges existed, leaking memory and passing NULL to memcpy. |
| `SEC-0176` | **Sev 2** | Out-of-Bounds Memory Access / Buffer Overflow | `src/libbg/trimesh.cpp:812, 840-848, 876-878` | `FIXED` | Missing vertex index bounds validation in bg_trimesh_aabb, bg_trimesh_area, and bg_trimesh_volume allowed out-of-bounds reads into point array p and out-of-bounds writes into visit_vert bitvector when called with corrupted or invalid mesh face data. |
| `SEC-0177` | **Sev 2** | Logic Error / Inverted Topology Map | `src/libbg/trimesh_diff.cpp:67-77, 206-255, 313-348` | `FIXED` | In bg_trimesh_diff, ind_map_1 and ind_map_2 inverted the mapping from original to sorted vertex indices (ind_map[i] = orig_ind instead of ind_map[orig_ind] = i), and tri_2 indexed with f1 instead of f2, ignoring mesh 2 face data; bg_trimesh_hash had the same mapping inversion and an early break in its minimum vertex search loop; dbl_clamp could trigger float overflow on non-positive tolerance. |
| `SEC-0178` | **Sev 2** | Unchecked Exception / Memory Leak / Input Validation | `src/libbg/spsr.cpp:52-54, 105-178` | `FIXED` | In bg_3d_spsr, missing parameter validation on points, normals, and face pointers allowed NULL pointer dereferences; num_input_pnts < 3 caused solver failures; negative cnt in PtStream caused unsigned overflow; unhandled C++ exceptions escaping the extern C boundary leaked implicit solver memory and aborted the program. |
| `SEC-0179` | **Sev 2** | Unchecked File Operation / Null Pointer Dereference / Division by Zero | `src/libbg/trimesh_isect.cpp:56-74, 95-245, trimesh_plot3.cpp:82, 351-372` | `FIXED` | In trimesh_isect.cpp, plot_faces called pl_color on unchecked fopen() return, causing NULL pointer dereference on file write failure; bg_trimesh_isect failed to validate vertex indices in faces_1 and faces_2 against vertex counts, risking OOB access, and never assigned output intersecting faces. In trimesh_plot3.cpp, pntset_2d_plot3 used bitwise OR (!p | !c); polyline_2d_plot3 allowed division by zero on scale <= 0.0 and loop condition i < xy.size() - 1 dropped the last vertex before closing. |
| `SEC-0180` | **Sev 1** | Input Validation / Integer Overflow / Exception Safety | `src/libbg/trimesh_remesh.cpp:82-87, trimesh_repair.cpp:126-131, trimesh_split.cpp:94-192, trimesh_sync.cpp:122` | `FIXED` | Missing vertex index validation, integer overflow guards on face counts / allocation sizes, and unhandled C++ exceptions escaping extern C functions in bg_trimesh_remesh, bg_trimesh_repair, bg_trimesh_separate, bg_trimesh_split, and bg_trimesh_sync. |
| `SEC-0181` | **Sev 1** | Undefined Behavior / Data Loss / Out-of-Bounds Memory Access | `src/libbg/GTE/Mathematics/TriMesh.h:208-212, 536-580, 595-650, 715-775` | `FIXED` | status(EdgeHandle e) used reinterpret_cast<EdgeStatus&> on std::vector<bool>::operator[] proxy bit-reference yielding undefined behavior; TriMesh::garbage_collection() wiped face connectivity before reading vertices destroying active geometry; multiple handle and iterator methods lacked index bounds validation. |
| `SEC-0182` | **Sev 2** | Input Validation / Integer Overflow / Denial of Service | `src/libbg/GTE/Mathematics/BotSmooth.h:85-115, BotSubdivide.h:48-95, 330-360` | `FIXED` | Unchecked face vertex indices allowed out-of-bounds reads into vertex coordinate arrays in gte_bot_smooth and gte_bot_subdivide; unconstrained subdivision recursion levels allowed exponential memory allocation and integer overflow. |
| `SEC-0183` | **Sev 2** | Input Validation / Division by Zero / Matrix Solvability | `src/libbg/GTE/Mathematics/LSCMParameterization.h:96-120, 160-220, 275-310` | `FIXED` | Missing vertex index bounds checking on boundaryIndices, interiorIndices, and triangle vertex references when indexing vertices3D in MapBoundaryToCircle and Parameterize; unchecked linear system matrix dimensions could lead to division by zero or invalid memory access in SolveSymmetricCG. |
| `SEC-0184` | **Sev 2** | Out-of-Bounds Memory Access / Input Validation | `src/libbg/GTE/Mathematics/MeshHoleFilling.h:275-320, 520-560, MeshPreprocessing.h:130-155, 225-255` | `FIXED` | Unchecked triangle vertex indices allowed out-of-bounds reads in ComputeEarScore3D, ComputeTriangulationArea, TriangulateHoleLSCM, and MeshPreprocessing::ComputeTriangleArea / ComputeSignedVolume / RemoveSmallComponents. |
| `SEC-0185` | **Sev 3** | Null Pointer Dereference / Out-of-Bounds Array Access | `src/libbg/GTE/Mathematics/MeshQuality.h:230-236, MeshValidation.h:122-138, 220-250, MeshRepair.h:200-215, 430-495, 600-630, 990-1005` | `FIXED` | MeshQuality::ComputeTriangleRaw lacked null pointer validation for raw vertex pointers; MeshValidation::HasSelfIntersections and TriangleBoxesOverlap lacked empty mesh and vertex index bounds validation; MeshRepair lacked vertex index bounds validation in computeTotalArea, DetectIsolatedVertices, ColocateVertices, RelativeOrientation, Dissociate, and RemoveIsolatedVertices. |
| `SEC-0186` | **Sev 2** | Unsigned Integer Underflow / Out-of-Bounds Memory Access | `src/libbg/tests/polygon_op.c:55-80, 240-270` | `FIXED` | In _bg_polygon_diff, offset calculation size_t p2_ind = ((offset + j) >= c1->num_points) ? (j - offset) : (offset + j); produces an unsigned integer underflow when j < offset, wrapping p2_ind to SIZE_MAX and causing an out-of-bounds array access. In addition, unvalidated dcr2 dereferencing could crash on empty polygons, and plot_files contained a contour array dimension mismatch. |
| `SEC-0187` | **Sev 2** | Stack Buffer Overflow / Potential Null Pointer Dereference | `src/libbg/tests/bgtester.c:85-115, 230-260` | `FIXED` | In parse_case, parameter arrays d, l, i, u were fixed 50-element stack buffers populated in a while loop without bounds checking, allowing stack buffer overflows on inputs exceeding 50 parameters. In main, token strings returned by strtok were dereferenced without checking for NULL. |
| `SEC-0188` | **Sev 3** | Null Pointer Dereference / Logical Indexing Flaw | `src/libbg/tests/chull.c:40-70, obr.c:45-75` | `FIXED` | In plot2d_chull, plot_chull3d, and plot_obr, fopen results were passed directly to pl_color and fclose without NULL verification, risking null pointer crashes if file creation failed. Additionally, plot2d_chull indexed pnt_array[i][0] when closing the polygon loop instead of pnt_array[0][Y]. |
| `SEC-0189` | **Sev 3** | Division by Zero / Unchecked Parsing / Missing Pointer Validation | `src/libbg/tests/plane_dist.c:35-50, lseg_pt.c:45-65, geogram_optimizer.cpp:55-80` | `FIXED` | In plane_dist.c, relative error calculation performed division by expected_return without checking for zero, resulting in division by zero (NaN/Inf). In lseg_pt.c, sscanf return counts were unchecked, allowing uninitialized stack values to be used. In geogram_optimizer.cpp, converged_optimizer was dereferenced without checking for NULL. |
| `SEC-0190` | **Sev 3** | Resource Leak / Memory Management | `src/libbg/tests/poly2tri.c:110-180, chull.c:120-170, chull3d.c:70-130` | `FIXED` | Dynamically allocated vertex, face, hole, and output polygon arrays allocated via bu_calloc/bu_malloc in poly2tri.c, chull.c, and chull3d.c were never freed prior to test completion or return, resulting in systematic memory leaks. |
| `SEC-0191` | **Sev 3** | Resource Leak / Null Pointer Dereference | `src/libbg/tests/polygon_triangulate.c:48-62, 134-150, 184-192, 225-237, 269-281, 298-306` | `FIXED` | Dynamically allocated face index arrays allocated by bg_poly_triangulate and bg_nested_poly_triangulate across all five test cases were never released via bu_free prior to block exit, causing memory leaks. In addition, _tess_report lacked validation guarding against NULL face and point arrays. |
| `SEC-0192` | **Sev 2** | Out-of-Bounds Substring / Unchecked Pointer Dereference | `src/libbg/tests/tri_ray_isect.cpp:44-64, tri_tri_isect_coplanar.cpp:41-61` | `FIXED` | In read_point(), if an empty or whitespace-only argument was supplied, find_first_not_of returned std::string::npos, causing substr(sp, ep-sp+1) to throw an unhandled std::out_of_range exception. Additionally, input pointers p and arg were not validated before use, and sscanf return values in main were unchecked. |
| `SEC-0193` | **Sev 3** | Uninitialized Stack Memory / Unchecked Input Parsing | `src/libbg/tests/tri_tri_isect.c:31-66, tri_closest_pt.c:43-53` | `FIXED` | In tri_tri_isect.c, stack variables f1 and f2 were left uninitialized in declaration float f1, f2, f3 = 0.0;, and sscanf return counts were unchecked across all coordinate arguments in tri_tri_isect.c and tri_closest_pt.c, risking calculation using uninitialized stack coordinates upon malformed input. |
| `SEC-0194` | **Sev 3** | Null Pointer Dereference Guard / Code Quality | `src/libbg/tests/trimesh_sync.c:109-130, tri_area.c:49-53` | `FIXED` | In trimesh_sync.c, error reporting function parrays() dereferenced ff and ctrl pointers without verifying that they were non-NULL, risking null pointer dereferences during error handling. In tri_area.c, an extraneous duplicate semicolon was cleaned up. |
| `SEC-0195` | **Sev 2** | Out-of-Bounds Memory Access / Buffer Overflow | `src/libbg/geogram/NL/nl_matrix.c:765-780` | `FIXED` | In nlSparseMatrixConstruct, the row array was allocated with capacity m (NL_NEW_ARRAY(NLRowColumn, m)), but the row initialization loop mistakenly iterated up to n (for (i=0; i<n; i++)). If the column count n exceeded the row count m, this resulted in an out-of-bounds write past the allocated row buffer; if n < m, rows from n to m-1 remained uninitialized. |
| `SEC-0196` | **Sev 1** | Logic Error / Broken Comparator | `src/libbg/geogram/NL/nl_matrix.c:132-143` | `FIXED` | In nlCoeffCompare, the comparator callback returned (((NLCoeff*)(p2))->index < ((NLCoeff*)(p1))->index), returning only 0 or 1. It violated strict weak ordering required by qsort/bu_sort (never returning negative values when p1 < p2), risking non-deterministic sort order or sorting anomalies. |
| `SEC-0197` | **Sev 2** | Format String / Type Mismatch & Division by Zero | `src/libbg/geogram/NL/nl_blas.c:1440-1455, 1495-1510` | `FIXED` | In host_blas_show_stats, nlBlasGFlops() returns a double, but was passed to nl_printf using %d format specifier, risking register/stack corruption on 64-bit platforms. Furthermore, nlBlasGFlops() divided by elapsed_time without checking for zero elapsed time. |
| `SEC-0198` | **Sev 2** | Divide-by-Zero / Floating Point Exception | `src/libbg/geogram/NL/nl_api.c, src/libbg/geogram/NL/nl_preconditioners.c:nl_api.c:660-675, nl_preconditioners.c:110-130, 215-265` | `FIXED` | In nlNormalizeRow, the normalization divided by vector norm without checking if the norm was zero, leading to division by zero on degenerate rows. In Jacobi and SSOR preconditioners (nlNewJacobiPreconditioner, nlSparseMatrixMultLowerInverse, nlSparseMatrixMultUpperInverse), diagonal entries were divided without guards against zero diagonal entries. |
| `SEC-0199` | **Sev 1** | Macro Hazard / Null Pointer Dereference Guard | `src/libbg/geogram/NL/nl_private.h, src/libbg/geogram/NL/nl_os.c, src/libbg/geogram/NL/nl_amgcl.cpp:nl_private.h:288-300, nl_os.c:55-135, nl_amgcl.cpp:178-195` | `FIXED` | NL_DELETE and NL_DELETE_ARRAY macros expanded to multiple unbracketed statements (free(x); x = NULL), creating dangerous syntax and logic errors when used inside unbraced single-line conditionals. Error reporting and assertion handlers in nl_os.c lacked NULL checks on function pointers and format arguments. AMGCL solver interface in nl_amgcl.cpp lacked NULL checks on context, matrices, and vectors. |
| `SEC-0200` | **Sev 3** | Buffer Overflow / Logic Error in Dimension Check | `src/libbg/geogram/basic/attributes.cpp:390-405` | `FIXED` | In AttributesManager::copy_attribute, the compatibility check between existing attribute and destination attribute tested if ((store->size() != new_store->size()) && (store->dimension() != new_store->dimension()) && (store->element_size() != new_store->element_size())) using logical AND (&&) instead of logical OR (||). If the attributes had matching dimensions but differing element counts, the condition evaluated to false, allowing memcpy to copy an oversized source buffer into an undersized destination buffer, causing a critical heap buffer overflow. |
| `SEC-0201` | **Sev 2** | Memory Leak / Missing Destructor & Dangling Pointer | `src/libbg/geogram/basic/thread_sync.h:150-227` | `FIXED` | BasicSpinLockArray allocated heap memory via new spinlock[size_in], but lacked a destructor (~BasicSpinLockArray()), causing all allocated spinlock arrays to be leaked upon destruction. Furthermore, BasicSpinLockArray::clear() deleted the array without resetting size_ to 0 or spinlocks_ to nullptr, and CompactSpinLockArray::clear() did not reset spinlocks_ to nullptr, leaving dangling pointers. |
| `SEC-0202` | **Sev 2** | Memory Management Flaw / Out-of-Bounds Read & Write | `src/libbg/geogram/basic/packed_arrays.cpp, src/libbg/geogram/basic/packed_arrays.h:packed_arrays.cpp:90-185, packed_arrays.h:160-165` | `FIXED` | In PackedArrays, calloc return values were not checked for allocation failure. In resize_array, realloc(ZV_[array_index], 0) was invoked when shrinking to <= Z1_block_size_, risking platform-dependent memory leaks or undefined behavior, and the realloc return was directly assigned without failure handling. Array accessors (get_array, set_array, resize_array, array_size) lacked bounds checks on array_index in release mode. |
| `SEC-0203` | **Sev 2** | Integer Underflow & Unbounded Stack Allocation | `src/libbg/geogram/basic/parallel.cpp, src/libbg/geogram/basic/permutation.h, src/libbg/geogram/basic/attributes.cpp:parallel.cpp:67-85, permutation.h:158-240, attributes.cpp:160-180` | `FIXED` | In parallel_for, if from >= to, unsigned integer subtraction to - from underflowed to a massive positive number (~4 billion), causing thread spawning loops with out-of-bounds tasks. In Permutation::apply and AttributeStore::swap_items, BRLCAD_ALLOCA was invoked unconditionally on element sizes, risking stack overflow on large elements. In Permutation::apply(vector<T>&, ...), mismatch between data size and permutation size was not checked, violating documented contract and causing out-of-bounds access. |
| `SEC-0204` | **Sev 1** | Macro Precedence Hazards & Divide-by-Zero / Floating-Point Exception | `src/libbg/geogram/basic/assert.h, src/libbg/geogram/basic/memory.h, src/libbg/geogram/basic/geometry_nd.h, src/libbg/geogram/basic/rationalg.h, src/libbg/geogram/basic/vecg.h:assert.h:145-215, memory.h:390-485, geometry_nd.h:215-295, rationalg.h:540-550, vecg.h:180-195` | `FIXED` | Assertions in assert.h were defined with raw braces { ... } rather than do { ... } while(0), causing dangling-else and syntax errors in conditional contexts. geo_aligned_alloca macro parameter was unparenthesized. Memory::aligned_allocator::allocate lacked integer overflow check on size * sizeof(T). triangle_area lacked max(A2, 0.0) guard causing sqrt(negative) NaNs, and triangle_circumcenter divided by determinant without zero check. rationalg::estimate() divided by denominator without zero check. vecng initializer_list constructor lacked bounds check on iteration count. |
| `SEC-0205` | **Sev 2** | Out-of-Bounds Memory Access & Integer Overflow | `src/libbg/geogram/mesh/index.h, src/libbg/geogram/mesh/mesh.h, src/libbg/geogram/mesh/mesh.cpp:index.h:70-130, mesh.h:200-475, mesh.cpp:115-460` | `FIXED` | In MeshCells::pop(), cell_ptr_[nb()-1] was accessed unconditionally; simplicial meshes store an empty or single-element cell_ptr_, resulting in heap out-of-bounds reads. In MeshVertices::copy, point_ptr(0) was called when rhs.nb() == 0, accessing beyond empty buffers. In Mesh::get_subelements_by_type and get_subelements_by_index, invalid queries dereferenced null pointers *(MeshSubElementsStore*)nullptr. Index classes left buffer arrays uninitialized in default constructors. create_sub_elements and reserve lacked integer multiplication overflow guards. In connect_tets and connect, corrupt facet/cell vertex indices were not validated against vertices_.nb(). |
| `SEC-0206` | **Sev 2** | Divide-by-Zero & Out-of-Bounds Vector Access | `src/libbg/geogram/mesh/mesh_AABB.h, src/libbg/geogram/mesh/mesh_AABB.cpp:mesh_AABB.h:45-1250, mesh_AABB.cpp:35-180` | `FIXED` | In ray_triangle_intersection, 1.0 / det was calculated prior to checking whether fabs(det) >= 1e-20, causing floating-point division by zero and NaN/Inf propagation on rays coplanar to triangle planes. Querying or intersecting AABB trees built on empty meshes (nb() == 0) accessed bboxes_[1] out-of-bounds and caused infinite recursion in max_node_index. |
| `SEC-0207` | **Sev 1** | Divide-by-Zero & Denial of Service / Process Abort | `src/libbg/geogram/mesh/mesh_geometry.h, src/libbg/geogram/mesh/mesh_geometry.cpp, src/libbg/geogram/mesh/mesh_halfedges.cpp:mesh_geometry.h:210-240, mesh_geometry.cpp:80-160, mesh_halfedges.cpp:60-145` | `FIXED` | mesh_facet_center and mesh_cell_center divided by corner/vertex counts without checking for empty facets/cells (0 count). In mesh_geometry.cpp, normalize was called on zero vectors, and bounding box functions did not validate null output pointers or zero-vertex meshes. In MeshHalfedges, border and vertex traversals on non-manifold or cyclical meshes aborted the process via geo_assert_not_reached or geo_assert(count < 10000) instead of gracefully failing. |
| `SEC-0208` | **Sev 2** | Out-of-Bounds Memory Access, Stack Exhaustion & Process Abort | `src/libbg/geogram/mesh/mesh_repair.cpp, src/libbg/geogram/mesh/mesh_preprocessing.h, src/libbg/geogram/mesh/mesh_preprocessing.cpp, src/libbg/geogram/mesh/mesh_topology.cpp:mesh_repair.cpp:65-175, 490-590, 665-685, 820-840, 920-1010, 1145-1215; mesh_preprocessing.h:77; mesh_preprocessing.cpp:65-135; mesh_topology.cpp:48-105` | `FIXED` | In repair_connect_facets, v2c[v1], c2f[c2], and next_c_around_v[c] were indexed without validating vertex/corner indices against mesh element counts, causing out-of-bounds array reads. facet_is_degenerate and normalize_facet_vertices_order performed unbounded BRLCAD_ALLOCA stack allocations for vertex arrays on arbitrary polygonal facets without heap fallback, causing stack overflow vulnerabilities. find_corner, repair_propagate_orientation, and SimplePriorityQueue::pop aborted the process on malformed topological meshes via geo_assert_not_reached. mesh_colocate_vertices_no_check indexed old2new without bounds checks. In mesh_preprocessing.cpp and mesh_topology.cpp, empty meshes or unbound attributes resulted in out-of-bounds indexing in component traversal and signed volume calculation. |
| `SEC-0209` | **Sev 2** | Divide-by-Zero & Out-of-Bounds Buffer Indexing | `src/libbg/geogram/mesh/mesh_reorder.cpp, src/libbg/geogram/mesh/mesh_remesh.cpp:mesh_reorder.cpp:280-295, 430-445, 570-585, 935-945, 1115-1175; mesh_remesh.cpp:75-80, 125-140, 150-165, 205-255, 285-295, 470-505` | `FIXED` | In mesh_reorder.cpp, Base_fcmp::center and Base_ccmp::center computed 1.0 / double(nb_vertices) without checking nb_vertices == 0, causing floating-point division by zero; Base_tcmp accessed 4 cell vertices without validating vertex count. In mesh_remesh.cpp, remesh_smooth and mesh_adjust_surface crashed or had undefined behavior on empty meshes or meshes with dimension < 3; mesh_adjust_surface divided by double(d) on facets with 0 vertices; create_ribbon_on_border called normalize on zero-length normal vectors, causing NaNs. |
| `SEC-0210` | **Sev 2** | Divide-by-Zero & Buffer Overflow | `src/libbg/geogram/mesh/mesh_sampling.h:mesh_sampling.h:68-95, 120-165, 215-265, 285-335` | `FIXED` | In mesh_generate_random_samples_on_surface and mesh_generate_random_samples_in_volume, division by total area (Atot) and total volume (Vtot) occurred without checking Atot <= 0.0 or Vtot <= 0.0, resulting in division by zero and NaN sample coordinates on degenerate meshes. mesh_facet_mass and mesh_tetra_mass lacked bounds checking on facet/cell vertex counts and attribute arrays, potentially reading out of bounds. |
| `SEC-0211` | **Sev 2** | Out-of-Bounds Memory Access & Assertion Abort | `src/libbg/geogram/delaunay/delaunay.cpp, src/libbg/geogram/delaunay/delaunay.h:delaunay.cpp:115-180, 245-290; delaunay.h:200-245` | `FIXED` | In delaunay.cpp (update_v_to_cell, update_cicl, get_neighbors_internal, save_histogram), missing bounds checks on vertex and cell indices allowed out-of-bounds writes to v_to_cell_ and cicl_ on corrupted mesh topology or NO_INDEX vertices. In save_histogram, an off-by-one check (histogram.size() <= N instead of < N) allowed out-of-bounds array writes. In delaunay.h, geo_assert_not_reached() was called on unlinked cells causing process crashes instead of graceful failure. |
| `SEC-0212` | **Sev 2** | Stack Exhaustion & Unbounded Allocation | `src/libbg/geogram/delaunay/delaunay_nn.cpp:delaunay_nn.cpp:120-195, 230-310` | `FIXED` | In delaunay_nn.cpp (enlarge_neighborhood, store_neighbors_CB, get_neighbors_internal), unbounded BRLCAD_ALLOCA was used for neighbor candidate and distance arrays proportional to requested neighbor counts. High neighbor counts or deep recursion could exhaust thread call stacks causing stack overflow crashes. Additionally, float equality comparison against 0.0 triggered compiler warnings. |
| `SEC-0213` | **Sev 2** | Stack Exhaustion & Unbounded Allocation | `src/libbg/geogram/points/colocate.cpp:colocate.cpp:85-150` | `FIXED` | In Colocate::find_nearest_neighbors, unbounded BRLCAD_ALLOCA was invoked per point for neighbor query arrays based on requested neighbor counts, creating risk of stack overflow on large neighbor queries. |
| `SEC-0214` | **Sev 3** | Uninitialized Memory, Out-of-Bounds Access & Infinite Recursion | `src/libbg/geogram/points/kd_tree.cpp, src/libbg/geogram/points/kd_tree.h:kd_tree.h:110-145; kd_tree.cpp:180-260, 410-480, 520-600` | `FIXED` | In kd_tree.h, KdTree::NearestNeighbors constructor initialized loop condition with nb_neighbors (which was 0) instead of nb_neighbors_max, leaving neighbor index and distance arrays uninitialized and leaking memory to user callers via copy_to_user(). In kd_tree.cpp, AdaptiveKdTree::split_kd_node failed to clamp split point m, resulting in child nodes duplicating parent intervals [b, e) and causing infinite recursion and call stack exhaustion. KdTree::get_nearest_neighbors_leaf used fixed-size stack arrays local_idx[MAX_LEAF_SIZE] without checking e - b <= MAX_LEAF_SIZE. BalancedKdTree::get_node and AdaptiveKdTree::get_node lacked bounds checks on node index n. |
| `SEC-0215` | **Sev 2** | Out-of-Bounds Access & Assertion Abort | `src/libbg/geogram/points/nn_search.cpp, src/libbg/geogram/points/nn_search.h:nn_search.h:70-90; nn_search.cpp:45-75` | `FIXED` | In nn_search.cpp (get_nearest_neighbors), query point index q_index was not validated against nb_points(), risking out-of-bounds point access. In nn_search.h (get_nearest_neighbor), geo_assert(result < nb_points()) triggered process abort when no neighbors were found on empty point sets instead of returning NO_INDEX. |
| `SEC-0216` | **Sev 3** | Memory Corruption & Heap Buffer Under-Allocation | `src/libbg/geogram/numerics/multi_precision.cpp, src/libbg/geogram/numerics/multi_precision.h:multi_precision.h:115-125; multi_precision.cpp:80-145, 595-610` | `FIXED` | In multi_precision.cpp, Pools allocator used slot sizes smaller than sizeof(void*) on 64-bit platforms, causing heap corruption when casting to freelist pointers; missing null check in free; missing integer overflow guard on expansion capacity. |
| `SEC-0217` | **Sev 2** | Out-of-Bounds Memory Access & Integer Underflow | `src/libbg/geogram/numerics/multi_precision.cpp:multi_precision.cpp:215-230, 240-275, 305-330, 680-720` | `FIXED` | In multi_precision.cpp, compress_expansion underflowed index m on lengths <= 1, causing out-of-bounds heap memory access; scale_expansion_zeroelim, fast_expansion_sum_zeroelim, fast_expansion_diff_zeroelim read out-of-bounds on zero-length expansions; assign_sq_dist and assign_dot_at underflowed dimension dim == 0 causing infinite recursion. |
| `SEC-0218` | **Sev 2** | Assertion Failure Denial-of-Service Crashes | `src/libbg/geogram/numerics/predicates.cpp, src/libbg/geogram/numerics/PCK.h:PCK.h:170-175; predicates.cpp:445-460, 620-635, 960-975, 1130-1145, 1395-1410, 1535-1550` | `FIXED` | In predicates.cpp, exact predicate implementations aborted via SIGABRT on geo_assert(Delta_sign != ZERO) on degenerate/collinear inputs instead of gracefully returning ZERO; PCK.h SOS() asserted on invalid mode. |
| `SEC-0219` | **Sev 2** | Mathematical Logic Flaw & Missing Pointer Validation | `src/libbg/geogram/numerics/predicates.cpp, src/libbg/geogram/numerics/predicates.h, src/libbg/geogram/numerics/PCK.cpp:PCK.cpp:25-35; predicates.h:260-275; predicates.cpp:1640-2260` | `FIXED` | In predicates.cpp (PCK::dot_3d), det_3d_filter was erroneously invoked instead of dot_3d_filter; geometric predicates lacked null pointer checks on double* coordinate inputs; percent() lacked division by zero protection. |
| `SEC-0220` | **Sev 3** | Use-After-Free / Dangling Pointer & Missing Null Validation | `src/libbg/geogram/voronoi/RVD.cpp:1754-1775, 1810-1855, 2480-2500, 2535-2587` | `FIXED` | In prepare_projection(), mesh_vertices_ held a raw pointer to a local vector<double> destroyed upon function return, causing project_points_on_surface() to read through a dangling pointer (use-after-free). In RestrictedVoronoiDiagram::create, delaunay was dereferenced prior to checking for null pointer. |
| `SEC-0221` | **Sev 2** | Buffer Overflow, Integer Shift Overflow, Unchecked Realloc & Vector Stack Underflow | `src/libbg/geogram/voronoi/generic_RVD_utils.h, src/libbg/geogram/voronoi/generic_RVD_vertex.h:generic_RVD_utils.h:45-55, 275-290, 345-385; generic_RVD_vertex.h:175-195, 240-260, 270-300, 725-770` | `FIXED` | In generic_RVD_utils.h, VectorStack::pop() called pop_back() on empty vectors causing out-of-bounds underflow; array_capacity computed 1 << (result - 1) with 32-bit signed shift that overflowed on large capacities; and insert() directly reassigned realloc return pointers without failure validation. In generic_RVD_vertex.h, small_set appended past capacity DIM without bounds checks; PointAllocator lacked chunk allocation failure handling and bounds checks. |
| `SEC-0222` | **Sev 2** | Denial-of-Service Assertion Aborts & Unchecked Pointer Dereferences | `src/libbg/geogram/voronoi/generic_RVD_cell.cpp, src/libbg/geogram/voronoi/generic_RVD_polygon.cpp, src/libbg/geogram/voronoi/RVD_callback.cpp, src/libbg/geogram/voronoi/RVD.cpp:generic_RVD_cell.cpp:635-645, 1020-1040; generic_RVD_polygon.cpp:520-530; RVD_callback.cpp:80-95; RVD.cpp:1620-1695, 2410-2420, 2580-2585` | `FIXED` | In side_exact, initialize_from_surface_mesh, triangulate_polygon, run_thread, and RestrictedVoronoiDiagram::create, assertions geo_assert and geo_assert_not_reached were triggered on non-simplex facets, unexpected topology, or unhandled dimensions, terminating the process via SIGABRT. |
| `SEC-0223` | **Sev 2** | Out-of-Bounds Access, Missing Null Guards & Zero Division | `src/libbg/geogram/voronoi/CVT.cpp, src/libbg/geogram/voronoi/CVT.h:CVT.h:120-140, 195-215; CVT.cpp:60-80, 135-155, 175-195, 230-260, 310-340, 360-390` | `FIXED` | In CVT.cpp and CVT.h, constructors and member methods accepted Mesh* and double* pointers without null validation, accessed empty embedding vectors, and performed unvalidated indexing and division when dimension_ or point counts were zero. |
| `SEC-0224` | **Sev 2** | Division by Zero, Out-of-bounds Vector Access & Dimension Validation | `src/libbg/geogram/third_party/LBFGSpp/include/LBFGS.h:LBFGS.h:170-175, 230-240; LBFGSB.h:205-215; BFGSMat.h:115-125, 270-340, 480-505; BKLDLT.h:80-95, 125-140, 160-175; Cauchy.h:120-145, 175-190; LineSearchMoreThuente.h:34-55, 71-125; LineSearchNocedalWright.h:42-50, 94-98; Param.h:210, 368; SubspaceMin.h:44-58, 134-138` | `FIXED` | In LBFGSpp optimization routines, missing zero guards on matrix determinants, Hessian eigenvalues, line search denominators, and empty input vector dimensions allowed potential divisions by zero, infinite loops, and out-of-bounds array access on degenerate or singular optimization problems. |
| `SEC-0225` | **Sev 2** | Out-of-bounds Array Access, Null Dereference, Division by Zero & Traversal Flaw | `src/libbg/geogram/third_party/amgcl/amgcl/adapter/zero_copy.hpp, src/libbg/geogram/third_party/amgcl/amgcl/amg.hpp, src/libbg/geogram/third_party/amgcl/amgcl/backend/builtin.hpp, src/libbg/geogram/third_party/amgcl/amgcl/backend/detail/matrix_ops.hpp, src/libbg/geogram/third_party/amgcl/amgcl/backend/interface.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/detail/galerkin.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/plain_aggregates.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/pointwise_aggregates.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/smoothed_aggr_emin.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/smoothed_aggregation.hpp, src/libbg/geogram/third_party/amgcl/amgcl/coarsening/tentative_prolongation.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/inverse.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/qr.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/sort_row.hpp, src/libbg/geogram/third_party/amgcl/amgcl/detail/spgemm.hpp, src/libbg/geogram/third_party/amgcl/amgcl/make_solver.hpp, src/libbg/geogram/third_party/amgcl/amgcl/preconditioner/dummy.hpp, src/libbg/geogram/third_party/amgcl/amgcl/relaxation/spai0.hpp, src/libbg/geogram/third_party/amgcl/amgcl/reorder/cuthill_mckee.hpp, src/libbg/geogram/third_party/amgcl/amgcl/solver/cg.hpp, src/libbg/geogram/third_party/amgcl/amgcl/solver/skyline_lu.hpp, src/libbg/geogram/third_party/amgcl/amgcl/util.hpp, src/libbg/geogram/third_party/amgcl/amgcl/value_type/interface.hpp` | `FIXED` | In AMGCL solver and preconditioner routines, missing bounds checks on row/column indices and negative aggregate IDs allowed out-of-bounds array reads and writes. Missing checks for singular pivots, zero denominators, and zero spectral radius allowed divisions by zero. Unchecked matrix and vector pointers allowed null pointer dereferences. A loop condition logic error in Cuthill-McKee reordering skipped node 0 during graph level set traversal. |
| `SEC-0226` | **Sev 2** | Null Pointer Dereference, Division by Zero, Out-of-bounds Array Access | `src/libbrep/BBNode.cpp, src/libbrep/BRNode.cpp, src/libbrep/PullbackCurve.cpp, src/libbrep/Subcurve.cpp, src/libbrep/Subsurface.cpp, src/libbrep/assembly.cpp, src/libbrep/boolean.cpp, src/libbrep/brep_defines.h` | `FIXED` | In libbrep core evaluation, trimming, assembly, and pullback routines, missing null checks on curve, surface, face, and child pointers could result in null pointer dereferences. Missing checks against zero denominators in cubic curve interpolation, knot intervals, Newton solver steps, and basis control ratio calculations could cause division by zero. Edge index parameters in edge merging routines lacked array bounds checks before indexing brep edge tables. |
| `SEC-0227` | **Sev 2** | Null Pointer Dereference, Division by Zero, Out-of-bounds Index, Resource Leak | `src/libbrep/px_event.cpp, src/libbrep/ssx_event.cpp, src/libbrep/quality.cpp, src/libbrep/edit.cpp, src/libbrep/debug_plot.cpp` | `FIXED` | In px_event.cpp, Compare() returned inverted null-pointer values and used boolean instead of 3-way integer comparison for sorting. In ssx_event.cpp, DumpSSXEvent() unconditionally dereferenced m_curveA, m_curveB, and m_curve3d without null checks. In quality.cpp, bbox_contains() evaluated an invalid point, and edge quality iteration lacked vertex and trim index bounds validation. In edit.cpp, brep_edge_create() lacked curve/vertex index bounds checks, and calculateTangentVectors(), getPosRoot(), bsplineBasisFuns(), and solveTridiagonalint() had unguarded divisions by potentially-zero denominators. In debug_plot.cpp, write_plot_to_file() used fopen() result without null check. |
| `SEC-0228` | **Sev 2** | Null Pointer Dereference, Out-of-bounds Vector Access, Resource Leak | `src/libbrep/cdt/cdt.cpp, src/libbrep/cdt/cdt_util.cpp, src/libbrep/cdt/mesh.cpp, src/libbrep/cdt/ovlps_simple.cpp, src/libbrep/cdt/surf.cpp, src/libbrep/cdt/tri_isect.cpp` | `FIXED` | In cdt.cpp and ovlps_simple.cpp, missing size validation and null pointer checks on bedge_seg_t::uedges() results caused potential out-of-bounds access and null pointer dereference. In mesh.cpp, bedge_seg_t::uedges() lacked trim index bounds checking and null pointer validation. Across mesh.cpp, cdt_util.cpp, tri_isect.cpp, and surf.cpp, pervasive unchecked fopen() return values in debug plot functions caused potential NULL pointer dereferences. |
| `SEC-0229` | **Sev 2** | Memory Access Violation, Out-of-bounds Array Access, Memory Leaks, Division by Zero, Null Pointer Dereference | `src/libbrep/shape_recognition/cone.cpp, src/libbrep/shape_recognition/cylinder.cpp, src/libbrep/shape_recognition/pipeline.cpp, src/libbrep/shape_recognition/planar.cpp, src/libbrep/shape_recognition/shape_recognition.cpp, src/libbrep/shape_recognition/sphere.cpp, src/libbrep/shape_recognition/sr_util.cpp, src/libbrep/shape_recognition/torus.cpp` | `FIXED` | In planar.cpp, an off-by-one loop condition j <= array_end - array_start caused out-of-bounds read and write in triangulate_array_with_holes; outer_pt_ind, holes arrays, vert_map, and loop_starts leaked on every triangulation; BU_PTBL_GET dereferenced empty island_children causing null dereference crash; in cylinder.cpp, points[3] was accessed without checking points count > 3, and implicit_plane_ind was indexed without bounds checks; in cone.cpp, loop over cone planes indexed plane 1 when count was 1, and sin(C) was divided without zero checking; in pipeline.cpp, nde array leaked across multiple return paths, and nonplanar_surfaces was dereferenced when empty; in shape_recognition.cpp, unchecked fol_to_i iterator dereference caused crash, subbrep_shoal_data leaked when shoal_csg failed, and face_surface_types and uninserted sb leaked on failure; in sr_util.cpp, BU_PUT for obj->nucleus erroneously freed subbrep_shoal_data with struct csg_obj_params size/tag, and empty face->m_li caused out-of-bounds loop access; in sphere.cpp, a typo c2->IsArc(NULL, &a1) left a2 uninitialized and leaked curve duplicates c1 and c2; in torus.cpp, arc loop leaked curve ecv and ep_normal was incorrectly set to torus.plane.Normal(). |
| `SEC-0230` | **Sev 2** | Memory Leaks, Uncontrolled Recursion, Out-of-bounds Array Access, Null Pointer Dereference, Logic Error | `src/libbrep/tools/tools.cpp, src/libbrep/tools/tools_util.cpp, src/libbrep/tests/brep_cdt_hole_face17.c, src/libbrep/tests/brep_cdt_hole_face27.c, src/libbrep/tests/brep_cdt_invalid.cpp, src/libbrep/tests/brep_cdt_mesh.cpp, src/libbrep/tests/assembly.cpp, src/libbrep/tests/ppx.cpp, src/libbrep/tests/pullback_context.cpp, src/libbrep/tests/test_curve_intersect.cpp, src/libbrep/tests/test_point_intersect.cpp` | `FIXED` | In libbrep tools and tests: in tools.cpp, find_next_point placed recursion limit inside else block, causing infinite recursion and stack exhaustion; ON_Curve_Get_Tangent and ON_Curve_Has_Tangent lacked null pointer and direction bounds checks; in ON_Surface_IsStraight, frames[0] and frames[1] were repeatedly indexed instead of frames[i] and frames[j]; in tools_util.cpp, ON_BrepTikz leaked duplicate edge curves on non-linear edges, and lacked null pointer and array bounds checks; in brep_cdt_mesh.cpp, invalid argument count printed usage but proceeded without exiting, dereferencing invalid argv[1]; in brep_cdt_hole_face17.c and brep_cdt_hole_face27.c, multiple heap-allocated arrays leaked on test completion; across test executables, argv[0] was passed to bu_setprogname without validating argc > 0 and argv != NULL. |
| `SEC-0231` | **Sev 2** | Infinite Loop Denial of Service, Null Pointer Dereference, Division by Zero, Missing Bounds Validation | `src/libfft/fftfast.c, src/libfft/splitdit.c, src/libfft/ditsplit.c, src/libfft/fftc.c, src/libfft/ifftc.c, src/libfft/splitditc.c, src/libfft/ditsplitc.c, src/libfft/fftest.c` | `FIXED` | In libfft routines: init_sintab infinite loop on invalid size, unchecked calloc returns, cdiv zero division, and missing null pointer and bounds checks across forward/inverse FFT transforms and test generators. |
| `SEC-0232` | **Sev 2** | Buffer Overflow, Out-of-Bounds Array Access, Division by Zero & Missing Pointer Validation | `src/libtermio/libtermio.h, src/libtermio/linenoise.hpp` | `FIXED` | In libtermio: terminal parameter arrays sized FOPEN_MAX lacked fd bounds checks, FD_SET lacked fd bounds checks in termio_getch, EditHistoryNext used unbounded strcpy, EditInsert lacked buffer capacity checks, and refresh lines divided by unchecked cols_. |
| `SEC-0233` | **Sev 2** | Out-of-Bounds Array Access, Division by Zero, and Missing Pointer Validation | `src/libpc/gecode_librt_test.cpp, src/libpc/solver_test.cpp, src/libpc/vm_test.cpp, src/libpc/domain_constraint_propagator.cpp, src/libpc/cartesian-heart.cpp, src/libpc/gecode_solver_test.cpp` | `FIXED` | In libpc: unchecked point indices in geometry constraint helpers, null dereference in solver test functors and parameter access, zero division in math VM test, and unchecked Space* pointers in domain constraint propagators. |
| `SEC-0234` | **Sev 2** | Use-After-Free, Double-Free, Buffer Overflow, and Resource Leaks | `src/nirt/main.cpp, src/nirt/showshot.c` | `FIXED` | In nirt: premature db_close caused use-after-free, double-free on failure cleanup, double pclose/fclose on shared output stream, leaked rt_read_cmd buffers, unbounded rname copy in showshot, and unchecked radius input. |
| `SEC-0235` | **Sev 2** | Heap/Stack Buffer Overflow, Pointer Underflow, and Memory Leaks | `src/bwish/cmd.c, src/bwish/input.c, src/bwish/main.c` | `FIXED` | In bwish/btclsh: wrong struct size in historyInit realloc, missing capacity check in history_record_priv, off-by-one read in inputHandler, size_t underflow in processChar, negative pointer arithmetic in editing handlers, and unchecked fd in FD_SET. |
| `SEC-0236` | **Sev 2** | Format String Bugs, Division Errors, File Descriptor Leaks, and Bounds Checks | `bench/clean.c, bench/compute.c, bench/run.c, bench/pixcmp.c, bench/benchmark.c` | `FIXED` | In bench suite: vls accumulation bug and memory leak in clean.c, off-by-one element count causing negative division in compute.c, passing bu_vls by value to %s in run.c, argv[1] OOB access and file descriptor leaks in pixcmp.c and benchmark.c. |
| `SEC-0237` | **Sev 2** | Buffer Bounds, Resource Leaks, Null Dereferences, and Out-of-Bounds Memory Access | `src/art/tile.cpp, src/art/brlcadplugin.h, src/art/brlcadplugin.cpp, src/art/art.cpp` | `FIXED` | In art Appleseed integration: missing frame/fbp checks and row offset calculation in tile.cpp, missing rt_i_destroy and thread index clamping in brlcadplugin.cpp, leaked ged instances and open dbip in art.cpp, and leaked temporary vls buffers. |
| `SEC-0238` | **Sev 2** | Buffer Overflow, Out-of-bounds Array Access, Null Pointer Dereference, and Input Validation | `src/launcher/launcher.c, src/launcher/registry.c, src/launcher/launch.c, src/launcher/fbtext.c, src/launcher/ui_fb.c, src/launcher/ui_text.c` | `FIXED` | In launcher: unchecked argc/argv in main, null pointer dereference in list_apps, unchecked registry growth and bu_dir results, framebuffer vertical row bounds checks in draw_char, and button action index bounds checks in ui_fb.c. |
| `SEC-0239` | **Sev 2** | Buffer Overflow, Memory Leaks, Division by Zero, Null Pointer Dereference, and Out-of-Bounds Memory Access | `src/isst/gfile.h, src/isst/gfile.cpp, src/isst/isstgl.h, src/isst/isstgl.cpp, src/isst/main.cpp, src/isst/main_window.cpp, src/isst/isstapp.cpp` | `FIXED` | In isst: uninitialized GFile members and memory leaks in closedb(), static gcvwriter global state, out-of-bounds array write in nmg_to_adrt_internal, out-of-bounds vertex indexing and leaked intern in nmg_to_adrt_regstart, leaked db_path_to_string buffers, uninitialized camera in TIERenderer, division by zero in resize(), null tie dereference in render(), missing render mutex in set_tie(), and unchecked argc/argv in main. |
| `SEC-0240` | **Sev 1** | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Array Access, and Null Pointer Dereferences | `src/libbv/*` | `FIXED` | In libbv: fixed display list and scene object leaks, division by zero in camera and knob math, and array bounds in polygon and clipping routines. |
| `SEC-0241` | **Sev 1** | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libdm/*` | `FIXED` | In libdm: fixed color map out-of-bounds write risks, integer overflow in getmem, division by zero in reshape/aspect, and resource leaks across display manager backends. |
| `SEC-0242` | **Sev 2** | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libgcv/*` | `FIXED` | In libgcv: fixed float-to-integer conversion in bottess, uninitialized memory reads in OBJ/PLY plugins, division by zero across converters, and intermediate geometry leaks. |
| `SEC-0243` | **Sev 2** | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 1)` | `FIXED` | In libged Batch 1: fixed memory leaks and double-free hazards on wdb_put_internal, stack buffer overflow in adc, division by zero across analyze/arot/arrange, and ARS/ARB bounds checks. |
| `SEC-0244` | **Sev 2** | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 2: bot, brep)` | `FIXED` | In libged Batch 2: fixed rt_db_internal initialization/free leaks and double-frees, array bounds on vertices/faces/trims, division by zero in normals/decimation/scale, and NULL pointer checks across bot and brep subcommands. |
| `SEC-0245` | **Sev 2** | Memory Leaks, Double-Free, Division by Zero, Infinite Loop, Array Out-of-Bounds, and File Descriptor Leaks | `src/libged (Batch 3: cc, check, coil, color, columns, comb, comb_std, combmem, concat, constraint, copymat, cpi, dbi_state, debug2c)` | `FIXED` | In libged Batch 3: fixed double-frees following rt_db_put_internal and freed internal representation on db_diradd failures across cc, cpi, comb, comb_std, and copymat; added NULL guards, division-by-zero checks on units, heap VLS frees, and plot file descriptor leak fixes in check; plugged memory leaks of sections, validated sscanf, and prevented division by zero in coil; fixed cnt != 5 typo and temp file leak in color; added NULL checks in columns; freed rt_tree_array in combmem and fixed infinite loop on paren evaluation in comb_std; guarded argv bounds and closed dbip on error exits in concat and constraint; cleaned up view_states and aborted failed transactions in dbi_state; and added file check in debug2c. |
| `SEC-0246` | **Sev 2** | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 4: decompose, delay, display_list, dm, draw, dsp, dump, dup, eac, edcodes)` | `FIXED` | In libged Batch 4: fixed memory leaks on non-NMG solids and db_lookup/db_diradd failures, replaced sprintf with snprintf, and eliminated double-free of new_m in decompose; validated sec/usec in delay; added NULL checks across display list erase/hash helpers and handled invent_solid failure; guarded argc > 0, freed dm_name leaks, and corrected return status in dm; guarded division by zero in aspect ratio, fixed loop index typo, and freed bu_vls in ert; freed dm_name on help path, added ndmp NULL guard, fixed argv bounds, and freed idata on failure in screengrab; guarded division by zero, plugged db_intern leaks in csg_wireframe_update and brep_adaptive_plot, and cleaned up draw_scene error paths in draw; resolved TODO by freeing dgcdp, plugged ap leak, and prevented duplicate ptbl initializations in bigE; freed brep_intern and obj_path in draw.c; guarded dbi_state and corrected view state lookup loop in draw2; prevented size_t underflows, freed tcl_argv, fixed orientation quaternion bounds, and guarded against division by zero in loadview; prevented buffer overflow in ged_cm_tree, checked argc >= 2 before fopen, and freed gd_rt_cmd and ged_tmp_uptrs in preview; validated xy argument count, fixed off-by-one bounds check, fixed intern2 typo in diff subcommand, and freed intern on lookup/read errors in dsp; used wdb_close in dump; enforced max_entries check to prevent array bounds overflow in dup; freed vls on read error, checked ID_COMBINATION, and used rt_db_free_internal in eac; added NULL pointer checks in comparisons, checked argc >= 2, freed av on fopen error, and used rt_db_free_internal in edcodes. |
| `SEC-0247` | **Sev 2** | Memory Leaks, Double-Free, Dangling Pointer, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 5: edit)` | `FIXED` | In libged Batch 5 (edit commands): eliminated double-free hazards where rt_db_free_internal was called after GED_DB_PUT_INTERN in edarb and facedef; added ARB edge bounds check and validated argc in facedef; scoped bn_tol to function scope in cmd_checkpoint::exec to prevent dangling s->tol; freed intern and container struct on all paths and prevented double-free of pintern in cmd_perturb; guarded attribute NULL pointers and empty strings across rotate_*, scale_*, and translate_*; prevented floating-point division by zero on vector magnitudes across scale_* commands; and guarded uri constructor against NULL text pointer. |
| `SEC-0248` | **Sev 2** | Memory Leaks, Out-of-bounds Memory Access, Logic Errors, and Null Pointer Dereferences | `src/libged (Batch 6: editit, edmater, env, env2c, erase, erase2, exec, exists, expand, eye_pos)` | `FIXED` | In libged Batch 6: fixed bu_opt_desc array indexing collision (d[0]..d[4]) and option parse error handling in editit; corrected argc passed to wmater, guarded argc <= 1, and aligned malloc tags in edmater; guarded NULL gedp and validated argc in env; validated argc range, checked bu_opt_parse return, and caught std::exception in env2c; plugged new_argv and bu_vls memory leaks, guarded avs bounds, and corrected option skipping in erase; checked bu_opt_parse, guarded argc <= 0 and bvs NULL in erase2; guarded argv[0] NULL dereference, checked gedp->i->i, and unwound recursion counters and exec_stack on recursion limit exceeded in exec; guarded out-of-bounds pointer advances and NULL dereferences in exists grammar and token lexer; reset backslash state per argument, used bu_vls_putc, and guarded string NULLs in expand; and corrected unit conversion factor from dbi_base2local to dbi_local2base when setting eye position in eye_pos. |
| `SEC-0249` | **Sev 2** | Use-After-Free, Memory Leaks, Double-Free, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 7: facetize)` | `FIXED` | In libged Batch 7 (facetize): fixed Cat 1 Use-After-Free of wgedp database handle across iterative meshing attempts in brep.cpp; fixed 4 BU_PUT struct type mismatches and eliminated double-free in nmg.cpp; guarded division by zero on obj_bbox_vol, freed temporary bot faces/vertices on retry/abort, eliminated duplicate bounding box check, ensured bot is freed on all exits, replaced mismatched calloc with bu_calloc, and paired BU_GET with BU_PUT for manifold_mesh in old_facetize.cpp; validated stderr FD and NULL pointers in old_facetize_log.c; fixed memory leaks and eliminated double-frees in regions.cpp; fixed kill argument layout in subprocess/brep_csg.cpp; freed candidate bot on retry and fixed BU_PUT type in subprocess/continuation.cpp; freed cache_dir and checked seed in subprocess/main.cpp; verified ft_tessellate in subprocess/nmg.cpp; checked obj_bbox_vol with ZERO in subprocess/sample.cpp; checked point cloud bounds in subprocess/spsr.cpp; added NULL/empty guards in subprocess/util.cpp; freed temporary bu_vls in tess_opts.h; eliminated duplicate curtree allocation, freed td_name, and used bu_calloc in tri.cpp; and validated inputs, freed intern on diradd failure, and closed wdbip on error exits in util.cpp. |
| `SEC-0250` | **Sev 2** | Memory Corruption, Memory Leaks, Resource Leaks, Catastrophic Data Loss Hazard, Recursion Lockout Bug, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 8: fb2pix, fbclear, form, fracture, garbage_collect, gdiff, ged, ged_cmd_scanner, ged_exec, ged_init)` | `FIXED` | In libged Batch 8: validated image dimensions and guarded fclose against stdout/NULL in fb2pix; replaced float literal comparisons, handled unquoted RGB args, and routed errors to ged_result_str in fbclear; reordered argc check ahead of db open and formatted error messages in form; freed old_intern, guarded log10(0), fixed cross-model region bug, eliminated global static status, freed model on diradd failure, and expanded string buffers in fracture; plugged bu_external leak, guarded division by zero, prevented database deletion on backup failure, checked db_ls path count, and cleaned up working file on errors in garbage_collect; guarded tolerance lookup, checked path bounds, initialized rt_db_internal, freed in1 on in2 failure, checked ID_COMBINATION, checked msgs NULL, reordered db_lookup before allocating full paths, and checked raydiff results in gdiff; fixed BU_PUT struct type mismatch freeing struct bu_list as struct bu_vls for gd_headDisplay and gd_headVDraw, zeroed ged_cbs on allocation with memset to prevent uninitialized counters triggering false recursive warnings, verified wdbp and dbip before creating ged struct in ged_open, decremented callback recursion depth before error return to prevent permanent callback lockout, and added NULL checks in callback handlers in ged; eliminated duplicate and out-of-bounds argv checks in generated wrappers in ged_cmd_scanner; guarded argv[0] and argc before bu_setprogname and verified plugin function pointers before dispatch in ged_exec; allocated sentinel NULL termination for command array and guarded filenames before path lookup in ged_init. |
| `SEC-0251` | **Sev 2** | Memory Leaks, Buffer Overflow, Double-Free, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 9: inside, track, util, get, get_autoview, get_comb, get_eyemodel, get_obj_bounds, get_solid_kp)` | `FIXED` | In libged Batch 9: eliminated memory leaks on interactive prompts/errors, fixed out-of-bounds argv[2] access, cleared dangling idb_ptr, fixed copy-paste unit_d typo, and guarded negative radicands and division by zero across primitives in ged_inside; resolved 30-year-old swap bug overwriting tr[0] with uninitialized tr[2], expanded track name buffers, replaced sprintf with snprintf, eliminated double-free of intern, freed member lists, and guarded acos/slope against zero divisions and domain errors in ged_track; added bounds check in ged_results_get, validated wdbp and freed previous dbi_title in ged_dbcopy, checked scale factor scans, guarded eye model functions against NULL, freed intern on combadd2 error, and passed correct count to db_mkgift_tree in ged_util; freed intern and logged diagnostics when ft_get unavailable in get; fixed option parsing -p flag bug and validated remaining args in get_autoview; freed intern and rt_tree_array across all exits and used snprintf in get_comb; guarded trace levels to prevent buffer overflow, replaced free with bu_free, freed intern on rt_i_create failure, and validated ft_prep in get_obj_bounds; guarded NULL inputs, checked empty lists before list head access, and guarded vertex/curve pointers in get_solid_kp. |
| `SEC-0252` | **Sev 2** | Memory Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, Logic Errors, and Null Pointer Dereferences | `src/libged (Batch 10: get_type, glob, gqa, graph, grid, grid2model_lu, grid2view_lu, group, heal, help)` | `FIXED` | In BRL-CAD libged Batch 10 commands (get_type, glob, gqa, graph, grid, grid2model_lu, grid2view_lu, group, heal, help): in get_type.c, validated argc and argv[1], initialized rt_db_internal before import, and guarded wdbp; in glob.c, added null checks to _debackslash, _backslash_specials, and _ged_expand_str_glob, checked gp->gl_pathv before string access, added per-word match counting to fall back to unescaping individual patterns when unmatched, and guarded argc and argv in ged_glob_core; in gqa.cpp, added null check on units buffer, constrained num_views (1..3) to prevent fixed-size array out-of-bounds access, guarded region and hit pointers against null in _gqa_overlap, initialized point arrays and passed valid pointer in _gqa_hit, bounded string traversal in find_cmd_line_obj, validated inputs and region count returning error on invalid state in allocate_per_region_data, removed redundant duplicate density file loading, fixed massive memory leaks of intern, density names, and avs across directories in densities_prep, prevented null dereference on strrchr, guarded against division by zero on state->shots across all views in view_reports, weight_volume_terminate, and summary_reports, guarded wdbp, rtip, obj_tbl, reg_tbl, and ged_gqa_plot.vbp before cleanup and destruction, and reset aborted state; in graph.cpp, checked ID_COMBINATION and pointers in process_comb and hl_scan_db, guarded child tree leaf names against null, verified file stream write success in hl_layout_and_output, removed redundant argument shifting in igraph mode and validated subcommand argument; in grid.c, guarded against null gv_s view state in grid_vsnap, grid_vls_print, and ged_grid_core, clamped user RGB color components to 0..255, and corrected error reporting parameter; in grid2model_lu.c, validated argv arguments and checked for zero denominator with ZERO macro before division; in grid2view_lu.c, guarded argv[1] and argv[2] against null; in group.c, validated group name and member arguments against null and empty strings; in heal.c, guarded arguments, clamped negative zipper tolerance, freed internal representation on non-BOT objects, and verified rt_db_put_internal return; in help.cpp, moved directory listing free inside directory traversal loop to eliminate directory listing leak, freed filepath on unreadable files, reset zeros counter per file so a binary file does not disable reading all subsequent documentation files, freed word buffer on each file exit, fixed cntptr type to size_t * preventing memory corruption, and checked bu_dir return before strdup while cleaning up resources when words == 0. |
| `SEC-0253` | **Sev 2** | Resource Leaks, Buffer Overflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 11: help tests, hide, how, human, illum, importFg4Section, plugin.h, inside, instance, isize)` | `FIXED` | In BRL-CAD libged Batch 11 commands (test_help, hide, how, human, illum, importFg4Section, plugin.h, inside, instance, isize): in test_help.c, guarded ac and av pointers before calling bu_setprogname, and called ged_close before return to cleanly shut down GED resources; in hide.c, guarded argv[i] arguments against null or empty strings, tracked write and export failures, and corrected db5_export_object3 invocation; in how.c, initialized dpp, added null guards on hdlp, vls, dpp, and style struct pointer sp->s_os in dl_how, validated argument bounds and pointers, handled -b flag correctly, and guarded gd_headDisplay before traversal; in human.c, replaced process-terminating bu_exit calls with graceful error return in read_args, added null checks on fopen returns before writing to file pointers in text and verbose, validated argc, verified wdb_dbopen return, replaced unchecked sprintf with snprintf, and called wdb_close to eliminate persistent database handle leak; in illum.c, added GED_CHECK_DATABASE_OPEN, GED_CHECK_VIEW, GED_CHECK_DRAWABLE, and GED_CHECK_ARGC_GT_0 to ged_labelvert_core, guarded argv[i] arguments, checked dmp before calling dm_set_dirty, guarded gdlp and obj in dl_set_illum, validated directory pointer and d_namep, checked argv[1] against null using BU_STR_EQUAL, and verified gd_headDisplay; in importFg4Section.c, validated argc and argv pointers, verified wdb_dbopen return, and added wdb_close to eliminate database handle leak; in include/plugin.h, audited plugin macros; in inside.c, guarded argc and argv[1] against null and verified outdp; in instance.c, validated argument count and null/empty object and instance names, guarded argv[3] against null, and safely formatted invalid operation string; in isize.c, added GED_CHECK_DATABASE_OPEN to prevent null dereference of gedp->dbip, and guarded against division by zero using ZERO macro on base2local factor. |
| `SEC-0254` | **Sev 2** | Use-After-Free, Memory Corruption, Memory Leaks, Double-Free, Infinite Loop, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 12: item, joint, joint2, keep, keypoint, kill, killall, killrefs, killtree)` | `FIXED` | In BRL-CAD libged Batch 12: in item.c, validated argc range (3..6), guarded argv[1..2] against null, checked argv[3..5] before atoi, initialized rt_db_internal, and validated combination type; in joint.c, eliminated Cat 1 Use-After-Free in parse_hold by adding missing return after free_hold on EOF, fixed 64-bit struct member memory corruption where hp->priority was passed as double * clobbering flag, fixed infinite loop in joint_move dirs parsing by adding missing argv/argc increment, guarded against division by zero in parse_units with ZERO macro, eliminated persistent memory leaks in free_hold, part_solve, and joint_load by freeing arc sets, joint handles, and bu_vls, added null guards across hold_point_to_string, joint_unload, parse_error, joint_mesh, joint_save, joint_accept, joint_reject, reject_move, joint_solve, joint_hold, joint_move, and joint_cmd, fixed copy-paste typo in joint_reject usage, and corrected return status logic in joint_solve; in joint2.c, verified callback function pointers and selection counts, added bounds check preventing out-of-bounds read of argv[2] when argc == 2, and eliminated Cat 1 Double-Free of intern after GED_DB_PUT_INTERN; in keep.c, guarded directory and component pointers in node_write, closed incoming database on format mismatch and open failures to eliminate file descriptor leaks, and used wdb_close on all exits to properly release wdbp and underlying dbip; in keypoint.c, guarded argv[1..3] against null before bn_decode_vect and sscanf; in kill.c, enforced required object name argument after option stripping and guarded argv[i] in deletion loops; in killall.c, guarded argv[1] on -n check and enforced argument counts reporting usage; in killrefs.c, guarded argv[1], enforced argument count, guarded display erasure and tree deletion loops, and validated combination types; in killtree.c, guarded directory and data pointers in callbacks, enforced argument count after option parsing, guarded argv[i] in processing loop, and unconditionally freed argv allocations to eliminate -n memory leak. |
| `SEC-0255` | **Sev 2** | Use-After-Free, Memory Leaks, Resource Leaks, Integer Underflow, Division by Zero, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 13: label, lc, libfuncs, lint)` | `FIXED` | In BRL-CAD libged Batch 13: in label.c, validated argc and argv bounds before dereferencing argv[0]; in lc.c, guarded against null struct pointers and string fields before bu_strcmp and atoi in cmp_regions and sort_regions, validated argc and argv in ged_lc_core, handled bu_file_realpath null returns and freed norm_name on errors, closed output file and freed vls on error exits, freed results1 and results2 search tables via db_search_free, freed db_full_path root, duplicated attribute strings and freed all duplicated strings on all exits to eliminate Cat 1 Use-After-Free of stack-scoped avs attributes, and replaced descending size_t loop with reverse counting loop to prevent unsigned integer underflow; in libfuncs.c, guarded argv, argv[0], argv[1], and argv[2] before bu_sscanf, bn_decode_mat, and bn_decode_vect across mat_ae, mat_mul, mat4x3pnt, and mat_scale_about_pnt, and added missing newlines to usage strings; in lint/cyclic.cpp, freed path strings allocated by db_path_to_string, replaced process-terminating bu_bomb with graceful error logging, initialized rt_db_internal, and validated ID_COMBINATION and combination pointers; in lint/ged_lint.h, audited header declarations; in lint/invalid_shape.cpp, initialized intern, eliminated memory leaks of BREP, ARB8, DSP, and EXTRUDE internal representations on early returns by calling rt_db_free_internal across all exits, properly initialized and freed pc search table, and guarded directory pointers; in lint/lint.cpp, guarded ostr.pop_back() against empty problem vectors, validated key_val parsing, fixed off-by-one underflow in argument verification loop that caused argv[-1] out-of-bounds reads, freed combination members with mk_freemembers after mk_lcomb, and initialized is_region; in lint/lint_bot.cpp, validated triangle vertex indices against num_vertices and guarded normal magnitude before division in bot_face_normal, bounded triangle indices and vertex indices in tri_to_json and plot_bad_tris, guarded map iterator dereference in bot_check, clamped ncpus to num_faces, set last worker end to num_faces so the final triangle face is not skipped, cleaned per-worker resources with rt_clean_resource, and freed worker state array to eliminate thread resource and memory leaks; in lint/missing.cpp, replaced bu_bomb with graceful error logging, added buffer size checks against header lengths before pointer arithmetic in shape_find_missing to prevent buffer over-reads in DSP and EXTRUDE objects, and initialized and freed rt_db_internal structures across all exits; in lint/raytrace.cpp, verified ID_COMBINATION and tree pointers before traversing combination trees in subtree_has_halfspace and collect_subtree. |
| `SEC-0256` | **Sev 2** | Memory Leaks, Resource Leaks, Integer Overflow, Infinite Loop, and Null Pointer Dereferences | `src/libged (Batch 14: list, lod, lod2, log, ls, lt, m2v_point, make, make_name, man)` | `FIXED` | In BRL-CAD libged Batch 14: in list.c, validated argc and argv bounds, added missing newline to usage, guarded argv[arg] against null, closed wdbp immediately after copying initial tree state to prevent wdbp handle leak, freed full path on traversal failures, initialized and freed internal structures, and guarded describe callbacks; in lod.c, checked argv bounds, guarded against null gvp and gvp->gv_s view state pointers before member access, validated non-negative scale factors using bu_sscanf, and guarded argv subcommands against null; in lod2.cpp, guarded gedp and ged_result_str against null before writing result; in log.c, guarded clientdata and str in log_hook, checked gedp->ged_log before hook operations and log dumps, validated argv[1], and added missing newlines to usage messages; in ls.c, guarded list_of_names and num_in_list in vls_long_dpp and vls_line_dpp, guarded directory pointers and names against null, initialized and freed intern representations, guarded ft_label and binunif typestrings before string length operations, guarded name and type widths against unsigned underflow, guarded argv in _ged_ls_attr_objs and _ged_ls_named_objs, guarded results_obj before formatting, and freed str vls on all exit paths to eliminate memory leaks; in lt.c, initialized intern, validated ID_COMBINATION and pointers before accessing comb tree, freed intern and vls on flatten tree error exit paths to eliminate memory leaks, guarded tree leaf names against null, and validated argv bounds and option characters; in m2v_point.c, guarded argv arguments, added missing newlines to usage, and replaced raw sscanf with bu_sscanf; in make.c, validated positive scale factors, guarded extrude_ip and freed internal on error, replaced sprintf with snprintf, and called rt_db_free_internal on db_diradd failure to eliminate primitive internal memory leaks; in make_name.c, validated argv pointers, added missing newlines, parsed -s argument with bu_sscanf ensuring non-negative index, added loop bounds and overflow guards in candidate generation loop, and avoided redundant null byte injection; in man.c, checked argv bounds, verified brlman path existence, freed lang vls on all early returns to eliminate memory leaks, cleaned up failed subprocess handles with bu_process_wait_n, and waited for CLI mode processes to exit cleanly. |
| `SEC-0257` | **Sev 2** | Memory Corruption, Resource Leaks, Memory Leaks, Out-of-bounds Memory Access, Integer Underflow, and Null Pointer Dereferences | `src/libged (Batch 15: match, mater, material, metaball, mirror, model2grid_lu, model2view, model2view_lu, move, move_all)` | `FIXED` | In BRL-CAD libged Batch 15 commands (match, mater, material, metaball, mirror, model2grid_lu, model2view, model2view_lu, move, move_all): in match.c, added missing newline to usage, guarded argv pointers against null, replaced unchecked pointer increment loop with safe index-bounded loop, and guarded dp and dp->d_namep before bu_path_match; in mater.cpp, freed d_path_dir vls across all exits, closed wdbp handle with wdb_close in mater_import, safely parsed mat_id with bu_sscanf before comparison, eliminated heap allocations for std::set and msgs to prevent memory leaks, freed new_buf from analyze_densities_write and bin_ext on db_dirbuild failure, replaced dynamic heap avs allocation with stack struct and ensured bu_avs_free is invoked on all iterations and exits, guarded oname before std::string conversion, safely parsed integer IDs, returned BRLCAD_ERROR on fail, and freed nname before early returns; in material.c, eliminated Cat 1 memory corruption by removing illegal bu_free on stack buffer, closed densityTable file descriptor on all paths, closed wdbp handle with wdb_close on all exits across import, create, set, and remove, freed AVS property tables on each loop iteration and exit, validated argc bounds before accessing argv indices, guarded string parsing loop against integer underflow, verified ID_MATERIAL internal type before accessing material structure, called rt_db_free_internal on all exit paths, prevented orphaning of bu_vls string buffers by using bu_vls_strcpy/bu_vls_trunc instead of BU_VLS_INIT, and propagated subcommand error return codes; in metaball.c, closed wdbp handle on all paths, verified DB5_MINORTYPE_BRLCAD_METABALL before casting internal pointer, replaced raw sscanf with bu_sscanf, fixed out-of-bounds pointer dereference of argv[3] when argc was 3 in delete error message, and added missing newlines to usage messages; in mirror.c, called rt_db_free_internal on all exit paths after rt_db_get_internal to eliminate primitive memory leaks, replaced raw sscanf with bu_sscanf, and guarded argv pointers against null; in model2grid_lu.c and model2view_lu.c, moved matrix dereferences after GED_CHECK_DATABASE_OPEN to prevent null dereference of gedp, guarded argv arguments, replaced sscanf with bu_sscanf, and added missing newlines; in model2view.c, guarded argv arguments, replaced raw sscanf with bu_sscanf, and added missing newline to usage; in move.c and move_all.c, called rt_db_free_internal after rt_db_put_internal to eliminate memory leaks, replaced libc free with bu_free on heap strings allocated by bu_strdup, safely updated display list path strings, guarded old and new name arguments against null, and fixed format parameter mismatch in name length limit error message. |
| `SEC-0258` | **Sev 2** | Memory Corruption, Use-After-Free, Memory Leaks, Resource Leaks, Out-of-bounds Memory Access, and Null Pointer Dereferences | `src/libged (Batch 16: move_arb_edge, move_arb_face, mrot, nirt, nmg, nmg_cmface, nmg_collapse, nmg_fix_normals, nmg_kill_f, nmg_kill_v)` | `FIXED` | In BRL-CAD libged Batch 16 commands (move_arb_edge, move_arb_face, mrot, nirt, nmg, nmg_cmface, nmg_collapse, nmg_fix_normals, nmg_kill_f, nmg_kill_v): in move_arb_edge.c, closed wdbp handle on all exit paths in move_arb_edge and find_arb_edge, called rt_db_free_internal after rt_db_put_internal to eliminate memory leaks, guarded argv pointers against null, replaced raw sscanf with bu_sscanf, and added missing newlines to usage and error messages; in move_arb_face.c, eliminated Cat 1 memory corruption and stack array overflow by enforcing face bounds check on both positive and negative indices for the specific arb_type before modifying planes array, closed wdbp handle on all paths, called rt_db_free_internal after rt_db_put_internal, returned BRLCAD_ERROR when object is not an ARB, replaced sscanf with bu_sscanf, and added missing newlines; in mrot.c, validated argv and argv[i] pointers against null, and added missing newlines; in nirt.cpp, eliminated Cat 1 heap corruption on subprocess failure by replacing incorrect cast and free of string pointers as bu_vls structures with bu_free, fixed use of freed av_args and memory leak of obj by directly emitting draw commands to stdin in skip_drawn block, freed nirt exec string and nv options across all error returns, corrected loop to inspect argv[i] instead of repeatedly checking argv[0], freed dpv allocated by db_ls, fixed off-by-4 bug in ged_vnirt_core where av[i] = NULL clobbered argument pointers, replaced sscanf with bu_sscanf, guarded ged_gdp before dl_set_wflag, and added missing newlines; in nmg.c, eliminated Cat 1 linked list corruption in get_face_list where actual model face list pointers were stolen into stack f_list causing circular loops and free crashes by using detached copy structs, freed internal representations and face list allocations, fixed off-by-one subcommand lookup in ged_nmg_core where subcmd was erroneously read from argv[0] instead of argv[1], guarded argv[2] before dereferencing in kill, move, and make subcommands, and propagated subcommand return codes; in nmg_cmface.c, freed verts buffer to eliminate persistent memory leaks, closed wdbp handle on all paths, replaced atof with bu_sscanf, corrected variable in error message, and added missing newlines; in nmg_collapse.c, closed wdbp on all exit paths, freed internal representation on non-planar face detection, validated tolerances with bu_sscanf and ZERO macro, and added missing newlines; in nmg_fix_normals.c, persisted fixed normals to database via rt_db_put_internal, freed internal representation, and added missing newlines; in nmg_kill_f.c, eliminated Cat 1 Use-After-Free in remove_face by immediately returning once target face is destroyed by nmg_kfu, closed wdbp on all paths, parsed fid with bu_sscanf, and added missing newlines; in nmg_kill_v.c, eliminated Cat 1 Use-After-Free and Double-Free in remove_vertex by restarting topology search on each deletion instead of continuing iteration on freed loopuses and edgeuses, closed wdbp on all paths, parsed coordinates with bu_sscanf, and added missing newlines. |
| `SEC-0259` | **Sev 2** | Use-After-Free, Memory Leaks, Resource Leaks, Out-of-bounds Memory Access, Logic Errors, and Null Pointer Dereferences | `src/libged (Batch 17: nmg_make_v, nmg_mm, nmg_move_v, nmg_simplify, npush, ocenter, open, orient, orotate, oscale)` | `FIXED` | In BRL-CAD libged Batch 17 commands (nmg_make_v, nmg_mm, nmg_move_v, nmg_simplify, npush, ocenter, open, orient, orotate, oscale): in nmg_make_v.c, validated vertex coordinates with bu_sscanf, closed wdbp handle with wdb_close on error and success paths, freed verts buffer on wdb_put_internal failure, and added missing newlines to usage and error strings; in nmg_mm.c, freed internal representation on db_diradd failure to prevent memory leak, checked rt_db_put_internal return status, and added missing newline to usage; in nmg_move_v.c, validated 6 coordinate arguments using bu_sscanf, closed wdbp handle on error and success exits, reported correct object name on error, and added missing newline to usage; in nmg_simplify.c, eliminated Cat 1 Use-After-Free and database corruption where failure of all conversion methods (arb/tgc/poly) fell through to out1: attempting to add and write a freed/stale new_intern, closed wdbp handle on all exit paths in out3:, and added missing newlines to usage strings; in npush.cpp, eliminated persistent leak of rt_wdb handle by immediately copying tolerance and closing wdbp, freed temporary msgs vls on early exit in non-verbose conflict path, added missing newlines to conflict and error messages, and preserved all missing/added tops reports by using bu_vls_printf instead of bu_vls_sprintf; in ocenter.c, added bounds check on gtd.gtd_objpos to prevent negative array indexing out-of-bounds, replaced sscanf with bu_sscanf, and added missing newlines to usage and error strings; in open.cpp, added missing newlines in usage and error strings, returned BRLCAD_OK when print_help is requested, and safely destroyed existing ged_lod context and dbi_state before reassigning; in orient.c, fixed off-by-one error in error reporting where argv[i-1] was printed instead of argv[i], replaced sscanf with bu_sscanf, and added missing newlines to usage strings; in orotate.c, added bounds check on gtd.gtd_objpos to prevent out-of-bounds array access, replaced sscanf with bu_sscanf, and added missing newlines to usage and error strings; in oscale.c, added scale factor validation with bu_sscanf and SQRT_SMALL_FASTF to prevent degenerate or non-positive scaling, added bounds check on gtd.gtd_objpos, and added missing newlines to usage and error strings. |
| `SEC-0260` | **Sev 2** | Resource Leaks, Double-Free, Buffer Overflow, Logic Errors, Out-of-bounds Memory Access, and Process Termination in Library Function | `src/libged (Batch 18: osg, otranslate, overlay, path, pathlist, pathsum, perspective, pipe, pix2fb, plot)` | `FIXED` | In BRL-CAD libged Batch 18 commands (osg, otranslate, overlay, path, pathlist, pathsum, perspective, pipe, pix2fb, plot): in osg.cpp, added NULL pointer checks to _osgLoadHiddenSolid, _osgLoadSolid, and _ged_osgLoadScene, and verified osp->viewer validity; in otranslate.c, added bounds check on gtd.gtd_objpos preventing negative out-of-bounds array access, replaced sscanf with bu_sscanf, and added missing newlines to usage and error strings; in overlay.c, fixed out-of-bounds / null pointer dereference on argv[1] when bu_file_list returned <= 0 by changing to argv[0], freed vbp on fopen failure inside loop to eliminate memory leak, preserved cmd_name for diagnostics, and added missing newlines; in path.c, fixed critical logic flaw where the return value of path_validate_recurse was ignored allowing invalid paths to pass validation, checked intern.idb_type == ID_COMBINATION, and added missing newline; in pathlist.c, eliminated persistent wdbp database handle leak by immediately calling wdb_close after reading initial tree state, replaced static mutable global pathListNoLeaf with thread-safe struct pathlist_data passed via client_data, checked fp_len > 1 before decrement, and added missing newlines; in pathsum.c, checked _GED_TRACE_MAX_LEVELS upper bound to prevent stack buffer overflow in gtd.gtd_obj, duplicated path argument before calling strtok to avoid in-place mutation of argv and thread safety issues, and added missing newlines; in perspective.c, replaced sscanf with bu_sscanf, added angle range check [0, 180) to prevent division by zero or singularity in persp_mat, and added missing newlines; in pipe.c, eliminated persistent wdbp leaks by calling wdb_close across append, find, and move commands, fixed out-of-bounds argv[3] access when argc == 3 in delete command by correcting to argv[2], eliminated double-free hazards of intern following GED_DB_PUT_INTERN, replaced sscanf with bu_sscanf, checked seg_i >= 0, and added missing newlines; in pix2fb.c, eliminated process termination bug where bu_exit was invoked on file open failure by returning error and logging to ged_result_str, fixed usage string repetition, checked infd > 0 before close, and formatted error messages with argv[0] and newlines; in plot.c, removed mutable static local variables in dl_plot making it reentrant and thread-safe, preserved cmd_name before advancing argv, freed bu_vls str on popen failure, formatted system errors with strerror(errno) into result string, and added missing newlines. |
| `SEC-0261` | **Sev 2** | Memory Leaks, Resource Leaks, Buffer Overflow, Infinite Loop, In-place Argument Mutation, and Null Pointer Dereferences | `src/libged (Batch 19: pmat, pmodel2view, png, png2fb, pnts, pnts_util, points_eval, polyclip, prcolor)` | `FIXED` | In BRL-CAD libged Batch 19 commands (pmat, pmodel2view, png, png2fb, pnts, pnts_util, pnts_util.h, points_eval, polyclip, prcolor): in pmat.c, added diagnostic error message on bn_decode_mat failure and fixed usage formatting; in pmodel2view.c, added missing newline to usage string; in png.c, encapsulated mutable globals in struct png_state, removed static locals from draw_png_solid for thread safety, clamped raster coordinates against image bounds to prevent buffer overflow, clamped img_size to prevent integer overflow in buffer allocation, replaced raw sscanf with bu_sscanf, freed image and bytes buffers and destroyed libpng structures via png_destroy_write_struct on all error and success exits to eliminate persistent memory leaks, and added missing newlines to usage and error messages; in png2fb.c, removed duplicate usage prefix, distinguished file open failure from help request returning error instead of printing usage, replaced stderr writes with bu_log, and added missing newlines; in pnts.cpp, added bounds checks in _pnts_collect_arrays linked list loops to prevent heap buffer overflow, eliminated in-place mutation of caller argv in _ged_pnts_cmd_tri and ged_pnts_core by passing offset pointers and lengths to bu_cmd, propagated subcommand return codes, fixed unsafe argc decrement when argc <= 0, freed fl and unit vls structures on all exits in _ged_pnts_cmd_read, used RAII guard for pnt_str in _ged_pnts_cmd_write to eliminate persistent memory leak on every write operation, freed intern on fopen failure, and added missing newlines to result and error strings; in pnts_util.c, added NULL pointer checks to _ged_pnt_v_set, _ged_pnt_c_set, _ged_pnt_s_set, _ged_pnt_n_set, _ged_pnts_init_head_pnt, _ged_pnts_add, and _ged_pnts_dup; in points_eval.c, guarded d->dbip against NULL, checked fp->fp_len > 0 before calling DB_FULL_PATH_CUR_DIR, and properly initialized intern; in polyclip.cpp, closed wdbp database handles on all exit paths in ged_import_polygon, ged_polygons_overlap, and ged_polygon_fill_segments to eliminate persistent handle leaks, guarded input pointers, validated vfilldelta > SMALL_FASTF to prevent infinite loop hang, freed all 2D polygon contours, contour points, hole arrays, and result_vls on completion in ged_polygon_fill_segments to eliminate massive memory leak, and freed intern on export failure; in prcolor.c, replaced sprintf with snprintf to prevent buffer overflow, and added missing newlines to usage and none output. |
| `SEC-0262` | **Sev 2** | Memory Corruption, Resource Leaks, Double-Free, Pointer Cast Error, and Underflows | `src/libged (Batch 20: prefix, process, ps, pset, pull, push, put, put_comb, putmat, qray)` | `FIXED` | In BRL-CAD libged Batch 20 commands (prefix, process, ps, pset, pull, push, put, put_comb, putmat, qray): in prefix.c, removed leftover debugging bu_log prints, guarded prefix against empty string, guarded directory names against null/empty in rename loop, freed tempstring_v5 on all early error exits to eliminate memory leaks, validated intern.idb_type == ID_COMBINATION before tree walk, and added missing newlines to usage and error strings; in process.c, fixed Cat 1 integer underflow and memory exhaustion in _ged_process_list where longest_pid < 3 underflowed longest_pid - 3 to UINT_MAX - 2 when passed to %*c in bu_vls_sprintf, freed cmdroot before return in _ged_process_gabort to eliminate memory leak, added null guards on subprocess pointers, streamlined subcommand dispatch in ged_process_core to properly display help on unrecognized or malformed arguments, and added missing newlines; in ps.c, removed mutable static local variables in ps_draw_solid making it reentrant and preventing state leakage between solids, replaced sscanf with bu_sscanf, changed early return on bad color to goto bad so font, title, and creator are freed on error, guarded sp and hdlp against null in ps_draw_body, guarded bu_optind > 0 before accessing argv[bu_optind-1], and added missing newlines to usage and error strings; in pset.c, replaced sscanf with bu_sscanf, guarded attribute against null and empty string in _ged_set_metaball, clamped threshold when ZERO(threshold), guarded argv arguments against null, simplified cleanup to unconditionally call rt_db_free_internal(&intern) whenever ret != BRLCAD_OK, and added missing newlines; in pull.c, fixed Cat 1 pointer cast corruption in pull_leaf where mp (mat_t *) was cast to struct bu_vls * and passed to bu_vls_printf, fixed massive memory leak where modified primitives transformed by ft_xform were never written back or freed by adding rt_db_put_internal and rt_db_free_internal, fixed option parsing bug in ged_pull_core where argc != 2 check and db_lookup preceded bu_getopt making -d impossible to pass, passed (matp_t)NULL instead of 0-matrix m to rt_db_get_internal in pull_comb, freed intern on empty comb trees, checked return of bn_mat_inverse, and added missing newlines; in push.c, eliminated persistent resource leak of wdbp by immediately extracting init_state and calling wdb_close(wdbp), guarded argc < 1 after option stripping, guarded null directory and database pointers and freed intern on empty comb trees in identitize, and added missing newlines; in put.c, eliminated Cat 1 double-free of intern where rt_db_free_internal(&intern) was called after wdb_put_internal (which unconditionally frees the internal structure on both success and failure), closed wdbp with wdb_close(wdbp) on both error and success paths to eliminate handle leak, guarded argv[1] and argv[2] against null and empty strings, and added missing newlines; in put_comb.c, eliminated Cat 1 buffer underflow in trailing space stripping loop where empty or all-space names decremented i below 0 and accessed name[-1], fixed logic bug in mktemp_comb where db_lookup checked template string str instead of candidate name, freed rt_tree_array on error and success paths in put_tree_into_comb_and_export to eliminate persistent memory leak, freed intern on db_diradd failure in save_comb, replaced sscanf with bu_sscanf and guarded null str in put_rgb_into_comb, and added missing newlines; in putmat.c, eliminated Cat 1 memory leaks of name1 and name2 in _getmat where bu_vls_free was omitted on all successful matrix retrieval paths, removed machine-identifiable paths from error messages, guarded against null argv[1] and argv[2], and added missing newlines; in qray.cpp, fixed Cat 1 out-of-bounds string access in qray_init when parsing format lines shorter than expected, and added null pointer checks on gdp, gdp->gd_qray_fmts, and vhead in qray_init, qray_free, and qray_data_to_vlist. |
| `SEC-0263` | **Sev 2** | Double-Free, Memory Leaks, Division by Zero, Uninitialized Memory Reads, Pointer Aliasing, and Missing Validation | `src/libged (Batch 21: qray, qray.h, quit, rcodes, rect, red, regdef, region, repair, rfarb)` | `FIXED` | In BRL-CAD libged Batch 21 commands (qray, qray.h, quit, rcodes, rect, red, regdef, region, repair, rfarb): in qray.h, fixed macro parameter bug in DG_QRAY_BOTH; in qray/qray.c, added null checks on gedp->i and gedp->i->ged_gdp across all entry points, replaced sscanf with bu_sscanf, corrected typo in command name, and added missing newlines to error strings; in quit/quit.cpp, verified clean with no changes needed; in rcodes/rcodes.c, eliminated Cat 1 double-free of intern on rt_db_put_internal failure (which unconditionally frees intern internally), eliminated persistent memory leak by freeing intern when changed == 0 or when non-combination objects are encountered, replaced sscanf with bu_sscanf, added null and empty string checks on argv[1], and added missing newlines to usage and error messages; in rect/rect.c, added null check on gedp->ged_gvp->gv_s, added ZERO(grsp->aspect) and cdim <= 0 checks to prevent division by zero in rect_image2view and rect_adjust_for_zoom, validated user coordinate dimensions to prevent division by zero, replaced sscanf with bu_sscanf, guarded argv[0] and argv[1] against null, and added missing newlines; in red/red.c, eliminated mutable file-scope static global buffer _ged_tmpfil by passing stack-allocated buffer into build_comb and write_comb to ensure thread safety, eliminated persistent memory leaks of rt_tree_array across all error and success exits in both build_comb and write_comb, freed intern on all early error paths in build_comb and after write_comb in ged_red_core, freed allocated matrix on error in _ged_find_matrix, replaced sprintf with snprintf to prevent buffer overflow, and added missing newlines; in regdef/regdef.c, guarded wdbp against null return from wdb_dbopen, replaced sscanf with bu_sscanf, and added missing newlines to usage and output strings; in region/region.c, guarded wdbp against null, guarded argv[1], argv[i], and argv[i+1] against null/empty, and added missing newlines to usage and error strings; in repair/repair.cpp, added GED_CHECK_DATABASE_OPEN, GED_CHECK_READ_ONLY, and GED_CHECK_ARGC_GT_0 guards, handled bu_opt_parse error returns, eliminated Cat 1 double-free of intern by only freeing intern when ft_repair returns non-zero (rt_db_put_internal unconditionally frees intern on both success and failure), guarded argv[i] against null/empty, and added newlines to JSON status messages; in rfarb.c, eliminated Cat 1 double-free of internal on rt_db_put_internal failure and returned BRLCAD_ERROR, eliminated memory leak of internal on db_diradd failure, prevented uninitialized stack coordinate usage by returning BRLCAD_ERROR when bu_sscanf coordinate parsing fails, replaced sscanf with bu_sscanf, guarded argv against null, and added missing newlines to all error and usage messages. |
| `SEC-0264` | **Sev 2** | Stack Buffer Overflow, Memory Leaks, Logic Inversion, Out-of-bounds Array Access, Command Length Miscalculation, and Missing Validation | `src/libged (Batch 22: rm, rmap, rmat, rmater, rot, rotate_about, rot_point, rrt, rt, rtabort)` | `FIXED` | In BRL-CAD libged Batch 22 commands (rm, rmap, rmat, rmater, rot, rotate_about, rot_point, rrt, rt, rtabort): in rm.c, fixed boolean CSG tree subtraction bug in _rm_tree_remove_named_leaf_instance where removing the left child of an OP_SUBTRACT node erroneously promoted the right child to a positive union instead of freeing the right tree and nullifying the subtraction, guarded null and empty operands in _rm_expand_operand while preserving unmatched glob patterns for standard error reporting, guarded argv[i] against null/empty in operand loop, and added missing newline to usage string; in rmap.c, added _ged_rmap_free_list helper and called it on rt_db_get_internal failure to eliminate persistent memory leaks of id_to_names and id_names list nodes, validated intern.idb_type == ID_COMBINATION and intern.idb_ptr before casting, replaced bu_vls_addr with bu_vls_cstr, and added missing newlines to usage and error messages; in rmat.c, added null check on argv[1], reported diagnostic error message when bn_decode_mat fails, and added missing newline to usage; in rmater.c, fixed stack buffer overflow in extract_mater_from_line by bounding string extraction to name and shader buffer capacities, replaced raw sscanf with bu_sscanf, prevented undefined behavior and crash by continuing loop instead of falling through on rt_db_get_internal failure, validated intern.idb_type == ID_COMBINATION before accessing comb, used bu_vls_trunc to safely clear comb->shader, and added missing newlines; in rot.c, added standard GED_CHECK_DATABASE_OPEN, GED_CHECK_VIEW, and GED_CHECK_ARGC_GT_0 guards; in rotate_about.c, guarded against out-of-bounds byte reads and null dereference on argv[1], and added missing newlines to current setting output and usage strings; in rot_point.c, fixed copy-paste typo where ged_m2v_point was reported instead of command name, replaced sscanf with bu_sscanf, guarded coordinate arguments against null, and added missing newlines; in rrt.c, fixed command length miscalculation where gd_rt_cmd_len was set only to the count of who objects rather than the full command length, eliminated persistent memory leak of strings allocated by ged_who_argv by freeing each who object after execution, and guarded argv[i] against null; in rt.c, replaced sprintf with snprintf, provided PATH fallback when bu_dir returns null, guarded argv[i] against null, and explicitly null-terminated gd_rt_cmd; in rtabort.c, added null checks on rrp, rrp->p, and cmd before processing and terminating subprocesses, and added missing newline to usage string. |
| `SEC-0265` | **Sev 2** | Resource Leaks, Memory Leaks, Null Pointer Dereferences, Out-of-bounds Memory Access, and Missing Validation | `src/libged (Batch 23: rtcheck, rtcheck2, rtwizard, savekey, scale, search, select, select2, set_output_script, set_transparency)` | `FIXED` | In BRL-CAD libged Batch 23 commands (rtcheck, rtcheck2, rtwizard, savekey, scale, search, select, select2, set_output_script, set_transparency): in rtcheck.c, added null checks in rtcheck_vector_handler and rtcheck_output_handler on rtcp, rrtp, gedp, rtcp->fp, and rrtp->p, provided PATH fallback when bu_dir returns null, allocated args + 1 for gd_rt_cmd, guarded argv[i] against null, and eliminated persistent memory leak of strings allocated by ged_who_argv by freeing each string on error and success paths; in rtcheck2.cpp, added null checks in rtcheck_vector_handler and rtcheck_output_handler on rtcp, rrtp, gedp, rtcp->fp, and rrtp->p, provided PATH fallback when bu_dir returns null, allocated args + 1, guarded argv[i] against null, and freed strings allocated by ged_who_argv on error and success paths; in rtwizard.c, added null checks on gedp and gd_rt_cmd in _ged_run_rtwizard, replaced sprintf with snprintf, allocated args + 1 for gd_rt_cmd, guarded argv[i] against null, and freed strings returned by ged_who_argv upon command completion to eliminate memory leaks; in savekey.c, added null checks on gedp, gvp, fp, and eye_model in savekey_rt_oldwrite, validated time argument with bu_sscanf instead of raw atof and reported error on invalid input, replaced raw perror writes to stderr with structured error logging to ged_result_str, checked argv[1], and added missing newlines to usage and error strings; in scale.c, added GED_CHECK_DATABASE_OPEN, GED_CHECK_VIEW, and GED_CHECK_ARGC_GT_0 guards, validated scale factor against non-positive and non-finite values and reported error instead of silently returning OK, and added missing newline to error message; in search.c, corrected pointer size calculation from sizeof(char *) to sizeof(struct directory *) in _ged_search_localized_obj_list, added missing GED_CHECK_DATABASE_OPEN and GED_CHECK_ARGC_GT_0 guards in ged_search_core, guarded argv_orig[i] against null in option scanning loop, checked bu_argv_dup return value, and bounded plan_argv < argc in both plan discovery and plan string construction loops to prevent out-of-bounds pointer reads; in select.c, plugged persistent leak of rt_wdb database handles opened via wdb_dbopen by ensuring wdb_close is called immediately after import or upon error in both ged_select_core and ged_rselect_core, guarded ged_gvp->gv_s before accessing screen rectangle, freed intern on early error paths, replaced raw sscanf with bu_sscanf, added missing newlines to all error and usage messages, and added null checks on botip, botip->vertices, hdlp, and vls; in select2.cpp, added GED_CHECK_DATABASE_OPEN and GED_CHECK_ARGC_GT_0 guards in ged_select2_core, guarded argv[i] in option loop, safely checked argc <= 0 before indexing argv[0] in subcommand dispatch, added null checks in _select_cmd_msgs, and added missing newlines in _select_cmd_add and _select_cmd_rm; in set_output_script.c, added missing newline to usage, and guarded against passing null ged_output_script to %s in bu_vls_printf; in set_transparency.c, added GED_CHECK_DATABASE_OPEN guard, returned GED_HELP on argc == 1, replaced raw sscanf with bu_sscanf, clamped transparency to [0.0, 1.0], returned BRLCAD_ERROR when _ged_build_dpp fails, added null checks on gedp, i, ged_gdp, dpp, hdlp, and sp->s_os in dl_set_transparency, and added missing newlines to usage messages. |
| `SEC-0266` | **Sev 2** | Resource Leaks, Memory Leaks, Double-Free, Division by Zero, Mutating Input, and Null Pointer Dereferences | `src/libged (Batch 24: set_uplotOutputMode, setview, shaded_mode, shader, shells, showmats, shrinkwrap, simulate)` | `FIXED` | In BRL-CAD libged Batch 24 commands (set_uplotOutputMode, setview, shaded_mode, shader, shells, showmats, shrinkwrap, simulate): in set_uplotOutputMode.c, added null and empty string guards on argv[1] before inspecting characters, and appended missing newlines to usage, binary, and text output strings; in setview.c, added null checks on argv[1] when argc == 2 and argv[1..3] when argc == 4, replaced raw sscanf with bu_sscanf, safely printed bad coordinate values, and added missing newlines to usage strings; in shaded_mode.c, guarded argv[1] against null, replaced raw sscanf with bu_sscanf, and added missing newlines to mode output and usage strings; in shader.c, added null check on argv[1], verified argv[2..argc-1] are non-null before bu_vls_from_argv, replaced bu_vls_addr with bu_vls_cstr, and added missing newlines to usage, current shader output, and read-only error message; in shells.c, fixed major resource and memory leaks by deferring wdb_dbopen until after argument validation, verifying wdbp allocation, calling wdb_close on all error and success exits, calling rt_db_free_internal on old_intern across all exits, freeing shell_name on all exits, and eliminating double-free of m_tmp after rt_db_put_internal failure; in showmats.c, eliminated mutation of input path and improved safety by operating on a duplicated string buffer via bu_strdup and freeing path_copy on all exit paths, guarded smdp, smdp->smd_child, and comb_leaf->tr_l.tl_name against null in Do_showmats, guarded argv[1] against null in ged_showmats_core, added trailing newline to 16-element matrix output in -a mode, and added missing newlines to usage strings; in shrinkwrap.c, added GED_CHECK_DATABASE_OPEN guard and safely handled potential null argv[0]; in simulate/ged_command.cpp, added missing newline to non-Bullet error message, validated argc >= 3 and ensured argv[1] and argv[2] are non-null before parsing options, wrapped anim_state in std::unique_ptr to prevent persistent memory and resource leaks if exceptions are thrown during simulation steps, and added missing newline to exception result output; in simulate/rt_collision_algorithm.cpp, guarded against null rays in free_xrays, prevented division by zero by validating grid_radius > 0 and radius > 0 in generate_ray_grid and get_rays, returning null safely instead of calling bu_bomb, and added null checks on btRigidBody::upcast, getMotionState, and rays.ptr in calculate_contact_points to prevent null pointer dereferences. |
| `SEC-0267` | **Sev 2** | Resource Leaks, Memory Corruption, Unhandled Exceptions/Process Termination (bu_bomb), and Null Pointer Dereferences | `src/libged (Batch 25: simulate)` | `FIXED` | In BRL-CAD libged Batch 25 commands (src/libged/simulate/*): in rt_collision_shape.cpp, eliminated process-aborting bu_bomb calls by zeroing inertia when mass <= 0.0 and clamping negative scaling and margin values to 0.0; in rt_debug_draw.cpp, fixed major resource leaks of in-memory database handles by ensuring wdb_close is called on all paths in drawLine, drawAabb, and drawContactPoint, clamped color components to [0.0, 1.0] instead of terminating with bu_bomb, and added null check on message in reportErrorWarning; in rt_instance.cpp, guarded against null application and partition pointers in multioverlap_handler, falling back safely to rt_default_multioverlap on unexpected region table lengths or region names instead of calling bu_bomb, and threw InvalidSimulationError instead of aborting the process with bu_bomb when rt_i_create or rt_gettrees fails in get_overlaps; in rt_motion_state.cpp, guarded matrix and result destination pointers in bt_transform_to_matrix and path_to_matrix, and threw InvalidSimulationError instead of calling bu_bomb on rt_db_get_internal, db_find_named_leaf, or rt_db_put_internal failure; in rt_roi_collision_shape.cpp, guarded against null m_box_shape before dereferencing in getAabb, calculateLocalInertia, getLocalScaling, getMargin, setLocalScaling, and setMargin, clamped negative scaling and margin values, and zeroed inertia when mass <= 0.0; and in rt_roi_collision_shape.hpp, declared copy constructor and assignment operator private to enforce the Rule of Three and prevent double-free corruption of m_box_shape. |
| `SEC-0268` | **Sev 2** | Memory Leaks, Inverted Return Value Logic Bug, Process Termination in Library Function (bu_bomb), Missing Validation, Division by Zero, and Null Pointer Dereferences | `src/libged (Batch 26: simulate, slew, solid_report)` | `FIXED` | In BRL-CAD libged Batch 26 commands (simulate, slew, solid_report): in simulate/sim_animate.cpp and sim_animate.hpp, added null checks in az_el_to_offset, look_at_quaternion, and ae_to_quaternion, guarded m_gedp and dbip in getSceneCenter and renderFrame, cleared jpeg_data on error and bounded maximum buffer read size in readPixToJpeg, validated width, height, and fps in encodeVideo, enforced the Rule of Three on SimAnimState with private copy constructor and assignment operator, and removed unused method declaration writeMjpegAvi; in simulate/simulation.cpp and simulation.hpp, eliminated multiple process-terminating bu_bomb calls across get_aabb, get_simulation_parameters, Region::get_region, and Region::get_regions by throwing InvalidSimulationError with contextual path information, replaced bu_bomb in saveState with warning logging, eliminated persistent memory leak of bullet collision create functions in Simulation::Simulation by tracking allocated CreateFunc pointers in m_create_funcs and deleting them in ~Simulation(), and enforced the Rule of Three on Simulation and Region; in simulate/tests/simulate_test.cpp, safely returned false on null matrix in matrix_equal instead of calling bu_bomb, and guarded argv and argv[0] in main; in simulate/tests/verify_simulation.c, added null checks in parse_bbox, get_bbox, check_presim, check_postsim, and main, replaced raw sscanf with bu_sscanf, replaced bu_vls_addr with bu_vls_cstr, and guarded against division by zero on truck_height when calculating penetration percentage; in simulate/utility.cpp, threw InvalidSimulationError in current_dir on empty paths, fixed critical inverted logic bug in set_region where bu_avs_remove returning 1 on successful attribute removal was erroneously treated as an error causing bu_bomb to abort the process, and replaced remaining bu_bomb calls with warning logging to ensure clean teardown in ~TemporaryRegionHandle; in slew/slew.c, added null checks on argv[1..3], replaced raw sscanf with bu_sscanf, and added missing newlines to all usage strings; and in solid_report/solid_report.c, guarded gedp against null. |
| `SEC-0269` | **Sev 2** | Memory Leaks, Resource Leaks, Option Parsing Collision, Uninitialized Memory Operations, and Null Pointer Dereferences | `src/libged (Batch 27: solids_on_ray, sphgroup, stat, summary, sync, tab_complete, tables, bot_dump, bot_split, check_mann_docs)` | `FIXED` | In BRL-CAD libged Batch 27 commands and test drivers: in solids_on_ray/solids_on_ray.c, eliminated persistent memory leaks of solids_on_ray_cmd_vec strings (allocated by ged_who_argv) and snames path strings (allocated by db_path_to_string), added null guards on ap and PartHeadp in rpt_hits, verified pp->pt_inseg and pp->pt_inseg->seg_stp before retrieving path, guarded ap in rpt_miss, added null checks on gedp, dbip, ray_orig, and ray_dir in skewer_solids, replaced raw sscanf with bu_sscanf, added null checks on argv[1] and argv[2], and added missing newlines to usage and error strings; in sphgroup/sphgroup.c, fixed persistent memory leak of sph_intern by calling rt_db_free_internal on non-sphere error, _ged_combadd error, and normal exit, added null/empty string validation on argv[1] and argv[2], added missing newline to usage string, and deleted commented-out dead code; in stat/stat.cpp, fixed option parsing bug where the -q quiet flag was clobbered by -r raw due to duplicate array index d[3], fixed memory leaks in cmp_dps by using std::string to eliminate bu_vls leaks and freeing avs and string allocations on all exit paths, fixed memory leaks in stat_output by scoping bu_vls and freeing avs, added null/bounds checks in dpath_sort and _stat_find_first_unescaped, and added missing newlines to bu_log; in summary/summary.c, fixed major memory leak in solid_counter by calling rt_db_free_internal, added null checks in comb_counter and solid_counter, validated bu_opt_parse return value, guarded argv[0] against null, and added error output on missing objects; in sync/sync.c, added GED_CHECK_ARGC_GT_0 to prevent null dereference of argv[0] and appended missing newline; in tab_complete.cpp, added null guards in alphanum_cmp, path_match, obj_match, and ged_cmd_completions; in tables/tables.c, fixed memory leak of tree_objs bu_ptbl, verified read count before matching identt in tables_sol_number, initialized static descriptors to -1, guarded sol_loaded before invoking ft_describe or freeing sol_intern in tables_new, guarded getpwuid against null in tables_header, guarded ctime return in ged_tables_core, and added missing newlines; in tests/bot/bot_dump.cpp, guarded argv against null, corrected arbs_stl output comparison path for arb4_bot_02.stl, and added missing newlines; in tests/bot/bot_split.cpp, guarded argv in main, added null checks in check_output_group, check_output_bot, and check_decimated_bot, and ensured rt_db_free_internal is called on early return; and in tests/check_mann_docs.cpp, validated argv in main, added null checks before array indexing, and verified file stream is_open status before reading or writing. |
| `SEC-0270` | **Sev 2** | Logic Bugs, Resource and Handle Leaks, Missing Parameter and Option Validation, and Null Pointer Dereferences | `src/libged (Batch 28: tests/check_prim_cmds, tests/create, tests/draw)` | `FIXED` | In BRL-CAD libged Batch 28 test suites and drivers: in tests/check_prim_cmds.cpp, guarded argc and argv in main and checked empty ftp->ft_label string; in tests/create/create_parity.c, added null checks in case_covered and check_coverage, fixed handle leak in open_test_db by closing wdbp with wdb_close instead of leaking wdbp via raw db_close, guarded gedp, gedp->dbip, name, and out in snapshot, guarded argc and argv in main, and ensured temporary test database files are deleted on all exit paths; in tests/create/create_parity.h, verified interface header clean; in tests/create/in_cases.c and make_cases.c, added null guards on gedp, name, and label in build_obj and make_obj, and added null checks in trans_exempt and extra_checks; in tests/draw/aet.cpp, guarded gedp, dbi_state, view counts, and display manager pointers in dm_refresh and img_cmp, freed tname on error exits, guarded argc and argv in main, validated option parsing results, freed fname, deleted temporary database moss_aet_tmp.g, and cleared local cache directory lcache on exit; in tests/draw/annotate.cpp, fixed handle leak in verify_geometry_update by ensuring wdb_close is called on wdbp, guarded gedp and gedp->dbip in verify_legacy_annotation_coloring, and guarded argc and argv in main; in tests/draw/basic.cpp and faceplate.cpp, fixed critical logic bug where if (uac == -1 || need_help) had an empty statement body which inverted command-line argument validation logic, guarded ac and av in main, guarded gedp across poly_* helper functions, freed fname, deleted temporary moss_tmp.g, and cleared lcache on exit; and in tests/draw/draw_color.cpp, guarded argv in main, guarded fixture path, and added null checks on gedp, gedp internals, display structures, and directory pointers in check_drawing. |
| `SEC-0271` | **Sev 2** | Logic Bugs, Temporary File and Resource Leaks, Double-Free, Missing Option and Parameter Validation, and Null Pointer Dereferences | `src/libged (Batch 29: tests/draw, tests/edit, ged_test_rm, ged_test_tire, plugins, search_tests, test_bb_tight)` | `FIXED` | In BRL-CAD libged Batch 29 test suites and drivers: in tests/draw/lod.cpp and select.cpp, corrected option parsing check from ac != 2 to uac != 2 so optional command flags such as -c are correctly recognized without causing premature test failure, added null guards on ac, av, gedp, gedp->dbip, v, and v->dmp, freed fname and cleaned up temporary test databases on all exit paths; in tests/draw/quad.cpp, added null checks across drawing and refresh helpers, guarded image comparison against null control and test images, freed cname, corrected option parsing bounds, and ensured temporary database cleanup on exit; in tests/draw/util.cpp, added null guards on dp, u_data, dbi_state, ged_gvp, and dmp, and plugged memory leaks in img_cmp; in tests/edit/test_edit.cpp, replaced invalid jump-over-initialization error path with direct cleanup in create_p0_fixture, replaced manual export and double-free in create_p6_fixture with mk_brep, and ensured all 10 temporary database files (p0_path through p6_path) are unlinked via bu_file_delete across all error and success exits; in tests/ged_test_rm.c, replaced leaking db_close calls with wdb_close, added close_test_db to delete temporary test database files upon completion across all 26 test functions, fixed unchecked db_lookup dereferences, and added null guards in CHECK_PRESENT, CHECK_ABSENT, member_count, comb_has_op, and main; in tests/ged_test_tire.cpp, fixed database handle leaks by properly pairing wdb_fopen with wdb_close, added close_test_db to clean up temporary test databases, unlinked temporary text files and pattern files via bu_file_delete, eliminated premature wdb_close in run_partial_cleanup_case on an unowned handle, and added null checks across inspection helpers; in tests/plugins.cpp, fixed off-by-one / null pointer dereference in error message accessing av[1] instead of av[0], guarded ac and av in main, and added null checks on imsgs and cmds; in tests/search_tests.cpp, added null guards for gedp, gedp->dbip, path_dp, and search_count_helper, and validated argc/argv; and in tests/test_bb_tight.c, fixed wdbp handle leaks in open_test_db, added close_test_db to remove temporary test databases, and added null guards in parse_bb_volume, run_bb_volume, and main. |
| `SEC-0272` | **Sev 2** | Resource Leaks, Null Pointer Dereferences, Division by Zero, and Array Overflow | `src/libged (Batch 30: test_bo, test_db, test_gqa, test_list, test_material, test_search, test_select, test_tops, test_view_dir, tire)` | `FIXED` | In BRL-CAD libged Batch 30 test programs and tire command: in test_bo.c, replaced db_close(wdbp->dbip) with wdb_close(wdbp) to fix wdb handle leak, and added null guard on binunif internal pointer before accessing type, count, and data fields; in test_gqa.c, added null check on ged_open return value; in test_list.c, validated atoi result for non-positive values and guarded elapsed_sec > 0 before division to prevent division by zero in ops-per-second calculation; in test_material.c, added null check on ged_open return value and added ged_close before exit to prevent resource leak; in test_search.c, added null check on ged_open return value and added bounds check on variadic plan arguments to prevent overflow of fixed-size cmd[6] array; in test_select.cpp, added null check on ged_open return value, freed DbiState allocation, and cleaned up temporary cache directory with bu_dirclear on exit; in test_tops.c, added null check on ged_open return value; test_db.c reviewed clean; test_view_dir.c reviewed clean; tire/tire.cpp reviewed clean. |
| `SEC-0273` | **Sev 2** | Division by Zero, Integer Underflow, and Convention Violations | `src/libged (Batch 31: tire, title, tol)` | `FIXED` | In BRL-CAD libged Batch 31 (tire, title, tol): in tire/tire_surface.cpp, added ZERO() division-by-zero guard; in tire/tire_tread.cpp, added empty vector guard to prevent size_t underflow; in title/title.c, replaced bu_vls_addr with bu_vls_cstr; in tol/tol.c, replaced sscanf with bu_sscanf. Reviewed clean: tire_conic.cpp, tire_csg.cpp, tire_private.h, tire_tread_def.cpp, tire_tread_profile.cpp, tire_wheel.cpp. |
| `SEC-0274` | **Sev 2** | Memory Leaks, Resource Leaks, Unsafe API, and Convention Violations | `src/libged (Batch 32: tops, tra, trace, track, tree, typein, unhide, units, v2m_point, vdraw)` | `FIXED` | In BRL-CAD libged Batch 32 (tops through vdraw): in tree/tree.c, fixed memory leak of attribute value set by adding bu_avs_free, fixed resource leak of rt_db_internal on v4gift flatten failure, replaced bu_vls_addr with bu_vls_cstr; in typein/typein.c, fixed resource leaks in extrude_in and revolve_in when imported object is not ID_SKETCH by adding rt_db_free_internal, replaced bu_vls_addr with bu_vls_cstr in revolve_in and pnts_in (4 instances); in units/units.c, replaced bu_vls_addr with bu_vls_cstr; in v2m_point/v2m_point.c, replaced raw sscanf with bu_sscanf (3 instances), fixed copy-paste error in error messages; in vdraw/vdraw.c, replaced raw sscanf with bu_sscanf (7 instances). Reviewed clean: tops.c, tra.c, trace.c, track.c, unhide.c. |
| `SEC-0275` | **Sev 2** | Unsafe API and Memory Leaks | `src/libged (Batch 33: view module)` | `FIXED` | In BRL-CAD libged Batch 33 (view module): in view/aet.c, replaced raw sscanf with bu_sscanf (3 sites); in view/align.c, replaced raw sscanf with bu_sscanf (3 sites); in view/center.cpp, replaced raw sscanf with bu_sscanf (3 sites); in view/eye.c, replaced raw sscanf with bu_sscanf (3 sites); in view/faceplate/faceplate.c, added bu_vls_free on stack VLS after bu_opt_color and bu_opt_int calls to prevent memory leaks (4 sites). Reviewed clean: vers.c, autoview.c, autoview2.cpp, axes.c, data_lines.c, faceplate.h, faceplate_axes.c, faceplate_grid.c, interactive_rect.c, ged_view.h. |
| `SEC-0276` | **Sev 2** | Memory Leaks, Logic Bugs, Out-of-bounds Array Access, Resource Leaks, Unsafe API, and Missing Validation | `src/libged (Batch 34: view module: gobjs through ypr)` | `FIXED` | In BRL-CAD libged Batch 34 (view module: gobjs through ypr): in view/gobjs.cpp, fixed memory leaks of full path and internal objects in create command and scene free callback, and checked database open; in view/labels.c and view/lines.c, guarded against null scene object creation and used bu_vls_sprintf to prevent vls buffer leaks; in view/lod.cpp, validated database open before cache commands, checked wdb handle, fixed copy-paste error in scale message, and removed dead vls variables; in view/lookat.c, replaced raw sscanf with bu_sscanf (3 sites), guarded against zero vector division when lookat point is at eye position, and added missing newlines; in view/objs.cpp, fixed memory leak of directory pointers in _view_cmd_old_obj across all return paths, guarded against null ged internals, removed redundant recurse check, and fixed argument reporting in arrow subcommand; in view/polygons.c, fixed out-of-bounds argv index in overlap subcommand (argv[1] -> argv[0]), fixed error message reporting in bool subcommand (argv[0] -> argv[1]), checked database open before overlap tolerance check, and formatted s_name with bu_vls_sprintf; in view/quat.c, replaced raw sscanf with bu_sscanf (4 sites) and added missing newlines; in view/qvrot.c, replaced raw sscanf with bu_sscanf (4 sites), corrected argument reporting for bad angle from argv[1] to argv[4], and added missing newlines; in view/saveview.c, replaced bu_vls_addr with bu_vls_cstr, guarded display list traversal against null pointers, and added missing newlines; in view/size.c, replaced raw sscanf with bu_sscanf and added missing newlines; in view/snap.c, fixed critical logic bug where vp was set from uninitialized p instead of parsed 2D coordinates p2d, freed temporary msg vls on all early returns to eliminate memory leak, and added missing newlines; in view/view.c, added missing newlines to usage and error messages; in view/viewdir.c, added missing newline to usage message; in view/ypr.c, replaced raw sscanf with bu_sscanf (3 sites) and added missing newlines. Reviewed clean: knob.c. |
| `SEC-0277` | **Sev 2** | Memory Leaks, Resource Leaks, Memory Corruption, Unsafe API, Double Free, Division by Zero, and Missing Validation | `src/libged (Batch 35: view2grid_lu through zoom, completing src/libged)` | `FIXED` | In BRL-CAD libged Batch 35 (completing src/libged subsystem, 21 files): in view2grid_lu.c and view2model_lu.c, moved GED_CHECK_DATABASE_OPEN before b2lval evaluation, replaced raw sscanf with bu_sscanf, guarded against division by zero with ZERO macro in view2model_lu.c, and added missing newlines; in view2model.c, added missing newline to usage; in view2model_vec.c, replaced sscanf with bu_sscanf, checked bn_mat_inverse return, and added newline; in voxelize.c, fixed persistent rt_wdb resource leak with wdb_close, fixed rt_i_destroy leak on error, fixed argument reporting in error message, replaced sscanf with bu_sscanf, added bounds checks on voxel size and level of detail, and fixed format string; in vrot.c, added missing newlines and returned GED_HELP on argc == 1; in vutil.c, fixed memory corruption in ged_dl_hash by passing dp->d_namep string content instead of pointer address, added null guards, and checked bn_mat_inverse return values; in wcodes.c, fixed memory leak of path array on error exits, replaced direct ft_ifree with rt_db_free_internal, guarded null names, and added newlines; in wdb_importFg4Section.c, fixed crash on command reuse by resetting static state variables at start of command, replaced free with bu_free, replaced bu_bomb with error logging, validated line buffer lengths, and added zero face count guard; in whatid.c, verified ID_COMBINATION and added newlines; in which.cpp, replaced sscanf with bu_sscanf, guarded against integer subtraction overflow, capped range to prevent memory exhaustion, freed comb_objs on error, and verified ID_COMBINATION; in which_shader.c, fixed major memory leak of combination records by calling rt_db_free_internal on every iteration, replaced bu_vls_addr with bu_vls_cstr, and added newlines; in who.c, moved GED_CHECK_ARGC_GT_0 to top, replaced bu_vls_addr with bu_vls_cstr, guarded gdlp->dl_dp, and added newlines; in who2.cpp, moved GED_CHECK_ARGC_GT_0 to top, guarded dbis and bvs against null, and added newlines; in who_solids.cpp, checked sp->s_os before accessing s_dmode, moved GED_CHECK_ARGC_GT_0 to top, and guarded gedp internals; in wireframe_eval.c, guarded scene and scene data against null, set op for OP_NOP, fixed memory leak of application struct and ppath in draw_m3, and added null checks in fix_halfs and free_etree; in wmater.c, moved GED_CHECK_ARGC_GT_0 to top, replaced bu_vls_addr with bu_vls_cstr, verified ID_COMBINATION, and added newlines; in xpush.c, eliminated persistent rt_wdb handle leaks in Copy_solid and Copy_comb by using stack tolerance structs, fixed double-free on rt_db_put_internal failure, fixed combination internal memory leak when found is null or comb tree is null, guarded log10 domain, and fixed typo; in zap.c, guarded gedp internals, checked path length before accessing first solid, moved GED_CHECK_ARGC_GT_0 to top, and added newline; in zap2.cpp, freed cvls on help and error returns, guarded views, v, bvs, and v->gv_s against null, and moved GED_CHECK_ARGC_GT_0 to top; in zoom.c, replaced sscanf with bu_sscanf, guarded gedp->ged_gvp and division by zero, moved GED_CHECK_ARGC_GT_0 to top, and added newlines. |
| `SEC-0278` | **Sev 2** | Memory Leaks, Resource Leaks, Null Pointer Dereferences, Process Termination, and Missing Validation | `src/libwdb (Batch 36: annot through id)` | `FIXED` | In BRL-CAD libwdb Batch 36 (procedural geometry export, annot through id, 14 files): in annot.c, added null checks on fp, name, and ann, and checked rt_copy_annot return value before export; in arbn.c, validated filep, name, eqn, and checked neqn == 0 to prevent empty/invalid halfspace array export; in ars.c, validated filep, name, curves, and checked ncurves == 0 and pts_per_curve == 0; in bot.c, validated fp, fp->dbip, name, vertices, and faces, checked num_vertices == 0 and num_faces == 0, validated normals and face_normals when num_normals > 0, validated uvs and face_uvs when num_uvs > 0, guarded face_mode bitv duplication, and replaced manual loops with memcpy; in brep.cpp, replaced BU_ASSERT with explicit null validation on file, name, and vbrep, and freed bi on ON_Brep duplication failure; in cline.c, validated fp, name, V, and height, and ensured radius > 0 and thickness >= 0; in constraint.c, validated wdbp and name, and assigned expr to constraint expression when provided; in datum.c, validated wdbp, name, point, and direction in mk_datum, and validated fp, name, and head in mk_datums; in dsp.c, validated filep, name, and stom matrix, checked positive xdim/ydim dimensions, and initialized missing RT_DSP_SRC_FILE datasrc; in dynamic_geometry.c, fixed persistent memory leaks of tmp_name on all success paths in make_hole and make_hole_in_prepped_regions, freed internal database object and soltab on prep failure, called rt_db_free_internal after ft_prep to prevent leaking loaded combination/solid structures, eliminated bu_bomb process terminations, and validated input pointers and dimensions; in ebm.c, validated fp, name, file/binunif, tallness, dimensions, and matrix, and explicitly set RT_EBM_SRC_FILE in mk_ebm; in extrude.c, validated fp, name, sketch_name, V, h, u_vec, and v_vec, and checked height vector magnitude; in id.c, validated fp, fp->dbip, title, and conversion factor across mk_id, mk_id_units, and mk_id_editunits. Reviewed clean: export.c. |
| `SEC-0279` | **Sev 2** | Double-Free / Memory Corruption, Memory Leaks, Process Abort, Integer Overflow, and Missing Validation | `src/libwdb (Batch 37: mater through wdb, completing src/libwdb)` | `FIXED` | In BRL-CAD libwdb Batch 37 (procedural primitives, mater through wdb, 13 files, completing src/libwdb): in mater.c, added null checks on ofp and ofp->dbip, and returned -1 on unsupported v4 database rather than asserting mk_version == 4; in material.c, added null checks on wdbp and db_name, guarded against null name, parent, and source strings before bu_vls_strcpy, and validated attribute keys and values before bu_avs_merge to prevent bu_bomb aborts; in nmg.c, added null checks on filep, name, and m before NMG_CK_MODEL, and verified botp != NULL after nmg_bot conversion before export; in nurb.c, added null checks on wdbp, name, and surfs, and verified ni->nsrf > 0 (freeing ni on zero surfaces) before export; in pipe.c, added null checks on fp, name, vertex, and height, verified positive radii with ZERO macro, validated headp in mk_pipe, mk_pipe_free, and mk_pipe_init, and validated od > 0, id >= 0, id < od, and bendradius >= 0 in mk_add_pipe_pnt; in pnts.c, added null checks on pnts and pnts->point in pnts_init_head_pnt and pnts_add, checked scale >= 0.0, and validated point != NULL before adding points in mk_pnts; in reg.c, added null checks on comb and member_hd in mk_tree_pure and mk_tree_gift, guarded headp in mk_freemembers, added null checks on wdbp, combname, and headp in mk_comb, and validated membname in mk_comb1 and mk_region1; in script.c, eliminated Cat 1 memory corruption and caller memory free by allocating and duplicating scr into a newly allocated rt_script_internal before passing to wdb_export; in sketch.c, added null checks on fp, name, and skt, and checked rt_copy_sketch return before export; in submodel.c, added null checks on fp, name, and treetop; in units.c, added null check on str and ZERO() macro guards against zero conversion factor in mk_conversion and mk_set_conversion; in vol.c, added null checks on fp, name, file, cellsize, and mat, and verified positive dimensions and cell sizes; in wdb.c, eliminated memory leaks in mk_hyp by validating parameters before internal structure allocation, replaced bu_bomb in mk_metaball with internal structure cleanup and error return, guarded against integer overflow in mk_binunif allocation and validated data pointer before memcpy, and added null pointer and geometric parameter validation with ZERO macro across mk_half, mk_grip, mk_rpp, mk_wedge, mk_arb4-8, mk_sph, mk_ell, mk_tor, mk_rcc, mk_tgc, mk_cone, mk_trc_h, mk_trc_top, mk_rpc, mk_rhc, mk_epa, mk_ehy, mk_hrt, and mk_eto. |
| `SEC-0280` | **Sev 2** | Buffer Overflow, Double-Free, Logic / Angle Calculation Bug, Memory Leaks, Array Out-of-Bounds, Division by Zero, and Missing Validation | `src/mged (Batch 38: adc through chgtree)` | `FIXED` | In BRL-CAD mged Batch 38 (adc through chgtree, 9 files): in adc.c, fixed stack buffer overflow by capping user_pt coordinate parsing to the 3-element buffer capacity, replaced atof with bu_sscanf, guarded against division by zero in grid_scale across dst, dh, dv, and hv with ZERO macro, fixed incorrect input point parameter in MAT4X3PNT (passing pos_view instead of pos_model), added null pointer guards in adc_set_dirty_flag, adc_set_scroll, adcursor, and f_adc, and replaced bu_vls_addr with bu_vls_cstr; in arbs.c, eliminated double-free on rt_db_put_internal failure and fixed memory leak of internal struct on db_diradd failure and switch default, freed temporary vls on error return, eliminated unused file-scope dead array p_arb3pt and global mutable promp pointer, replaced atof with bu_sscanf, and replaced bu_vls_addr with bu_vls_cstr; in attach.c, made release() name parameter const char *, added null check on s and wp_name in mged_attach, removed redundant null check, and replaced bu_vls_addr with bu_vls_cstr; in axes.c, guarded against aspect division by zero with ZERO macro in draw_v_axes, and added null pointer guards in draw_e_axes, draw_m_axes, and draw_v_axes; in buttons.c, added bounds-checked get_state_str() helper to prevent out-of-bounds array reads on state_str, added null pointer checks in f_press, bv_vrestore, bv_vsave, and bv_adcursor, and replaced bu_vls_addr with bu_vls_cstr; in cad_boundp.c, resolved angle calculation bug where atan2 radian output was multiplied by DEG2RAD instead of RAD2DEG (corrupting bounding polygon angle computations), moved stray debug newline output inside #ifdef DEBUG, migrated memory management to bu_malloc and bu_free, included bu/malloc.h, replaced sscanf with bu_sscanf, and added negative tolerance validation; in cad_parea.c, replaced sscanf with bu_sscanf, and routed error logging from printf to stderr to prevent corrupting redirected stdout files; in chgmodel.c, guarded divisions in f_sc_obj against zero scale denominator and scale accumulators with ZERO macro, validated scale input with bu_sscanf, verified direction vector magnitude squared in f_qorot and corrected inverted error message, replaced sprintf with snprintf and guarded view_state in f_make, and replaced bu_vls_addr with bu_vls_cstr; in chgtree.c, fixed memory leak of internal database struct on db_diradd failure in f_copy_inv, added null guards in find_solid_with_path and find_solid_below_path, ensured lhs, rhs, and both paths are properly freed on all error exit paths in cmd_oed, and replaced bu_vls_addr with bu_vls_cstr. |
| `SEC-0281` | **Sev 2** | Stack Buffer Overflow, Out-of-bounds Array Access, Double-Free, Division by Zero, Memory Leaks, and Null Pointer Dereferences | `src/mged (Batch 39: chgview.c, clone.c)` | `FIXED` | In BRL-CAD mged Batch 39 (chgview.c and clone.c, 4,128 lines): in clone.c, fixed stack buffer overflows in get_name by adding field width limits with CPP_XSTR(CLONE_BUFSIZE) to bu_sscanf and replacing raw sscanf with bu_sscanf, fixed double-free and memory leaks of name vls by migrating deallocation from bu_vls_free to bu_vls_vlsfree (since get_name allocates outer struct via bu_vls_vlsinit), fixed out-of-bounds negative array indexing obj_list.names[-1] in copy_v5_comb_tree and copy_v4_comb by validating index_in_list return value (lidx >= 0) before indexing, fixed memory leak of obj_list.names[i].src in copy_object and ensured obj_list is freed across all return paths, fixed memory leaks of internal structures and records in copy_v4_solid, copy_v4_comb, copy_v5_solid, and copy_v5_comb on error paths, fixed potential division by zero in f_tracker by checking n_verts > 1, replaced raw calloc/free with bu_calloc/bu_free, and replaced read-only bu_vls_addr calls with bu_vls_cstr; in chgview.c, guarded against division by zero in cmd_size, mged_vscale, and cmd_sca by checking gv_i_scale with ZERO macro, added null checks on view_state and vs_gvp across cmd_center, cmd_size, size_reset, edit_com, cmd_autoview, f_status, f_refresh, update_all_rate_flags, mged_print_knobvals, knob_apply_misc, f_knob, mged_zoom, cmd_setview, f_slewview, mged_svbase, f_svbase, setview, slewview, f_view_ring, cmd_mrot, cmd_rot, cmd_arot, mged_vscale, and cmd_sca, fixed out-of-bounds argv access in edit_com, bounded state_str array indexing in f_status, replaced sprintf with snprintf in f_regdebug and guarded DMP, fixed early-out memory leak of orig_nargv and vlsargv in f_ill, guarded path_parse against null path, guarded MEDIT(s) and s->s_edit before dereference in mged_librt_knob_edit_apply and mged_escale, and replaced read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0282` | **Sev 2** | Memory Leaks, Resource Leak, Out-of-bounds Argument Access, Division by Zero, Duplicate Print Bug, and Null Pointer Dereferences | `src/mged (Batch 40: cmd.cpp, cmd.h)` | `FIXED` | In BRL-CAD mged Batch 40 (cmd.cpp and cmd.h, 3,647 lines): in cmd.h, audited header prototypes and linkage guards (clean); in cmd.cpp, eliminated memory leak in cmd_ged_inside where rt_db_internal intern was transformed but never freed with rt_db_free_internal across all exits, fixed NULL pointer dereference in cmd_ged_inside on illump->s_old.s_Eflag when illump is NULL, eliminated resource leak in cmd_rt_gettrees where rtip was created with rt_i_create but not destroyed with rt_i_destroy on missing geometry argument exit paths, eliminated duplicate window listing print bug in f_tie when called with no arguments, guarded division by zero in cmd_units with ZERO macro on sf, checked argc and argv bounds before indexing in cmd_ged_edit_wrapper, cmd_ged_simulate_wrapper, cmd_ged_in, cmd_ged_more_wrapper, cmd_nmg_collapse, and cmd_get_more_default, added missing error report when window name is not found in cmd_win set, added null pointer checks on view_state, view_state->vs_gvp, s->mged_curr_dm, DMP, illump, and MEDIT(s) across GED wrapper dispatchers, view management, and rendering hooks (cmd_ged_view_wrapper, cmd_ged_dm_wrapper, cmd_screengrab, cmd_blast, f_postscript, f_winset, _view_update_rate_flags_viewonly, and cmd_view), replaced fixed-size snprintf format in f_bomb with sizeof(buffer), and replaced ~45 read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0283` | **Sev 2** | Memory Leak, Null Pointer Dereference, Out-of-bounds Array / Argument Access, and Missing Parameter Validation | `src/mged (Batch 41: color_scheme.c, columns.c, dm-generic.c, dodraw.c)` | `FIXED` | In BRL-CAD mged Batch 41 (color_scheme.c, columns.c, dm-generic.c, and dodraw.c, 1,449 lines): in color_scheme.c, added null pointer checks on m_dmp, m_dmp->dm_dmp, s->interp, and color_scheme before dereferencing, ensured error messages are safely reported, and replaced read-only bu_vls_addr calls with bu_vls_cstr; in columns.c, added null pointer guards in vls_col_item and vls_col_eol to prevent crashes on null strings or null buffer pointers, and added symmetric null pointer checks for a, b, *dp1, *dp2, (*dp1)->d_namep, and (*dp2)->d_namep in cmpdirname comparator to prevent qsort crashes; in dm-generic.c, added null checks on s, s->interp, argc, and argv in common_dm and dm_commands, added null guards on rubber_band, mged_variables, s->mged_curr_dm, DMP, view_state, view_state->vs_gvp, s->gedp->ged_gvp->gv_s, adc_state, grid_state, and MEDIT(s) across idle, m, am, adc, con, size, getx, and bg command handlers, checked argc bounds before indexing argv[1..4], replaced raw sscanf with bu_sscanf for RGB background parsing, added null guards in view_state_flag_hook, dirty_hook, zclip_hook, and set_hook_data, and replaced all read-only bu_vls_addr calls with bu_vls_cstr; in dodraw.c, eliminated memory leak in replot_modified_solid where rt_db_internal intern was transformed via transform_editing_solid but never freed when ft_plot failed (< 0), fixed potential NULL pointer dereference and out-of-bounds access in replot_original_solid by validating bdata->s_fullpath.fp_len > 0 and LAST_SOLID(bdata) before dereferencing dp->d_namep, freed existing bdata->s_fullpath with db_free_full_path before duplicating in drawH_part2, guarded s->gedp and ged_dl(s->gedp) against NULL, added null guards in mged_bound_solid, replot_original_solid, replot_modified_solid, add_solid_path_to_result, and redraw_visible_objects, and replaced read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0284` | **Sev 2** | Division by Zero, Null Pointer Dereference, and Out-of-bounds Argument Access | `src/mged (Batch 42: doevent.c, dozoom.c)` | `FIXED` | In BRL-CAD mged Batch 42 (doevent.c and dozoom.c, 1,064 lines): in doevent.c, guarded against division by zero in motion_event_handler by clamping window width and height to positive values (width <= 0 ? 1 : width, height <= 0 ? 1 : height) and checking dm_get_aspect with ZERO macro before dividing, added null checks on s, eventPtr, s->mged_curr_dm, and DMP in mged_dm_motion and doEvent, added null guards on rubber_band, grid_state, MEDIT(s), adc_state, view_state, and view_state->vs_gvp across all AMM modes (AMM_IDLE, AMM_ROT, AMM_TRAN, AMM_SCALE, AMM_ADC_*, AMM_CON_*), guarded MEDIT in reset_edflag, and replaced read-only bu_vls_addr calls with bu_vls_cstr; in dozoom.c, eliminated critical division by zero in dozoom perspective calculation where to_eye_scr divided by tan(perspective) without verifying tan != 0 by checking tan value with ZERO macro and using fallback large distance, guarded against division by zero when adjusting inv_viewsize by checking MEDIT(s)->model_changes[15] with ZERO macro, added null checks on s, s->mged_curr_dm, DMP, view_state, view_state->vs_gvp, s->gedp, MEDIT(s), mged_variables, and color_scheme in dozoom, guarded transparency access (sp->s_os->transparency) against null sp->s_os in create_dlist_solid, added null pointer guards in createDLists, create_dlist_solid, createDListSolid, create_dlist_all, createDListAll, free_dlists, and freeDListsAll, and validated active_dm_set display managers and variables. |
| `SEC-0285` | **Sev 2** | Inverted Logic Bug, Double-Free, Memory Corruption / Type Mismatch, Resource Leaks, Division by Zero, and Null Pointer Dereferences | `src/mged (Batch 43: edsol.c, f_cmd.h)` | `FIXED` | In BRL-CAD mged Batch 43 (edsol.c and f_cmd.h, 2,324 lines): in f_cmd.h, audited extern command function prototypes (clean); in edsol.c, fixed critical inverted logic bug in ecmd_bot_thick_clbk where face_state > -1 mistakenly triggered error branch and face_state < 0 updated face 0, eliminated double-free in sedit_apply where rt_db_put_internal already frees es_int on all outcomes, fixed reset sequencing in f_sedit_reset where rt_db_free_internal was called before ft_prim_edit_reset zeroing primitive type ID, fixed inverted condition in f_get_sedit (illump || !illump->s_u_data) that caused command to always fail, prevented memory corruption in f_put_sedit by returning TCL_ERROR on functab mismatch rather than executing bu_structparse_argv with wrong structure layout, guarded against division by zero in mged_param with ZERO macro on viewscale, clamped input parameter count to RT_EDIT_MAXPARA, eliminated memory leaks of vls commands on early returns in get_sketch_name, ecmd_extrude_skt_name_clbk, and f_get_sedit_menus, replaced raw atof/atoi with bu_sscanf, verified bn_mat_inverse return in oedit_apply and f_oedit_apply, added primitive type bounds validation (ID_NULL < id <= ID_MAX_SOLID), and added extensive NULL guards on s, MEDIT(s), view_state, DMP, and bdata across all solid and object editing routines. |
| `SEC-0286` | **Sev 2** | Out-of-bounds Array / Buffer Access, Uninitialized Variables, Division by Zero, Resource Leaks, and Null Pointer Dereferences | `src/mged (Batch 44: f_db.c, facedef.c)` | `FIXED` | In BRL-CAD mged Batch 44 (f_db.c and facedef.c, 984 lines): in f_db.c, guarded against NULL pointer dereferences on s, gedp, ctx, argv, interpreter, and dbip across _post_opendb_failed, callbacks, f_opendb, and f_closedb, eliminated uninitialized buffer reads when bu_fgets returns EOF, checked Tcl result string validity before indexing, guarded curr_cmd_list before setting more_default, verified argc >= 2 before stripping trailing y/n database creation flags, and replaced all bu_vls_addr calls with bu_vls_cstr; in facedef.c, initialized plane equation index to -1 and added explicit range validation (plane >= 0 && plane < 6) to prevent out-of-bounds array writes, added upper and lower bounds checks on argc-derived array indexing into p_pleqn, p_3pts, p_rotfb, and p_nupnt arrays to prevent out-of-bounds reads, guarded against division by zero in get_pleqn using ZERO macro on vector magnitude before unitizing, replaced raw atof and atoi with bu_sscanf with return validation, added NULL pointer checks on arbo, s, MEDIT(s), and interp, freed error_msg VLS on all exit paths, and replaced bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0287` | **Sev 2** | Buffer Over-read, Mismatched Framebuffer Routine, Division by Zero, Infinite Loop / UI Hang, and Null Pointer Dereferences | `src/mged (Batch 45: fbserv.c, grid.c)` | `FIXED` | In BRL-CAD mged Batch 45 (fbserv.c and grid.c, 1,754 lines): in fbserv.c, fixed critical bug in fb_server_fb_bwwriterect where fb_writerect (RGB, 3 bytes/pixel) was called instead of fb_bwwriterect (monochrome, 1 byte/pixel) causing out-of-bounds heap over-reads and image corruption; added packet length and payload dimension validation across all framebuffer network handlers (fb_clear, fb_read, fb_write, fb_readrect, fb_writerect, fb_bwreadrect, fb_bwwriterect, fb_cursor, fb_setcursor, fb_scursor, fb_window, fb_zoom, fb_view, fb_wmap, fb_help) preventing buffer over-reads on truncated or malformed network packets; clamped absurd pixel requests (up to 8192x8192); handled malloc failures with 0-length error packets to prevent client hangs; replaced bu_strlcpy with bounded memcpy for binary auth token packets; added NULL pointer checks on pcp, s, s->mged_curr_dm, DMP, and fbp across all routines; in grid.c, guarded divisions against zero in draw_grid, snap_to_grid, and round_to_grid using ZERO macro on scale and aspect ratio; guarded against integer division by zero and infinite loops when res_major_h or res_major_v <= 0; clamped maximum grid dots (nv_dots, nh_dots <= 2000) to prevent denial-of-service UI hangs; added NULL pointer checks on s, s->mged_curr_dm, s->dbip, grid_state, view_state, view_state->vs_gvp, color_scheme, and s->interp across all callbacks and snap routines; and replaced all read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0288` | **Sev 2** | Memory Leak, Out-of-bounds Array / Buffer Access, Dead / Unused Code, and Null Pointer Dereferences | `src/mged (Batch 46: history.c, mater.c, menu.c, menu.h)` | `FIXED` | In BRL-CAD mged Batch 46 (history.c, mater.c, menu.c, and menu.h, 1,086 lines): in history.c, eliminated guaranteed memory leak in f_history by freeing dynamic VLS str across all normal and error exit paths; guarded against out-of-bounds buffer reads in f_journal by replacing single-byte string indexing with BU_STR_EQUAL(argv[1], "-d"); safely handled empty command string lengths in cmd_hist; added NULL pointer checks on cmdp, curr_cmd_list, curr_cmd_list->cl_cur_hist, journalfp, hptr, argv, and interp across history_record, history_journalize, f_journal, f_history, history_prev, history_cur, history_next, and cmd_hist; cleared dangling cl_cur_hist pointer in history_cleanup; replaced all read-only bu_vls_addr calls with bu_vls_cstr; in mater.c, added NULL pointer checks on s, s->gedp, ged_dl, dbip, and DMP in mged_color_soltab before dereferencing; in menu.c, eliminated dead/unused Tcl_DString variables in mged_mmenu_set and mmenu_set; added strict index bounds validation (index >= 0 && index < NMENU) in mmenu_set, mmenu_set_all, and cmd_mmenu_get to prevent out-of-bounds memory writes and reads; removed unsafe static storage duration from loop counters menu and item in mmenu_display and mmenu_select to prevent re-entrancy issues; added NULL checks on mptr->menu_string before indexing; added comprehensive NULL pointer guards on s, s->mged_curr_dm, DMP, menu_state, color_scheme, mged_variables, interp, and active_dm_set display managers across btn_item_hit, btn_head_menu, chg_l2menu, cmd_mmenu_get, mmenu_init, mged_menu_refresh, mged_mmenu_set, mmenu_set, mmenu_set_all, mged_highlight_menu_item, mmenu_display, and mmenu_select; and replaced all read-only bu_vls_addr calls with bu_vls_cstr; in menu.h, corrected header guard comment typo. |
| `SEC-0289` | **Sev 2** | Division by Zero, Memory Leaks, Dead Variable, Out-of-bounds Access, and Null Pointer Dereferences | `src/mged (Batch 47: mged.c)` | `FIXED` | In BRL-CAD mged Batch 47 (mged.c, 3,532 lines): eliminated floating-point division by zero in event_check when view_state->k.sca == 10.0 (where 1.0 / (1.0 - (view_state->k.sca / 10.0)) evaluated with 0.0 denominator) by validating denominator with ZERO macro; eliminated Tcl_DString memory leak in stdin_input on EOF return under non-cbreak mode; eliminated dead variable place and unused sprintf in mged_finish; guarded s->s_edit before rt_edit_destroy in mged_finish; guarded DMP and dm_bg before array indexing dm_bg[0..2] in main; guarded s->gedp before checking ged_subp table in main; added null pointer checks on s, s->s_edit, MEDIT(s), s->interp, view_state, view_state->vs_gvp, s->mged_curr_dm, DMP, curr_cmd_list, sd, and active display managers across mged_process_char, event_check, stdin_input, std_out_or_err, refresh, mged_finish, apply_cli_overrides, and main; added input_str_index bounds validation in mged_process_char; replaced raw sscanf with bu_sscanf in parse_debug_uint; and replaced all (~45) read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0290` | **Sev 2** | Uninitialized Memory, Missing Header Guards, Duplicate Code, Division by Zero, Resource Leak, and Null Pointer Dereferences | `src/mged (Batch 48: mged.h, mged_dm.h, mged_impl.cpp, mged_impl.h, mged_wdb.h)` | `FIXED` | In BRL-CAD mged Batch 48 (mged.h, mged_dm.h, mged_impl.cpp, mged_impl.h, mged_wdb.h, 1,610 lines): in mged_impl.cpp, zero-initialized allocated mged_state using memset to eliminate widespread uninitialized struct pointers and flags; refactored mged_state_create to call mged_state_init_internals, eliminating duplicate 18 callback registrations (DRY); in mged_state_destroy, guarded search_snapshot, dpy_string, s_edit, and s_edit->e before destroying and delegated internal destruction to mged_state_destroy_internals; cleared cmd_map in MGED_Internal destructor; guarded internal callback map lookups, registrations, and sync against null pointers and uninitialized state in mged_internal_clbk_map, mged_state_clbk_set, mged_state_clbk_get, and mged_edit_clbk_sync; in mged.h, guarded s, s->interp, and s->dbip in CHECK_DBI_NULL and CHECK_READ_ONLY macros to prevent null pointer crashes; in mged_dm.h, converted GET_MGED_DM macro to do-while(0) and guarded tp and tp->dm_dmp before dm_get_id to prevent null pointer dereference; guarded VIEWFACTOR against division by zero with ZERO macro; in mged_impl.h, added standard header guard #ifndef MGED_MGED_IMPL_H; in mged_wdb.h, wrapped extern declarations with __BEGIN_DECLS / __END_DECLS for standard C linkage when included in C++ translation units. |
| `SEC-0291` | **Sev 2** | Double-Free, File Descriptor Double-Close / Leaks, Logic Bugs, Memory Leaks, Division by Zero, and Null Pointer Dereferences | `src/mged (Batch 49: mover.c, overlay.c, plot.c, predictor.c, rect.c)` | `FIXED` | In BRL-CAD mged Batch 49 (mover.c, overlay.c, plot.c, predictor.c, rect.c, 1,179 lines): in mover.c, eliminated double-free in moveHobj and moveHinstance where rt_db_free_internal was called after rt_db_put_internal failure (which already frees internal database object on all outcomes), fixed memory leak in moveHinstance when combination tree is empty or object is not a combination by calling rt_db_free_internal, initialized internal database object with RT_DB_INTERNAL_INIT, and added null pointer checks on s, dbip, cdp, dp, xlate, and interp; in overlay.c, added null checks on ctp, s, gedp, mged_curr_dm, and DMP, replaced read-only bu_vls_addr with bu_vls_cstr, and explicitly returned TCL_OK; in plot.c, eliminated file descriptor double-close bug where close(fd1[1]) and close(fd3[0]) were executed after fclose(fp_w) and fclose(fp_r), fixed file descriptor leaks when subsequent pipe() calls fail, handled fork() failures gracefully, added _exit(1) after execlp calls to prevent child processes from continuing parent execution on exec failure, verified fp_w and fp_r after fdopen, guarded view_state and vs_gvp before matrix multiplication, replaced sprintf with snprintf, and replaced bu_vls_addr with bu_vls_cstr; in predictor.c, fixed logic bug in poly_trail where t1->t_nused <= 0 was checked twice instead of validating t2->t_nused, guarded division by zero in predictor_frame when frametime is zero using ZERO macro, and added null pointer checks across init_trail, push_trail, poly_trail, predictor_init, predictor_kill, predictor_frame, and predictor_hook; in rect.c, fixed critical crash in zoom_rect_area where rb_set_dirty_flag was passed NULL data causing MGED_CK_STATE abort, guarded against division by zero in rect_image2view when width <= 0, guarded against division by zero in adjust_rect_for_zoom, draw_rect, and zoom_rect_area when window aspect ratio is zero using ZERO macro, replaced bu_vls_addr with bu_vls_cstr, and added null pointer checks on s, mged_curr_dm, DMP, rubber_band, color_scheme, and interp. |
| `SEC-0292` | **Sev 2** | Loop Index Typo / Premature DList Deallocation, File Descriptor Leaks on Interrupt, Array Out-of-Bounds, Division by Zero, and Null Pointer Dereferences | `src/mged (Batch 50: rtif.c, scroll.c, sedit.h, set.c)` | `FIXED` | In BRL-CAD mged Batch 50 (rtif.c, scroll.c, sedit.h, set.c, 1,762 lines): in set.c, fixed critical bug in set_dlist where inner loop searching for active display managers sharing display lists used outer index di instead of dj in BU_PTBL_GET and checked uninitialized dlp2, causing the search to always fail and prematurely free active display lists in other display managers; guarded display list scene object list against empty list reads when freeing display lists; guarded against division by zero in set_absolute_model_tran when view scale is zero using ZERO macro; clamped perspective_angle to valid table indices [0..3] in establish_perspective and toggle_perspective preventing out-of-bounds array reads; guarded s, s->s_edit, and MEDIT(s) before syncing mv_context; guarded multi-level pointers in unset_var before dereferencing; guarded active display managers and DMP in set_dirty_flag and set_scroll_private; in rtif.c, fixed file descriptor leak in f_rmats when interrupted via setjmp by ensuring fp is closed before returning; validated and guarded vector list vertices (vp->nused > 0) preventing negative array indexing; added null pointer checks on s, s->gedp, view_state, view_state->vs_gvp, and interp across cmd_rt, cmd_rrt, rt_read, f_rmats, f_nirt, and f_vnirt; replaced atoi with bu_sscanf; in scroll.c, zero-initialized all elements of dm_scroll_array in set_scroll to guarantee NULL termination and bounded scroll_array pointer traversal by array capacity in scroll_display and scroll_select, preventing out-of-bounds array reads; extracted apply_sl_tol helper to eliminate duplicated tolerance thresholding logic (DRY); added null pointer checks on s, s->interp, view_state, DMP, color_scheme, and mged_variables across all event handlers and display routines; in sedit.h, guarded s, s->s_edit, and s->s_edit->e in SEDIT_ROTATE, SEDIT_TRAN, SEDIT_SCALE, and SEDIT_PICK, and guarded s in OEDIT_ROTATE, OEDIT_TRAN, and OEDIT_SCALE macros, preventing null pointer dereference crashes throughout solid and object editing; and replaced all read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0293` | **Sev 2** | Resource Leaks, Wrong Memory Deallocation Bug, Double-Open / File Descriptor Leaks, Array Out-of-Bounds, and Null Pointer Dereferences | `src/mged (Batch 51: setup.c, share.c, tclsync.c, tedit.c)` | `FIXED` | In BRL-CAD mged Batch 51 (setup.c, share.c, tclsync.c, tedit.c, 1,978 lines): in share.c, fixed critical bug in usurp_all_resources where freeing a zero-refcount display list state freed MGED_STATE->mged_curr_dm->dm_dlist_state instead of dlp2->dm_dlist_state, corrupting active display manager memory and leaking dlp2 resources; added null checks on dlp1, dlp2, and resource pointers in SHARE_RESOURCE macro; guarded all resource pointers in free_all_resources before decrementing refcounts and freeing, and nullified pointers after cleanup; added null checks on ctp, s, interpreter, and argv in f_share and f_rset; guarded active display managers and pathname lookups in f_share and share_dlist against null pointers; guarded s->mged_curr_dm in f_rset; in tedit.c, fixed file descriptor leak and concurrent double-opening of temporary files by passing bu_temp_file's open file handle directly to writesolid, flushing and closing before invoking external editor; eliminated memory leak of vls buffer in writesolid; bounded primitive type idb_type between ID_NULL and ID_MAX_SOLID before indexing EDOBJ dispatch table in writesolid and readsolid to prevent out-of-bounds memory access; made writesolid, readsolid, and editit static to minimize scope; guarded s, gedp, s_edit, MEDIT(s), view_state, and interp; in setup.c, guarded ctp, s, interp, and ctp->tcl_func in mged_cmd_dispatch; guarded argv[0] in quit usage message; guarded s and interp in cmd_setup; guarded s and view_state before setting vs_flag in mged_refresh_handler_impl and allocating vs_gvp in mged_setup; in tclsync.c, guarded interp, objc, objv, snapshot, record, and strings across EvalWords, ResultCopy, QualifiedPattern, AppendRecord, AppendProc, AppendProcs, AppendVariable, AppendVariables, AppendNamespace, AppendAliases, BuildInterpSnapshot, ReplayRecord, and ReplayInterpSnapshot; and replaced all read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0294` | **Sev 2** | Division by Zero, Stack Buffer Overrun Risk, String Mutation Bug, Unbounded Array Access, and Null Pointer Dereferences | `src/mged (Batch 52: titles.c, track.c, update.c)` | `FIXED` | In BRL-CAD mged Batch 52 (titles.c, track.c, update.c, 1,871 lines): in titles.c, eliminated floating-point division by zero in framerate calculation when frametime is zero using ZERO macro; eliminated in-place destructive mutation of caller's VLS buffer and dropped trailing lines in screen_vls by drawing lines via temporary buffer; bounded global_editing_state array indexing into state_str to prevent out-of-bounds reads; bounded solid type indexing into OBJ array and guarded ft_name before displaying keypoint; guarded MEDIT(s) against NULL before accessing model_changes and e_keypoint; guarded illump against NULL before checking s_old.s_Eflag; guarded s, s->mged_curr_dm, DMP, view_state, view_state->vs_gvp, and s->interp across create_text_overlay and dotitles; replaced sprintf with snprintf; replaced all read-only bu_vls_addr calls with bu_vls_cstr; in track.c, eliminated division by zero in slope when del[0] or slope is zero using ZERO macro and SMALL_FASTF; eliminated division by zero in crdummy when plano[0] - w[0] is zero using ZERO macro; eliminated multiple divisions by zero in top when magnitude of del is zero; clamped cosine values before acos in tancir to prevent NaN return; replaced unsafe custom track_itoa with snprintf; increased solid/region/group name buffers from 9-12 to 32 bytes to prevent name truncation; replaced raw atof with bu_sscanf; scoped all helper functions (crname, slope, crdummy, trcurve, bottom, top, crregion, track_itoa, wrobj, tancir) to static; guarded s, s->dbip, s->wdbp, and s->interp; in update.c, guarded s in mged_update and f_update against NULL pointer dereference; replaced raw sscanf with bu_sscanf; guarded donePtr and eventPtr in event callbacks; guarded clientData, s, interp, and argv[0..2] in f_wait; and replaced bu_vls_addr with bu_vls_cstr. |
| `SEC-0295` | **Sev 2** | Memory Leaks, Dangling Database Pointers, Dead Pre-libged Code, Out-of-bounds Array Access, Command Argument Parsing Bug, In-place String Mutation, and Null Pointer Dereferences | `src/mged (Batch 53: usepen.c, utility1.c, vparse.c, wdb_obj.c)` | `FIXED` | In BRL-CAD mged Batch 53 (usepen.c, utility1.c, vparse.c, wdb_obj.c, 3,149 lines): completing all 55 files of src/mged (100% complete): in usepen.c, eliminated dangerous in-place mutation of argv[1] string in f_matpick by copying into a local buffer before splitting slash path; removed static storage duration from transformation matrices t1 and t2 in wrt_view to make the function re-entrant; guarded against null pointers in illump before accessing s_u_data in f_matpick; guarded s, s->mged_curr_dm, s->gedp, ged_dl(s->gedp), DMP, illump, and illum_gdlp across illuminate, f_aip, and f_matpick; guarded argv[1] against null/empty strings; replaced raw sprintf with snprintf; and replaced all read-only bu_vls_addr calls with bu_vls_cstr; in utility1.c, eliminated over 200 lines of dead pre-libged code, including obsolete unused global variables (path, identt, idbuf, operate, regflag, lastmemb, old_or_new, oper_ok, numsol, numreg, idfd, rd_idfd, tabptr, ctemp) and unused functions/structs (printcodes, Do_printnode, check, id_names, id_to_names); added null checks on s and s->gedp in f_edcolor, f_edcodes, f_edmater, and f_red; and replaced bu_vls_addr with bu_vls_cstr; in vparse.c, added null pointer guards on vls, how_to_parse, structp, argv, and argv[1] across mged_vls_struct_parse and mged_vls_struct_parse_old; in wdb_obj.c, eliminated memory leak of log_str in wdb_track_cmd by adding missing bu_vls_free; fixed database reopen bug in wdb_reopen_cmd where allocating a new wdbp reassigned the local parameter and leaked the new object while leaving callers with a dangling pointer to freed dbip, by updating wdbp->dbip in place; fixed argument index parsing bug in wdb_make_bb_cmd where passing -u caused the bounding routine to treat the new bounding box name as an input object to bound; fixed argument parity condition in wdb_tol_cmd that blocked single-tolerance queries (argc == 2); clamped perpendicularity tolerance to [-1.0, 1.0] before acos to prevent NaN return; fixed wrong return value (returning TCL_OK instead of TCL_ERROR) when object is not an ARB in wdb_move_arb_face_cmd and wdb_rotate_arb_face_cmd; fixed wrong argv indices in error messages in wdb_rotate_arb_face_cmd; dynamically allocated resource structures in wdb_rt_gettrees_cmd eliminating shared static resource state and freeing in wdb_deleteProc_rt; replaced raw sscanf and atof with bu_sscanf; checked floating-point tolerances with ZERO macro; replaced raw sprintf with snprintf; and replaced all (~52) read-only bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0296` | **Sev 2** | Memory Leaks, Immediate NULL Pointer Dereference Crash, Resource Leaks, Wrong Memory Deallocation, and Missing Parameter Validation | `src/proc-db (Batch 54: bottest.c, brep_cobb.cpp, brep_cube.cpp, brep_invalid.cpp, brep_simple.cpp, brep_surface.cpp)` | `FIXED` | In BRL-CAD proc-db Batch 54 (bottest.c, brep_cobb.cpp, brep_cube.cpp, brep_invalid.cpp, brep_simple.cpp, brep_surface.cpp, 2,010 lines): in bottest.c, fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0] before bu_setprogname; checked outfp after wdb_fopen to prevent NULL dereference on write failure; fixed wrong memory deallocator by replacing bu_free with bu_bitv_free(face_mode); and replaced db_close(outfp->dbip) with wdb_close(outfp) to eliminate struct rt_wdb handle leak; in brep_cobb.cpp, eliminated persistent memory leak of 6 heap-allocated ON_NurbsSurface surfaces in Cobb_Sphere by using stack-allocated surfaces in a unified loop, and deleting ON_BezierSurface; guarded argv[0] before bu_setprogname; checked outfp after wdb_fopen; guarded brep before mk_brep; and replaced db_close(outfp->dbip) with wdb_close(outfp); in brep_cube.cpp, fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0]; checked outfp after wdb_fopen; eliminated internal database object memory leak by calling rt_db_free_internal(&ip); guarded brep allocation in MakeTwistedCube; and replaced db_close(outfp->dbip) with wdb_close(outfp); in brep_invalid.cpp, eliminated memory leaks in Cobb_Sphere by stack-allocating ON_NurbsSurface and deleting b1; added null check on c2 before appending to trimming loop; validated plate thickness with bu_sscanf; added standard help flags (-h, -?, --help); checked outfp after wdb_fopen; and replaced db_close(outfp->dbip) with wdb_close(outfp); in brep_simple.cpp, fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0]; checked outfp after wdb_fopen; eliminated internal database object memory leak by calling rt_db_free_internal(&ip); guarded brep allocation in MakeTwistedCube; replaced db_close(outfp->dbip) with wdb_close(outfp); and replaced raw printf with bu_log; in brep_surface.cpp, guarded brep and c2d curve allocations; validated thickness argument with bu_sscanf; added standard help flags; checked outfp after wdb_fopen; and replaced db_close(outfp->dbip) with wdb_close(outfp). |
| `SEC-0297` | **Sev 2** | Resource Leaks, Immediate NULL Pointer Dereference Crash, Division by Zero, Missing Argument Validation, and Memory Leaks | `src/proc-db (Batch 55: brep_trimmed.cpp, breplicator.cpp, brickwall.c, cchannel.c, clutter.c, common.c)` | `FIXED` | In BRL-CAD proc-db Batch 55 (brep_trimmed.cpp, breplicator.cpp, brickwall.c, cchannel.c, clutter.c, common.c, 2,535 lines): in brep_trimmed.cpp, guarded ON_Brep allocation in MakeBrepFace against NULL return; guarded argv[0] before bu_setprogname; added standard help flags (-h, -?, --help); replaced unsafe atof with bu_sscanf with error checking; checked outfp after wdb_fopen; and replaced db_close(outfp->dbip) with wdb_close(outfp) to eliminate struct rt_wdb handle leak; in breplicator.cpp, added null check and size check (count >= 8) on points in generate_brep; guarded ON_Brep allocation; fixed immediate SIGSEGV crash when run without arguments by checking argc > 1 before accessing argv[1]; guarded argv[0]; and replaced db_close(wdbp->dbip) with wdb_close(wdbp); in brickwall.c, guarded av and *av in parse_args; guarded argv[0] before bu_setprogname; replaced raw sscanf with bu_sscanf; replaced raw sprintf with snprintf; validated units_conv to prevent division by zero; guarded against division by zero in standalone horizontal spacing when horiz_bricks <= 1; and supported standard clean exit on help flags; in cchannel.c, replaced raw sscanf with bu_sscanf with error validation; used ZERO macro for float zero comparisons; fixed infinite loop vulnerability in addHoles by verifying positive step; replaced sprintf with snprintf; guarded argv[0] before bu_setprogname; removed invalid colons requiring arguments from help options string and supported clean exit on -h/-?; checked outfp after wdb_fopen; guarded domain of sqrt calculation; and replaced db_close(db->dbip) with wdb_close(db); in clutter.c, fixed memory leak of bn_unif random buffer by calling bn_unif_free; guarded argv[0] before bu_setprogname; added help flag handling with clean exit; validated wdb_fopen; replaced sprintf with snprintf; and replaced db_close(outfp->dbip) with wdb_close(outfp); in common.c, added null pointer guard on rgb in get_rgb; added null pointer guards on name, pos, dir_at, headp, and outfp in do_light; and guarded against NaN from unitizing zero vectors. |
| `SEC-0298` | **Sev 2** | Memory Leaks, Double Free, Handle Leaks, and Missing Argument Validation | `src/proc-db (Batch 56: csgbrep.cpp, donuts.c, gaia.c, gears.c)` | `FIXED` | In BRL-CAD proc-db Batch 56 (csgbrep.cpp, donuts.c, gaia.c, gears.c, 3,116 lines): in csgbrep.cpp, eliminated external buffer leak ext in write_out with bu_free_external; fixed ON_Brep leak by deleting brep and checking ON_Brep::New; guarded argv[0] before bu_setprogname; supported standard help flags (-h, -?, --help); checked outfp after wdb_fopen; freed extrude.sketch_name and revolve.sketch_name; and replaced db_close(outfp->dbip) with wdb_close(outfp); in donuts.c, replaced unbounded sprintf with snprintf across getName, createLights, createPlane, createEnvironMap, createScene, makeFlake; supported -h and -? in options; replaced raw sscanf with bu_sscanf; fixed inverted logic bug where empty material check tested == 0 instead of != 0; removed undefined fflush(stdin); guarded progname and argv[0]; checked wdb_fopen result fp; freed parameters.materialArray; and replaced db_close(fp->dbip) with wdb_close(fp); in gaia.c, added null pointer guard on path in open_raster_georef; guarded av[0] before bu_setprogname; supported clean help flag exit; replaced atoi and atof with bu_sscanf; and ensured GDAL datasets are closed on texture load failure paths; in gears.c, guarded make_gear against null db_fp and teeth <= 0; eliminated double free risk by freeing scratch arrays verts/lsegs/segments/reverse once and cleaning up gear_head wmembers; guarded av[0]; supported help flags (-h, -?, --help); replaced atof and atoi with bu_sscanf; cleaned up all_head wmembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0299` | **Sev 2** | Immediate NULL Pointer Dereference Crashes, Uninitialized Memory Access, Memory Leaks, Infinite Loop, and Handle Leaks | `src/proc-db (Batch 57: globe.c, gtimes.c, helicoil.c, kurt.c, lattice.c, lens.c)` | `FIXED` | In BRL-CAD proc-db Batch 57 (globe.c, gtimes.c, helicoil.c, kurt.c, lattice.c, lens.c, 1,910 lines): in globe.c, guarded progname and av[0]; added clean exit on help flags (-h, -?, --help); replaced atof with bu_sscanf; validated stepSize > 0 (eliminating infinite loop denial of service), initialSize > 0, and finalSize > initialSize (eliminating division by zero in shader params); replaced sprintf with snprintf; eliminated persistent leaks of wmember list nodes across loop iterations by calling mk_freemembers(&wm_hd.l) and mk_freemembers(&bigList.l); and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to fix struct rt_wdb handle leak; in gtimes.c, guarded av[0] before bu_setprogname; supported standard help options (-h, -?); replaced atoi with bu_sscanf; guarded against out-of-bounds pointer dereference when no file argument is given; guarded wdbp from wdb_dbopen against NULL; called ged_free(&ged) on every iteration to fix persistent ged container memory leaks; and replaced printf with bu_log; in helicoil.c, guarded build_helix against NULL head and non-positive turns; guarded av[0]; added clean help exit (-h, -?, --help); replaced atoi and atof with bu_sscanf; freed coil_hd and all_hd wmember lists with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in kurt.c, guarded argv[0] before bu_setprogname; added clean exit on help flags; checked outfp after wdb_fopen; in do_cell, guarded vp->v_n < 3 and fixed critical array index bug in sort loop that iterated over nroots instead of vp->v_n (which caused sorting of uninitialized memory); freed head wmembers in make_surface; guarded against division by zero in vector unitize in pnorms and do_light; and replaced db_close(outfp->dbip) with wdb_close(outfp); in lattice.c, guarded subdivide_face against freq < 1 or freq > MAX_FREQ; guarded av[0] before bu_setprogname; supported clean help exit; replaced atoi and atof with bu_sscanf; clamped frequency to MAX_FREQ; freed dome_head, light_head, and all_head wmembers with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in lens.c, fixed immediate SIGSEGV crash when run without filename where av[bu_optind] was NULL and passed to %s in bu_log; checked wdb_fopen return; guarded discriminant and radicand against negative values and ref_ind against zero; freed VLS buffers str, lens_type, and name; freed lensglass and lens wmembers; replaced sscanf with bu_sscanf; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0300` | **Sev 2** | Division by Zero, Memory Leaks, Denial of Service via Unbounded Recursion, and Handle Leaks | `src/proc-db (Batch 58: loftwing.c, masonry.c, menger.c)` | `FIXED` | In BRL-CAD proc-db Batch 58 (loftwing.c, masonry.c, menger.c, 2,245 lines): in loftwing.c, guarded naca_eval against negative x and p >= 1.0 (preventing division by zero); guarded naca_outline against npts < 4 and non-positive nupper/nlower; guarded build_loft against NULL pointers and invalid counts; guarded av[0] before bu_setprogname; added clean exit on help flags (-h, -?, --help); replaced atoi and atof with bu_sscanf with error checks; clamped points, stations, blades, span, and chord to valid positive ranges; eliminated persistent memory leaks of wm_hd wmembers across wing and blade branches by calling mk_freemembers; ensured db_fp and allocated buffers are freed on error exits; and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to eliminate struct rt_wdb handle leak; in masonry.c, guarded set_translate and set_rotate with bu_sscanf and initialized coordinates; guarded av and *av in parse_args before bu_path_component; supported standard help exit (-h, -?); replaced raw sscanf and atof with bu_sscanf; guarded studs and span in frame_opening to prevent division by zero; freed s_hd boardseg head and wm_hd wmembers in frame; guarded sheetrock against non-positive dimensions and freed wm_hd wmembers; guarded mortar_brick against non-positive wall/brick dimensions (preventing division by zero) and freed wm_hd wmembers; freed wm_hd wmembers in brick; freed ol_hd opening list and trans_matrix in main; and replaced db_close(db_fd->dbip) with wdb_close(db_fd); in menger.c, guarded comb, depth, width, and height in slice against NULL/invalid extents; in mengerize, guarded against empty pattern or zero repeat; eliminated persistent leaks of levels[slot]->l and final->l wmembers by calling mk_freemembers; guarded av[0] before bu_setprogname; limited repeat to maximum 5 to eliminate denial-of-service memory exhaustion from recursive fractal generation; replaced heap allocation of menger, ground, light0, light1, sponge with stack allocation and freed their wmembers with mk_freemembers; freed boxes VLS container; and replaced db_close(fp->dbip) with wdb_close(fp). |
| `SEC-0301` | **Sev 2** | Buffer Over-reads, Out-of-Bounds Memory Access, Memory Leaks, and Handle Leaks | `src/proc-db (Batch 59: metaball.c, molecule.c, nmgmodel.c, parashot.c, pdb-g.cpp)` | `FIXED` | In BRL-CAD proc-db Batch 59 (metaball.c, molecule.c, nmgmodel.c, parashot.c, pdb-g.cpp, 1,761 lines): in metaball.c, guarded make_meatballs against NULL name and non-positive count (eliminating division by zero in sqrt); in mix_balls, called rt_db_free_internal to eliminate persistent internal object memory leaks for every input object; checked wdbp returned by wdb_dbopen; guarded av and av[0] before bu_setprogname; added clean exit 0 on help flags (-h, -?); replaced atoi with bu_sscanf with range validation [1, 1000000]; and replaced db_close(fp->dbip) with wdb_close(fp) to eliminate struct rt_wdb handle leak; in molecule.c, guarded argv[0] before bu_setprogname; supported standard help flags with exit 0 (-h, -?, --help); checked outfp from wdb_fopen against NULL; rewrote read_data to use line-by-line reading with bu_fgets and bu_sscanf to eliminate infinite loop denial of service on non-numeric input; added bounds checking on atom indices and types to eliminate out-of-bounds array reads in atom_list; replaced unsafe sprintf with snprintf; increased s_name buffer to prevent truncation; freed reg_head and head wmembers with mk_freemembers; freed allocated sphere linked list to fix memory leak; and replaced db_close(outfp->dbip) with wdb_close(outfp); in nmgmodel.c, guarded av and *av before bu_path_component; supported clean exit 0 on help flags (-h, -?); freed model m with nmg_km if wdb_fopen fails; and replaced db_close(fdmodel->dbip) with wdb_close(fdmodel); in parashot.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on help flags (-h, -?); replaced raw sscanf, atoi, and atof with bu_sscanf; validated step count and pipe diameter; and replaced db_close(fp->dbip) with wdb_close(fp); in pdb-g.cpp, fixed buffer over-read vulnerability when parsing fixed-column PDB records (ATOM/HETATM) on short lines by trimming newlines and padding lines up to 80 characters with spaces; replaced raw sscanf with bu_sscanf; supported clean help exit (-h, -?, --help); derived default output geometry file if omitted; freed allocated header string with bu_free; freed all_atoms wmembers with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0302` | **Sev 2** | Free of Memory Not on Heap, Buffer Over-read, Race Condition, Unbounded Recursion, and Memory Leaks | `src/proc-db (Batch 60: pipe.c, pipetest.c, pix2g.c, pyramid.c, ringworld.c)` | `FIXED` | In BRL-CAD proc-db Batch 60 (pipe.c, pipetest.c, pix2g.c, pyramid.c, ringworld.c, 1,641 lines): in pipe.c, clamped Normals dot product to [-1.0, 1.0] before acos to prevent NaN; guarded tangent and cosine denominators against zero with ZERO(); fixed memory leaks and cumulative combination list corruption across pipe and elbow generations by calling mk_freemembers(&head.l) after every mk_lfcomb; guarded argv[0] before bu_setprogname; added clean exit 0 on -h and -?; replaced raw scanf with bu_fgets and bu_sscanf with validation; guarded against NULL pointer dereference in Names() and main() when fewer than two points are read; freed root points linked list; and replaced db_close(fdout->dbip) with wdb_close(fdout); in pipetest.c, fixed critical heap corruption crash (CWE-590: Free of Memory not on the Heap) by dynamically allocating pipe points via mk_pipe_init and mk_add_pipe_pnt instead of passing static array elements to mk_pipe which takes ownership and frees on export; guarded argv[0]; fixed unconditional usage message; supported clean exit 0 on help flags (-h, -?, --help); checked wdb_fopen return; added NULL guards in do_bending and pr_pipe; freed pipe points with mk_pipe_free; and replaced db_close(outfp->dbip) with wdb_close(outfp); in pix2g.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; replaced atoi and atof with bu_sscanf with range validation [1, 65536] on dimensions and positive checks on cell/object sizes; prevented buffer over-read (CWE-125) and crash when image buffer is smaller than width * height * 3 by halting with error instead of continuing to read past buffer end; eliminated critical race condition and list corruption across parallel worker threads by acquiring BU_SEM_GENERAL semaphore when modifying global allScanlineList; eliminated persistent leaks of hundreds of thousands of wmember list nodes by calling mk_freemembers on wm_hd, scanlineList, and allScanlineList; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in pyramid.c, removed unused dead function pnorms; guarded argv[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; replaced atoi with bu_sscanf and clamped recursion depth to [1, 8] to prevent denial of service from unbounded recursive branching; checked wdb_fopen return; eliminated persistent memory leaks in recursive tree generation by calling mk_freemembers(&head.l); and replaced db_close(outfp->dbip) with wdb_close(outfp); in ringworld.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on -h and -?; checked wdb_fopen return; eliminated wmember list node leaks in mk_sol, mk_ring, and main by calling mk_freemembers(&c.l); and replaced db_close(fp->dbip) with wdb_close(fp). |
| `SEC-0303` | **Sev 2** | Memory Leaks, Handle Leaks, Unbounded Recursion Denial of Service, Division by Zero, and Input Validation | `src/proc-db (Batch 61: seashell.c, sketch.c, specimen.c, sphflake.c, spltest.c)` | `FIXED` | In BRL-CAD proc-db Batch 61 (seashell.c, sketch.c, specimen.c, sphflake.c, spltest.c, 2,106 lines): in seashell.c, guarded superformula against n1 == 0 with ZERO() to prevent division by zero in pow(); guarded argv[0] before bu_setprogname; added clean exit 0 on -h, -?, --help; replaced atof and atoi with bu_sscanf with range validation on --turns, --expand, and --res; eliminated persistent wmember list node leaks across combinations by calling mk_freemembers(&all_hd.l); and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to fix struct rt_wdb handle leak; in sketch.c, guarded argv[0] before bu_setprogname; removed dead option parsing block that caused unconditional abort on any argument; supported clean exit 0 on -h, -?, --help; checked outfp returned by wdb_fopen against NULL; freed all_head wmembers with mk_freemembers; and replaced db_close(outfp->dbip) with wdb_close(outfp); in specimen.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; replaced atof with bu_sscanf and validated spacing >= 100.0; freed reg_hd wmembers after every specimen shelf region and freed gnd_hd, lt_hd, and all_hd wmembers in main to eliminate widespread heap leaks; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in sphflake.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; clamped recursion depth to [0, 5] using bu_sscanf to eliminate denial of service from exponential tree explosion; checked fp returned by wdb_fopen against NULL; eliminated massive memory leak by freeing all wmemberArray entries with mk_freemembers before bu_free; removed undefined behavior fflush(stdin) calls; replaced unsafe sprintf and sscanf with snprintf and bu_sscanf; and replaced db_close(fp->dbip) with wdb_close(fp); in spltest.c, guarded argv[0] before bu_setprogname; supported clean exit 0 on -h, -?, --help; guarded make_face against NULL pointers and unsupported order; checked srf returned by nmg_nurb_new_snurb; and replaced db_close(fp->dbip) with wdb_close(fp). |
| `SEC-0304` | **Sev 2** | Use-After-Free, Infinite Loops, Memory Leaks, File Descriptor Leak, Handle Leaks, and Missing Input Bounds Checks | `src/proc-db (Batch 62: surfaceintersect.cpp, surfaceintersect.h, tea.c, tea.h, tea_nmg.c)` | `FIXED` | In BRL-CAD proc-db Batch 62 (surfaceintersect.cpp, surfaceintersect.h, tea.c, tea.h, tea_nmg.c, 2,014 lines): in surfaceintersect.cpp, corrected inverted SI_MIN macro; guarded against division by zero in Step when normal cross product magnitude is zero; eliminated unbounded memory leaks and fixed typo in CurveCurveIntersect by properly deleting split curve objects left1/right1/left2/right2 and intersecting right1 with right2; updated SetCurveCurveIntersectionDir to use reference parameter so intersection direction updates are not discarded on copy, enabled the negative dot product branch (dot < 0), fixed typo that wrote m_dirB[0] twice, and made curve parameters const; fixed arguments to SetCurveCurveIntersectionDir in Get_ON_X_Events; capped Jiggle iteration loops in WalkIntersection and GetStartPointsInternal to prevent infinite loop denial of service; in GetStartPointsInternal, eliminated 12 heap-allocated ON_Surface leaks per recursion node and corrected return value accumulator from &= to |=; cleaned up dynamically allocated curves in BrepBrepIntersect before returning; in main(), guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?/-help, checked wdb_fopen return, freed all wmembers with mk_freemembers, and replaced db_close(db_fp->dbip) with wdb_close(db_fp) to fix struct rt_wdb handle leak; in tea.h, marked ducks and patches as static const to prevent multiple-definition linker collisions and inadvertent table modification; in tea.c, guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?, checked wdb_fopen return, added NULL check in dump_patch, added array bounds checks on patch indices before accessing ducks[], and replaced db_close(outfp->dbip) with wdb_close(outfp); in tea_nmg.c, fixed critical CWE-416 Use-After-Free vulnerability where nmg_m_to_vlist accessed model m after mk_nmg/wdb_export had already freed it by generating the vlist prior to exporting, fixed file descriptor leak by calling fclose(fp) on the plot3 file, freed vlist nodes with BV_FREE_VLIST, guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?, checked wdb_fopen return, checked nmg_mm() return, added bounds checks on patch indices, and replaced db_close(outfp->dbip) with wdb_close(outfp). |
| `SEC-0305` | **Sev 2** | Memory Leaks, Handle Leaks, Combination List Corruption, File Descriptor Leaks, and Missing Input Bounds Checks | `src/proc-db (Batch 63: terragen.c, torii.c, tube.c, twistedcube.cpp, twistedcube.h)` | `FIXED` | In BRL-CAD proc-db Batch 63 (terragen.c, torii.c, tube.c, twistedcube.cpp, twistedcube.h, 1,474 lines): in terragen.c, guarded av[0] before bu_setprogname, supported clean exit 0 on -h/-?/--help, replaced atoi and atof with bu_sscanf, added cleanup freeing hf and grid and calling wdb_close on sidecar write failure, freed combination members after terrain.r, water.r, sky.r, and all combs with mk_freemembers, and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in torii.c, guarded av[0] before bu_setprogname, supported clean exit 0 on -h/-?/--help, replaced atoi and atof with bu_sscanf, validated rows and cols (clamped 1..200) and major/minor radii to prevent denial-of-service memory/disk exhaustion, freed all_hd wmembers with mk_freemembers on error paths and normal completion, and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in tube.c, guarded argv[0] before bu_setprogname, supported clean exit 0 on -h/-?/--help, checked outfp returned by wdb_fopen against NULL, closed pos_fp with fclose, eliminated combination list corruption and memory leaks across frames by freeing head.l after bg.r and both head.l and ghead.l on every frame iteration with mk_freemembers, freed head.l in build_cyl with mk_freemembers, checked npts <= 0 and bp in build_spline, added bounds check on nsamples (< 1022) to prevent sample array overflow and replaced sscanf with bu_sscanf in read_frame, replaced fscanf with bu_fgets and bu_sscanf in read_pos, guarded against division by zero in xfinddir with ZERO(denom), and replaced db_close(outfp->dbip) with wdb_close(outfp); in twistedcube.cpp, added array bounds checks on from and to vertex indices against brep.m_V.Count() in MakeTwistedCubeEdge, validated face.m_si and checked surface pointer in MakeTwistedCubeTrimmingLoop, checked edge index ei against brep.m_E.Count(), and added NULL check on bi in printPoints; in twistedcube.h, reviewed clean. |
| `SEC-0306` | **Sev 2** | Memory Leaks, Handle Leaks, Combination List Corruption, Allocator Mismatches, Double Free, and Uninitialized Macro Member | `src/proc-db (Batch 64: vegetation.c, vegetation.h, voxelize.c, wavy.c, wdb_example.c)` | `FIXED` | In BRL-CAD proc-db Batch 64 (vegetation.c, vegetation.h, voxelize.c, wavy.c, wdb_example.c, 1,995 lines): completing all 55 files of src/proc-db (100% complete): in vegetation.h, fixed uninitialized branchMaxVariation bug in INIT_CHARACTERISTIC_T macro caused by setting dirMaxVariation twice; replaced unsafe sprintf with bu_strlcpy in INIT_OUTPUTCOUNTER_T; in vegetation.c, fixed memory leak of bigList on error in findIntersectors; replaced system free with bu_free on bu_calloc/BU_ALLOC buffers (segList, excluded, included, plant, and structure allocations) to eliminate allocator mismatch; fixed persistent leaks of included and excluded segment lists during growth retries; implemented recursive freeStructure helper to eliminate memory leaks of deeply nested substructures, branches, and segments in destroyPlant; freed oc->combination.l and oc->region.l wmembers with mk_freemembers; guarded argv[0] before bu_setprogname; supported clean exit 0 on -h/-?/--help; replaced atoi, atof, and atol with bu_sscanf with range validation and clamped age [1, 200] to prevent memory/CPU exhaustion; checked fp from wdb_fopen against NULL; and replaced db_close(fp->dbip) with wdb_close(fp); in voxelize.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h/-?/--help; replaced atoi with bu_sscanf; freed voldata and ebmdata buffers and closed db_fp on sidecar write and primitive creation failures; freed region_hd.l, ebm_hd.l, and all_hd.l wmembers with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp); in wavy.c, guarded argv[0] before bu_setprogname; fixed option parsing so -h and -? exit 0 cleanly with usage; replaced atof with bu_sscanf; checked outfp returned by wdb_fopen; documented ownership transfer where mk_bspline/wdb_export takes ownership and frees surfaces via rt_nurb_ifree, avoiding double free; and replaced db_close(outfp->dbip) with wdb_close(outfp); in wdb_example.c, guarded av[0] before bu_setprogname; supported clean exit 0 on -h/-?/--help; eliminated combination member leak by freeing wm_hd.l with mk_freemembers; and replaced db_close(db_fp->dbip) with wdb_close(db_fp). |
| `SEC-0307` | **Sev 2** | Allocator Mismatch, Memory Leaks, Uninitialized Pointers, and NULL Pointer Dereferences | `src/qged (Batch 65: QgEdApp.cpp, QgEdApp.h, QgEdFilter.cpp, QgEdFilter.h, QgEdMainWindow.cpp, QgEdMainWindow.h)` | `FIXED` | In BRL-CAD qged Batch 65 (QgEdApp.cpp, QgEdApp.h, QgEdFilter.cpp, QgEdFilter.h, QgEdMainWindow.cpp, QgEdMainWindow.h, 1,604 lines): in QgEdApp.cpp, fixed allocator mismatch (CWE-762) by replacing C++ delete on bu_strdup strings with bu_free; fixed memory leak of argv array av allocated with bu_calloc in QgEdApp::run_cmd; added cleanup loop in destructor to free pending tmp_av strings; added NULL pointer checks on p->gedp, p->gedp->ged_io_data, ca->w, and ca->w->console before dereferencing in io handlers; guarded w and w->CurrentView() in run_cmd; guarded el, el->controls, and w->CurrentDisplay() in element_selected; added NULL guards in raytrace callbacks; in QgEdApp.h, audited clean; in QgEdFilter.cpp, added NULL pointer checks on event e and application model pointer c->mdl before accessing interaction_mode; in QgEdFilter.h, audited clean; in QgEdMainWindow.h, removed duplicate QgView.h include, and initialized pointer members console, cad_open, cad_save_settings, and cad_exit to NULL to prevent uninitialized memory reads (CWE-457); in QgEdMainWindow.cpp, added NULL pointer guards on c4 across isValid3D, isDisplayActive, CurrentDisplay, CurrentView, DisplayCheckpoint, DisplayDiff, QuadDisplay, SingleDisplay, and constructor mode switching; added NULL guards on vcw in IndicateRaytraceStart and IndicateRaytraceDone; added NULL guards on w and qApp in widget_active; and added NULL guards on ap->mdl and ap->mdl->gedp in CreateWidgets, ConnectWidgets, and do_dm_init. |
| `SEC-0308` | **Sev 2** | Memory Leaks, Uninitialized Pointers, Out-of-bounds Array / Buffer Access, and NULL Pointer Dereferences | `src/qged (Batch 66: QgEdPalette.cpp, QgEdPalette.h, fbserv.cpp, fbserv.h, main.cpp)` | `FIXED` | In BRL-CAD qged Batch 66 (QgEdPalette.cpp, QgEdPalette.h, fbserv.cpp, fbserv.h, main.cpp, 881 lines): in QgEdPalette.cpp, initialized filenames pointer to NULL before bu_file_list and guarded bu_argv_free, added NULL checks on cmd, cmd->i, cmd->i->tool_create, and returned tool element el before inserting into c_map and calling addElement, and guarded selected->button before setStyleSheet; in QgEdPalette.h, audited clean; in fbserv.h, initialized pointer and index members (s = nullptr, ind = -1, fbsp = nullptr) in QFBSocket and fbsp in QFBServer to prevent uninitialized memory access (CWE-457); in fbserv.cpp, guarded fbsp, s, ind bounds, and pkc in QFBSocket::client_handler, checked realloc return before updating pkc_inbuf to prevent NULL dereference on allocation failure, guarded buffer length and bounds (pkc_inend >= 0 && pkc_inend < pkc_inlen) before copying remaining data; in QFBServer::on_Connect, guarded nextPendingConnection return, fbsp, and validated socket descriptor fd >= 0 before pkg_adopt_socket; in qdm_is_listening and qdm_listen_on_port, checked fbsp against NULL; in qdm_open_server_handler and qdm_close_server_handler, guarded fbsp and listener channel nl, and cleared fbsl_chan and fbsl_fd to avoid dangling pointers; in qdm_open_client_handler and qdm_open_sw_client_handler, added client index bounds checks (0 <= i < fbs_max_clients) and guarded data, s->s, and fbsp->fbs_fbp; in qdm_close_client_handler, guarded client index and cleared fbsc_chan to NULL; in QFBIPCSocket::ipc_handler, guarded fbsp, ind bounds, notifier, and fbsc_pkg before client processing; in qdm_open_ipc_client_handler, qdm_open_ipc_sw_client_handler, and qdm_close_ipc_client_handler, added client index bounds checks and guarded fbsp->fbs_fbp; in main.cpp, guarded argc < 1, argv, and argv[0] before bu_setprogname to prevent NULL pointer dereference crashes on empty argument vectors, guarded argv[i] in option scanning loop, eliminated memory leaks of bu_vls msg on error paths and prior to QApplication launch by adding bu_vls_free(&msg). |
| `SEC-0309` | **Sev 2** | Illegal Free of Non-Heap Member, Double Free, Memory Leaks, Uninitialized Pointers, Model Invariant Violations, and NULL Pointer Dereferences | `src/qged (Batch 67: plugin.h, QEll.cpp, QEll.h, ell_tool.cpp, CADViewModel.cpp, CADViewModel.h, view_info.cpp)` | `FIXED` | In BRL-CAD qged Batch 67 (plugin.h, QEll.cpp, QEll.h, ell_tool.cpp, CADViewModel.cpp, CADViewModel.h, view_info.cpp, 777 lines): in plugin.h, audited clean; in QEll.h, initialized all pointer member variables to nullptr to prevent uninitialized pointer reads (CWE-457); in QEll.cpp, cleared struct rt_ell_internal ell with memset(&ell, 0, sizeof(ell)) in constructor; connected write_edit and reset_values buttons to their write_to_db and read_from_db slots; in destructor, set p = NULL after bv_obj_put(p); in read_from_db, guarded qApp against NULL and checked ellp against NULL before RT_ELL_CK_MAGIC; in write_to_db, fixed illegal free of non-heap C++ object member &ell (CWE-763/CWE-590) and subsequent double free (CWE-415) by dynamically allocating ellp via BU_ALLOC and relying on rt_db_put_internal's internal deallocation without redundant and dangerous rt_db_free_internal calls; in update_obj_wireframe, guarded qApp, gedp->dbip, p from bv_obj_get, wdbp from wdb_dbopen, child scene object s, and pl[i].str against NULL pointer dereferences; in update_viewobj_name, guarded qApp, gedp->dbip, p, and ell_name against NULL dereferences; in eventFilter, added NULL guard on event pointer e; in ell_tool.cpp, converted heap-allocated QIcon to stack allocation to eliminate memory leak (CWE-401); in CADViewModel.h, audited clean; in CADViewModel.cpp, guarded qApp and bview pointer v against NULL in refresh, and invoked beginResetModel before deleting m_root to preserve Qt model invariants and avoid use-after-free by attached views; set m_root = NULL in destructor; in view_info.cpp, converted heap-allocated QIcon to stack allocation and parented CADViewModel to vview to eliminate memory leaks (CWE-401). |
| `SEC-0310` | **Sev 2** | Memory Leaks, Uninitialized Pointers, Argument Indexing Corruption, and NULL Pointer Dereferences | `src/qged (Batch 68: CADViewMeasure.cpp, CADViewMeasure.h, measure.cpp, CADViewSelector.cpp, CADViewSelector.h, select.cpp, CADViewSettings.cpp, CADViewSettings.h, view_settings.cpp)` | `FIXED` | In BRL-CAD qged Batch 68 (CADViewMeasure.cpp, CADViewMeasure.h, measure.cpp, CADViewSelector.cpp, CADViewSelector.h, select.cpp, CADViewSettings.cpp, CADViewSettings.h, view_settings.cpp, 1,374 lines): in CADViewMeasure.h, removed duplicate QLineEdit include and initialized pointer members to nullptr to avoid uninitialized memory reads (CWE-457); in CADViewMeasure.cpp, freed f2d and f3d filters in destructor to fix memory leak (CWE-401); in adjust_text, eliminated persistent memory leak of QLabel on every event by reusing ma_label instead of repeatedly reallocating new QLabel instances; guarded qApp, gedp->ged_gvp, gedp->dbip, mf, and reports against NULL dereferences; in update_color and eventFilter, guarded mf, measure_3d, color_3d, color_2d, and filters; in measure.cpp, converted heap-allocated QIcon to stack allocation to prevent memory leak (CWE-401); in CADViewSelector.h, initialized all pointer members (including filter pointers pf, bf, rf) to nullptr; in CADViewSelector.cpp, freed pf, bf, and rf in destructor to fix memory leak (CWE-401); in select_objs and deselect_objs, guarded gedp, dbi_state, cf, and scene object s against NULL; in erase_objs, fixed indexing bug in av array where NULL scene objects created holes in the argv vector passed to ged_exec_erase, and checked scnt > 1 before execution; in do_draw_selections, do_erase_selections, and do_view_update, guarded dbis->pathstr return before calling bu_strdup and constructing std::string; in eventFilter, added NULL guards on event e, qApp, filters, and checkboxes; in select.cpp, converted heap-allocated QIcon to stack allocation to prevent memory leak (CWE-401); in CADViewSettings.h, initialized all pointer members to nullptr; in CADViewSettings.cpp, added NULL checks on cb in set_ckbx and ckbx_val; in checkbox_refresh and view_refresh, guarded qApp, gedp, bview v, v->gv_s, and fb_mode_combo against NULL pointer dereferences; in view_settings.cpp, converted heap-allocated QIcon to stack allocation to eliminate memory leak (CWE-401). |
| `SEC-0311` | **Sev 2** | Memory Leaks, Uninitialized Pointers, and NULL Pointer Dereferences | `src/qged (Batch 69: QPolyCreate.cpp, QPolyCreate.h, QPolySettings.cpp, QPolySettings.h, polygon_tool.cpp)` | `FIXED` | In BRL-CAD qged Batch 69 (QPolyCreate.cpp, QPolyCreate.h, QPolySettings.cpp, QPolySettings.h, polygon_tool.cpp, 1,239 lines): in QPolySettings.h, initialized all pointer member variables to nullptr to eliminate uninitialized pointer access (CWE-457); in QPolySettings.cpp, added explicit QWidget parent to constructor, fixed severe memory leak in uniq_obj_name where ovname and vname were leaked on both collision early exit and success paths (CWE-401), guarded sketch_sync and sketch_name against NULL in sketch_sync_toggled, checked line_snapping and grid_snapping in signal handlers, and guarded p, p->s_i_data, and all UI controls against NULL in settings_sync; in polygon_tool.cpp, stack-allocated QIcon objects in polygon_tool_create and polygon_tool_modify to eliminate heap allocation leaks (CWE-401); in QPolyCreate.h, initialized all pointer member variables to nullptr (CWE-457); in QPolyCreate.cpp, added explicit QWidget parent to constructor, freed pcf in destructor to prevent filter memory leak (CWE-401), guarded qApp, gedp, gedp->dbip, p->s_i_data, and sketch widgets in finalize, guarded qApp, gedp, gedp->ged_gvp, and ps in do_vpoly_copy, guarded qApp, gedp, gedp->dbip, and ps in do_import_sketch, guarded gedp->dbip and sketch controls in sketch_sync to prevent NULL pointer dereferences on uninitialized databases, guarded v->gv_s and scene objects in toggle_line_snapping, toggle_grid_snapping, and checkbox_refresh, and in eventFilter guarded event pointer e, qApp, gedp, pcf, p->s_i_data, and ps settings controls. |
| `SEC-0312` | **Sev 2** | Memory Leaks, Uninitialized Pointers, and NULL Pointer Dereferences | `src/qged (Batch 70: QPolyMod.cpp, QPolyMod.h)` | `FIXED` | In BRL-CAD qged Batch 70 (QPolyMod.cpp, QPolyMod.h, 1,124 lines): completing all 34 files of src/qged (100% complete): in QPolyMod.h, initialized all pointer member variables to nullptr (ps, mod_names, select_mode, move_mode, update_mode, general_mode_opts, close_general_poly, append_pnt, select_pnt, csg_modes, apply_bool, viewsnap_poly, remove_poly, p, cf, puf, psf, ppf, pmf) to eliminate uninitialized pointer access (CWE-457); in QPolyMod.cpp, added explicit QWidget parent to constructor, freed mouse filter objects puf, psf, ppf, and pmf in destructor to eliminate memory leaks (CWE-401), guarded qApp and mod_names in mod_names_reset, guarded ip and all UI controls in poly_type_settings, guarded qApp, p, p->s_i_data, and ps settings controls in polygon_update_props, guarded qApp and gedp->ged_gvp in toplevel_config, guarded p and p->s_i_data in clear_pnt_selection, guarded qApp, gedp->ged_gvp, and ps in select, guarded p, p->s_i_data, close_general_poly, and boolean operation objects in toggle_closed_poly, guarded qApp, p, p->s_i_data, gedp->ged_gvp, and csg_modes in apply_bool_op, guarded qApp, p, p->s_i_data, and gedp->ged_gvp in align_to_poly, guarded qApp, p, p->s_i_data, and mod_names in delete_poly, guarded gedp->dbip and sketch controls in sketch_name_edit, checked existing sketch collision and guarded gedp->dbip in sketch_name_update, guarded qApp and ps in view_name_edit and view_name_update, guarded v->gv_s in toggle_line_snapping, toggle_grid_snapping, and checkbox_refresh, and in eventFilter guarded event pointer e, qApp, gedp, filters, p->s_i_data, and UI controls. |
| `SEC-0313` | **Sev 2** | Memory Leaks, Uninitialized Pointers, Off-by-one, Missing Header Guard, and NULL Pointer Dereferences | `libqtcad & include/qtcad (Batch 71: 14 files)` | `FIXED` | In BRL-CAD libqtcad Batch 71 (14 files, 1,563 lines): in defines.h, wrapped QTCAD_SLOT and QTCAD_EVENT macro definitions in do-while(0) blocks for safe statement syntax and guarded slot_name and event_name against NULL; in QgSignalFlags.h, added missing #define QGSIGNALFLAGS_H include guard; in QgAccordion.h, made constructors explicit with default nullptr and initialized all pointer members to nullptr; in QgAccordion.cpp, reparented objscrollarea to this, guarded addObject against null pointers and prevented duplicate insertion and redundant signal-slot connections, and guarded against null objects in accordion display loop; in QgAppExecDialog.h, added explicit constructor and destructor declarations and initialized logfile, console, proc, and buttonBox to nullptr; in QgAppExecDialog.cpp, implemented destructor closing and deleting logfile to eliminate persistent memory leaks (CWE-401), deleted logfile on open failure, and guarded proc, console, and buttonBox in read_stdout, read_stderr, process_abort, and process_done to prevent NULL pointer dereferences (CWE-476); in QgAttributesModel.h, modernized constructors and initialized pointers; in QgAttributesModel.cpp, deleted m_root in destructor and prior to allocating a new root in update and do_dbi_update to eliminate severe memory leaks (CWE-401), replaced unsafe bu_avs_remove loop during iteration with canonical bu_avs_free and bu_avs_init_empty, fixed off-by-one error in beginInsertRows (inclusive cnt - 1 bound), guarded against out-of-bounds access in add_Children when color attribute has fewer than 3 components (CWE-125), guarded against NULL strings and nodes, properly nested data updates between beginResetModel and endResetModel, and validated QModelIndex in refresh; in QgColorRGB.h, removed unused dead member d and initialized pointers to nullptr; in QgColorRGB.cpp, reparented child widgets to this, zeroed bu_color structure, used bu_color_from_rgb_chars for direct color synchronization, and guarded against NULL text and button pointers; in QgDockWidget.h, initialized m to nullptr and made constructor explicit; in QgDockWidget.cpp, removed unused map and set headers, guarded event pointer against NULL in event() to prevent crash, and replaced C-style cast with static_cast; in QgFlowLayout.h, initialized spacing members; in QgFlowLayout.cpp, guarded addItem, minimumSize, and doLayout against NULL items, checked widget and style pointers before layoutSpacing to prevent NULL pointer dereference crashes (CWE-476), clamped negative spacing, and returned nullptr in takeAt. |
| `SEC-0314` | **Sev 2** | Memory Leaks, Division by Zero, Syntax / Declaration Errors, Missing Header Guards, and NULL Pointer Dereferences | `libqtcad & include/qtcad (Batch 72: 9 files)` | `FIXED` | In BRL-CAD libqtcad Batch 72 (9 files, 1,422 lines): in QgKeyVal.h, initialized pointer members (m_root, parent) to nullptr, added explicit constructors, and added override specifiers; in QgKeyVal.cpp, initialized m_root to nullptr in model constructor to prevent undefined pointer dereferences (CWE-457), guarded curr_node against NULL in data and setData, ordered model reset correctly by calling beginResetModel before updating m_root in setRootNode, checked row bounds against child count before accessing children in index to prevent out-of-bounds reads (CWE-125), guarded node and parent pointers in parent, rowCount, NodeIndex, and NodeRow to prevent NULL pointer dereferences (CWE-476), and guarded string pointers in add_pair; in QgUtil.h, formatted header guard comment; in QgUtil.cpp, eliminated critical memory leak of bu_attribute_value_set in QgCombType by calling bu_avs_free before returning on all paths (CWE-401), guarded dp and dbip in get_arb_type, db_find_subregion, db_find_region, and QgCombType against NULL pointer dereferences, initialized intern structure with RT_DB_INTERNAL_INIT, replaced bu_bomb in db_find_subregion default case with non-fatal logging to prevent application crash on malformed CSG trees (CWE-755), and guarded comb pointer in db_find_region; in bindings.h, added standard QTCAD_BINDINGS_H header guard; in bindings.cpp, guarded against NULL event pointer in CADkeyPressEvent, CADmousePressEvent, CADmouseReleaseEvent, CADmouseMoveEvent, and CADwheelEvent, checked v->gv_s before accessing axes and ADC draw flags to prevent crash on uninitialized views (CWE-476), and prevented division by zero in CADmouseMoveEvent scaling calculation by clamping v->gv_height to a positive value (CWE-369); in QgConsoleListener.h, added standard QGCONSOLELISTENER_H header guard and initialized process, callback, data, and notifier members to nullptr; in QgConsoleListener.cpp, guarded process, process->gedp, and result string against NULL before checking string length or reading results, prevented unsigned integer underflow (CWE-191) on string length subtraction by verifying s2 > s1, safely disabled and disconnected notifier in destructor, and initialized members in constructor initialization list; in QgEdit.h, resolved syntax errors by adding missing semicolons to class declarations, corrected class name consistency (QgVectEdit), closed unclosed comment, made constructors explicit, and initialized pointer members (vx, vy, vz, dbip) to nullptr. |
| `SEC-0315` | **Sev 2** | Memory Leaks, Out-of-Bounds Access, Division by Zero, and NULL Pointer Dereferences | `libqtcad & include/qtcad (Batch 73: 8 files)` | `FIXED` | In BRL-CAD libqtcad Batch 73 (QgConsole.h, QgConsole.cpp, QgToolPalette.h, QgToolPalette.cpp, QgTreeSelectionModel.h, QgTreeSelectionModel.cpp, QgTreeView.h, QgTreeView.cpp, 2,342 lines): in QgConsole.h, initialized gedp pointer to nullptr; in QgConsole.cpp, eliminated memory leak of ct and av in GEDShellCompleter when gedp or dbip is null (CWE-401), replaced unsafe C-style cast on parent() with qobject_cast, bounded completionModel indexing, fixed out-of-bounds history indexing in consolidateHistory (CWE-125), eliminated dangling pointer read from temporary toLocal8Bit buffer in historyAt using toStdString (CWE-416), guarded Completer popup against NULL in keyPressEvent, selectCompletion, and updateCompleter, added NULL checks on clipboard and mimeData before text extraction, bounded CommandPosition on Key_Up and Key_Down, guarded CommandHistory against empty back() access in commandBuffer, fixed off-by-one word replacement in insertCompletion, prevented listener memory leak in destructor and listen() (CWE-401), and clamped cursor offsets to document bounds in printStringBeforePrompt; in QgToolPalette.h, initialized all pointer and layout members to nullptr; in QgToolPalette.cpp, guarded iicon in QgToolPaletteButton constructor and setter to prevent NULL dereference crashes (CWE-476), guarded controls in QgToolPaletteElement constructor and setter, implemented destructor in QgToolPalette to delete palette elements and prevent memory leaks (CWE-401), eliminated division by zero in button_layout_resize when width is smaller than icon width (CWE-369), fixed typo in setIconWidth where icon_height was assigned to button width, guarded empty elements set in setAlwaysSelected and deleteElement to prevent out-of-bounds / end-iterator dereference crashes (CWE-125/CWE-476), and guarded controls, scrollbars, and buttons in palette_displayElement; in QgTreeSelectionModel.h, initialized treeview to nullptr; in QgTreeSelectionModel.cpp, added NULL pointer checks on treeview, m, gedp, and dbi_state in clear_all and select slots, checked sv[0] bounds, eliminated heap allocation memory leak of QModelIndexList on every selection event by using stack allocation (CWE-401), and guarded snode against NULL before accessing path_hash and path_items (CWE-476); in QgTreeView.h, initialized model and delegate pointers to nullptr; in QgTreeView.cpp, guarded painter and invalid QModelIndex in gObjDelegate::paint, clamped icon height to prevent invalid image scaling, parented draw_action and erase_action to QMenu in context_menu to eliminate action memory leaks on menu deletion (CWE-401), guarded index, cnode, gedp, and view states in do_draw_toggle, guarded against empty path_hashes before back() and pop_back(), guarded m and items in redo_expansions and redo_highlights, and added NULL checks on model m before emitting layoutChanged. |
| `SEC-0316` | **Sev 2** | Memory Leaks, Uninitialized Pointers, Out-of-Bounds Access, and NULL Pointer Dereferences | `libqtcad & include/qtcad (Batch 74: 10 files)` | `FIXED` | In BRL-CAD libqtcad Batch 74 (QgView.h, QgView.cpp, QgViewCtrl.h, QgViewCtrl.cpp, QgGL.h, QgGL.cpp, QgSW.h, QgSW.cpp, QgQuadView.h, QgQuadView.cpp, 2,910 lines): in QgView.h, audited clean; in QgView.cpp, replaced return in switch default with break, set canvas_gl and canvas_sw to NULL after deletion in destructor, guarded add_event_filter against NULL, and in clear_event_filter properly updated filters vector and curr_event_filter while ensuring event filters are removed from both GL and SW canvases; in QgViewCtrl.h, initialized QAction pointer members (sca, rot, tra, center, raytrace, fb_mode, fb_clear) to nullptr; in QgViewCtrl.cpp, guarded gedp in fbclear_cmd, fb_mode_cmd, do_view_update, and raytrace_cmd, checked v->gv_s in fb_mode_cmd and do_view_update to prevent NULL pointer dereferences (CWE-476), guarded callback context vctrl in rt_cmd_start and rt_cmd_done, and guarded raytrace before setIcon in raytrace_start and raytrace_done; in QgGL.h, audited clean; in QgGL.cpp, fixed critical memory leak in destructor by calling bv_free on local_v prior to deallocation and corrected struct name in BU_PUT from struct bv to struct bview (CWE-401), set pointers to NULL upon destruction, guarded fb_get_platform_specific return against NULL before dereferencing fbps->data, guarded dm_bg1 and dm_bg2 before dm_set_bg, checked dmp in mouseReleaseEvent before calling dm_set_dirty, guarded v before bv_hash in stash_hashes and diff_hashes, and checked for null QImage in save_image; in QgSW.h, audited clean; in QgSW.cpp, fixed memory leak in destructor by calling bv_free(local_v) and corrected BU_PUT struct name (CWE-401), guarded dmp against NULL in need_update and paintEvent before calling dm_set_dirty, checked width and height bounds before painting and image allocation, guarded fbps return before setup, guarded dm_bg1 and dm_bg2, checked dm_image against NULL in paintEvent and save_image, checked dmp in mouseReleaseEvent, guarded v before bv_hash in stash_hashes and diff_hashes, and guarded dmp and dm_image in save_image and get_viewport_image; in QgQuadView.h, initialized currentView and gedp to nullptr; in QgQuadView.cpp, guarded gedp and view pointers in constructor, createView, changeToSingleFrame, and changeToQuadFrame, clamped index bounds in createView to prevent out-of-bounds reads on VIEW_NAMES array (CWE-125), guarded chained pointers v->gv_s in changeToQuadFrame, guarded view objects in autoview and draw_scene loops, deleted old layout before creating a new one in createLayout to prevent layout leaks and Qt warnings, guarded currentView in view() and do_view_changed, eliminated unsafe parent geometry lookup in get(QPoint) by using widget-local rect and mapFromGlobal, guarded event e in get(QEvent), and guarded quadrant_id and spacer pointers in select. |
| `SEC-0317` | **Sev 2** | Memory Leaks, NaN Domain Errors, Use-After-Free, Division by Zero, and NULL Pointer Dereferences | `libqtcad & include/qtcad (Batch 75: 8 files)` | `FIXED` | In BRL-CAD libqtcad Batch 75 (QgMeasureFilter.h, QgMeasureFilter.cpp, QgPolyFilter.h, QgPolyFilter.cpp, QgSelectFilter.h, QgSelectFilter.cpp, QgSketchFilter.h, QgSketchFilter.cpp, 2,899 lines): in QgMeasureFilter.h, declared virtual destructor in QgMeasureFilter; in QgMeasureFilter.cpp, implemented destructor releasing scene object s, fixed critical logic inversion bug in QgMeasureFilter::angle(bool radians) where radians and degrees were swapped, clamped dot product to [-1.0, 1.0] before acos to prevent NaN domain errors, guarded vector unitization against division by zero with ZERO(mag), added null checks on s after bv_obj_get and cleared s = NULL on reset to prevent use-after-free and null dereferences, guarded v in QMeasure2DFilter::get_point, implemented QMeasure3DFilter destructor to clean and free rt_resource, rtip, and application structures eliminating severe memory leaks (CWE-401), cleaned prior raytrace resources before allocating new ones on prep, guarded ray direction magnitude, and cleaned resources on tree loading failure; in QgPolyFilter.h and QgPolyFilter.cpp, added virtual destructors to base QgPolyFilter and derived classes (QPolyCreateFilter, QPolyUpdateFilter, QPolyMoveFilter) to free bu_ptbl containers bool_objs and move_objs eliminating memory leaks (CWE-401), guarded wp, checked contour existence before indexing contour 0, cleared wp->s_i_data = NULL on freeing unclosed polygon, and guarded bv_create_polygon return, wp->s_v, and wp->s_i_data across event handlers; in QgSelectFilter.h and QgSelectFilter.cpp, declared and implemented virtual destructor in QgSelectFilter to free selected_set with bu_ptbl_free (CWE-401), guarded sset and v in closest_obj_bbox and guarded ray direction unitization against division by zero, guarded v and v->gv_s in QgSelectBoxFilter::eventFilter and prevented division by zero when viewport dimensions are zero, removed debug logging spam, and ensured rt_clean_resource is called before destroying rtip and freeing resp/ap on all paths in QgSelectRayFilter; in QgSketchFilter.h and QgSketchFilter.cpp, added virtual destructor to base QgSketchFilter, guarded output parameters and verified sketch magic in screen_to_uv and snap_vertex_uv, guarded v and es against null in all event filters, verified valid ft_set_edit_mode function pointer before invocation, added bounds check on seg_idx against curve count and deg against RT_EDIT_MAXPARA in sketch_seg_sample, bounded all vertex indices against vert_count, guarded arc direction length against zero in sketch_arc_center_uv, bounded curr_seg and full-circle cs->end in QgSketchArcRadiusFilter, guarded event pointer in QgSketchCursorTracker, and safely extracted curr_seg without null dereference in QgSketchSetTangencyFilter. |
| `SEC-0318` | **Sev 2** | Memory Leaks, Uninitialized Pointers, Division by Zero, Model Invariant Violations, and NULL Pointer Dereferences | `libqtcad & include/qtcad (Batch 76: 7 files)` | `FIXED` | In BRL-CAD libqtcad Batch 76 (QgGeomImport.h, QgModel.h, QgGeomImport.cpp, QgModel.cpp, tests/qgmodel.cpp, tests/qgview.cpp, tests/qsketch.cpp, 1,323 lines): in QgModel.h, initialized rootItem to NULL to prevent uninitialized pointer dereference (CWE-457); in QgModel.cpp, fixed severe memory leak in destructor by iterating through and deleting all QgItem allocations in items before deleting container, freed empty_gvp, and safely deleted gedp->dbi_state before calling ged_close (CWE-401), deleted existing rootItem and cleared items on g_update reset, guarded mdl, gedp, and dbi_state in QgItem_cmp to prevent SIGSEGV crashes during sorting, added comprehensive null checks in QgItem constructor and path_hash, guarded mdl, gedp, dbi_state, and dp in update callbacks, guarded node and index in NodeRow, canFetchMore, and fetchMore, guarded qi, gedp, dbi_state, and ged_gvp in data(), validated argc and argv in run_cmd, verified sender QAction cast and guarded cnode in draw/erase actions, and added bounds and null checks in item expand/collapse handlers; in QgGeomImport.h and QgGeomImport.cpp, explicitly marked constructors and initialized all pointer members to NULL across ASCImportDialog, RhinoImportDialog, and STEPImportDialog (CWE-457), reparented dialog widgets to this for proper Qt memory ownership, deleted out_win in exec_console_app_in_window to prevent persistent dialog leaks (CWE-401), guarded bu_dir return before QString construction, added null checks on dialog UI controls in options(), and fixed critical logic flaw in gfile() where canceling an import dialog still executed the converter by checking dialog.exec() != QDialog::Accepted; in tests/qgmodel.cpp, tests/qgview.cpp, and tests/qsketch.cpp, guarded path_hashes against empty underflow and validated argc/argv with clean help handling in qgmodel, validated argc/argv with clean help handling and corrected argv[1] model path in qgview, and in qsketch validated argc/argv, added clean db_close on error exit paths, guarded nteeth <= 0 in sketch_create_gear to prevent division by zero (CWE-369), verified dp and dbip in QSketchEditWindow constructor, and guarded vertex/segment arrays and view in table population and screenshot methods. |
| `SEC-0319` | **Sev 2** | Stack Out-of-Bounds Read, Memory Leaks, Resource Leaks, Uninitialized Memory, Path Detection Bugs, and NULL Pointer Dereferences | `libtclcad & include/tclcad (Batch 77: 15 files)` | `FIXED` | In BRL-CAD libtclcad Batch 77 (include/tclcad.h, include/tclcad/defines.h, include/tclcad/draw.h, include/tclcad/misc.h, include/tclcad/setup.h, tclcad_private.h, auto_path.c, cmdhist.c, command_io.cpp, eval.c, global.c, init.c, tests/check_itcl.cpp, tests/check_multi_interp.cpp, tests/check_tclcad_cmds.cpp, 3,267 lines): in include/tclcad/draw.h, corrected header guard comment from TCLCAD_MISC_H to TCLCAD_DRAW_H; in auto_path.c, fixed critical path detection bugs where ITCL_LIBRARY and ITK_LIBRARY overrides appended filename (itcl.tcl/itk.tcl) and inserted file path instead of directory into auto_path, breaking subsequent file existence checks, fixed itk_set flag never being set to 1, eliminated capturing Tcl error message into paths when tcl_library is unset by replacing unchecked Tcl_Eval with Tcl_GetVar, and added _insert_unique_path helper to deduplicate path entries; in cmdhist.c, fixed severe memory leak of str on all exit paths of tclcad_cmdhist_history (CWE-401), closed fp before error returns to prevent file descriptor leaks, guarded against NULL argv and argv[0], guarded chop and argv[2] in tclcad_cmdhist_add, guarded chop, cho_curr, and BU_LIST boundaries in tclcad_cmdhist_prev/curr/next, guarded chop->cho_curr in cho_cmd before dereferencing, replaced redundant nested BU_LIST_NEXT calls with standard while (BU_LIST_WHILE(...)) dequeue loop in cho_deleteProc, and guarded objects and interp in cho_open/cho_open_tcl; in command_io.cpp, initialized interp to NULL and io_mode to 0 in tclcad_create_io_data eliminating uninitialized struct members (CWE-457), and guarded p->p in tclcad_delete_io_handler to prevent NULL pointer dereference in bu_process_fileno (CWE-476); in eval.c, validated interp and command, guarded args against NULL, and ensured individual argument strings are non-null in tclcad_eval and tclcad_eval_noresult; in global.c, guarded clientData against NULL in tclcad_interp_objects_delete, guarded interp and key in tclcad_interp_objects, and guarded state in tclcad_current_top; in init.c, guarded clientData, interp, and cmds in tclcad_init_state_delete, tclcad_init_state, and tclcad_register_cmds, guarded ctp and ct_func in wrapper_func, guarded filename in tclcad_source_file, verified non-null state in tclcad_init, and fixed critical out-of-bounds stack read (CWE-125) in tclcad_set_argv where !argv caused cast of a single-char stack variable to (const char **) passed into Tcl_Merge, handling empty/non-positive argc cleanly without invalid memory access; in tests/check_itcl.cpp, tests/check_multi_interp.cpp, and tests/check_tclcad_cmds.cpp, validated argv and argv[0] before bu_setprogname/Tcl_FindExecutable and added standard -h/-?/--help usage output with clean exit 0. |
| `SEC-0320` | **Sev 2** | Memory Leaks, Stack Out-of-Bounds Reads, Uninitialized Memory, Missing Include Guards, and NULL Pointer Dereferences | `src/libtclcad/view (Batch 78: 10 files)` | `FIXED` | In BRL-CAD libtclcad Batch 78 (view.h, arrows.c, autoview.c, axes.c, draw.c, faceplate.c, labels.c, lines.c, refresh.c, util.c, 2,912 lines): in view.h, added include guards, C++ extern C wrappers, and extern specifier on to_data_lines; in util.c, guarded gdvp, gdvp->dmp, current_top, and current_top->to_interp in to_is_viewable (CWE-476), initialized result_int to 0 (CWE-457), and prevented Tcl_Obj reference count memory leak on evaluation error by restoring and decrementing saved_result before early return (CWE-401); in autoview.c, fixed out-of-bounds argv[1] read in to_autoview by validating argc < 2 || argc > 3 (CWE-125), guarded tvd, tvd->gedp, current_top, and interp in to_autoview_view, and guarded top, top->to_gedp, and views in to_autoview_all_views; in arrows.c, fixed severe memory leak in points parsing where odd point count returned BRLCAD_ERROR without calling Tcl_Free((char *)av) (CWE-401), guarded current_top->to_gedp->u_data before disabling refresh_on, guarded gedp, gdvp, argv, and interp across go_data_arrows, to_data_arrows, and to_data_arrows_func, and added negative bounds validation on line_width, tip_length, and tip_width; in axes.c, guarded to_axes against argc < 3, NULL gedp, gdvp, gasp, and argv[2], validated non-negative values for axes_size, line_width, tick_interval, tick_length, tick_major_length, and ticks_per_major, guarded current_top, gdvp, and interp across go_data_axes and to_data_axes, and guarded gdvp->gv_s in to_model_axes, go_view_axes, and to_view_axes preventing NULL pointer crashes on uninitialized views (CWE-476); in draw.c, guarded hash table, udata, s_fpath, and dbip in key_matches_paths, guarded tvd->gedp, gedp->u_data, gedp->dbip, and sp->s_os in go_draw_solid, guarded gedp, ged_dl, and sp->s_os in go_draw_dlist, checked gdvp->dmp in go_draw, and in to_edit_redraw guarded dbip, ged_dl, verified !BU_LIST_IS_HEAD before dereferencing sp->s_os, and ensured last_gdlp is not head before dequeue and insert; in faceplate.c, guarded gedp, gdvp, and gdvp->gv_s in to_faceplate, and added RGB color range validation [0, 255] across center_dot, prim_labels, view_params, and view_scale; in labels.c, implemented _free_data_labels helper to safely free all allocated label strings and point buffers on Tcl_SplitList parsing failure, eliminating memory leaks on malformed input lists (CWE-401), guarded current_top, gedp, gdvp, and interp in go_data_labels, to_data_labels, and to_data_labels_func, validated non-negative label size, and in to_prim_label guarded current_top, gedp, and argv, prevented negative list size corruption on argc == 0, and safely reset list when argc == 1; in lines.c, guarded current_top, gedp, gdvp, and argv across go_data_lines and to_data_lines; in refresh.c, guarded gedp, gdvp, dbip, gdvp->gv_s, and current_top in go_refresh_draw, eliminated duplicate dm_draw_viewobjs call, guarded gdvp->u_data and dmp in go_refresh, guarded gdvp, top, and views in to_refresh_view and to_refresh_all_views, guarded gedp and current_top in to_refresh, to_refresh_all, and to_refresh_on, and added NULL checks in to_handle_refresh and to_refresh_handler. |
| `SEC-0321` | **Sev 2** | Type Confusion, Double Free, Premature Object Deallocation, Memory Leaks, Heap Buffer Underflow, Division by Zero, and NULL Pointer Dereferences | `src/libtclcad (Batch 79: bu.c, fbserv.c, rt.c, tkImgFmtPIX.c, wrapper.c)` | `FIXED` | In BRL-CAD libtclcad Batch 79 (bu.c, fbserv.c, rt.c, tkImgFmtPIX.c, wrapper.c, 2,388 lines): in tkImgFmtPIX.c, fixed critical type confusion vulnerability in FileWritePIX where Tcl_Obj * format was passed directly into Tcl_AppendResult (which expects const char * strings), causing illegal pointer dereferences and application crashes (CWE-843), guarded format against NULL in FileReadPIX to prevent NULL pointer dereference in Tcl_GetStringFromObj (CWE-476), checked widthPtr and heightPtr before writing in FileMatchPIX, validated image dimensions and pixelSize in FileWritePIX, added integer overflow protection on fileWidth * pixelSize pitch calculation, bounded srcX and srcY, and matched bu_malloc/bu_free allocation labels; in rt.c, eliminated critical double-free / premature object deallocation bugs in tcl_obj_to_int_array and tcl_obj_to_fastf_array where Tcl_DecrRefCount was erroneously called on list elements returned by Tcl_ListObjGetElements (corrupting Tcl object refcounts and causing use-after-free and crash when lists are accessed or freed, CWE-416/CWE-415), fixed severe memory leaks in tcl_list_to_int_array and tcl_list_to_fastf_array by properly incrementing and decrementing the temporary Tcl_Obj wrapper (CWE-401), eliminated division by zero in tclcad_rt_parse_ray by verifying direction vector magnitude with ZERO() macro before unitizing (CWE-369), guarded against array out-of-bounds reads on xyz in tclcad_rt_pr_cutter, replaced undefined variable rayp with NULL in RT_HIT_NORMAL, replaced sprintf/sscanf/atoi with snprintf/bu_sscanf across all command wrappers, and added comprehensive NULL checks on clientData, interp, and argv; in wrapper.c, fixed heap buffer underflow (CWE-125) in to_more_args_func where trimming an empty first element decremented ac_more to 0, causing avmp[ac_more-1] to access avmp[-1], eliminated memory leaks in to_view_func_common and to_dm_func by allocating av only after argument validation, help checks, and view lookup, guarded gdvp->gv_s and gdvp->dmp before accessing view state and setting perspective, guarded tgd and current_top->to_interp, and replaced bu_vls_addr with bu_vls_cstr; in fbserv.c, guarded clientData, fbslp, fbsp, and string pointers in comm_error and new_client_handler, added index bounds checks (0 <= i/sub < MAX_CLIENTS) in open/close client handlers and Windows IPC handlers, validated port range [0, 65535], and replaced unsafe sprintf with snprintf; in bu.c, guarded ctp and ct_func in lwrapper_func, guarded interp and argv in tcl_bu_get_value_by_keyword, prevented string truncation underflow on short lists, replaced raw sscanf with bu_sscanf in color converters, guarded dirkey in _tclcad_bu_dir_print, checked conv_factor with ZERO() macro in tcl_bu_units_conversion, and replaced all bu_vls_addr calls with bu_vls_cstr. |
| `SEC-0322` | **Sev 2** | Out-of-Bounds Reads, Memory Leaks, Parameter Swaps, Division by Zero, Integer Overflow / Dimension Guards, and NULL Pointer Dereferences | `src/libtclcad (Batch 80: bn.c, fb.c)` | `FIXED` | In BRL-CAD libtclcad Batch 80 (bn.c, fb.c, 2,535 lines): in fb.c, fixed critical out-of-bounds argument vector read in fbo_clear_tcl where argc == 3 erroneously accessed argv[6] instead of argv[2], causing invalid memory reads and segmentation crashes (CWE-125); added integer overflow protection and dimension clamping (<= 32768) in fbo_cell_tcl and fbo_rect_tcl preventing excessive memory allocation and heap buffer overflow (CWE-190/CWE-789); validated rectangle bounds against framebuffer dimensions (xmin + width <= fb_w and ymin + height <= fb_h) in fbo_cell_tcl and fbo_rect_tcl preventing memory corruption outside framebuffer bounds (CWE-125/CWE-787); validated port range (<= 65535) in fbo_listen_tcl and to_listen; corrected return code mapping in fbo_cmd from raw BRLCAD_ERROR to TCL_ERROR; added comprehensive NULL guards on gdvp, tvd, fbop, fbp, interp, gedp, and argv across fbo_coords_ok, fbo_deleteProc, fbo_close_tcl, fbo_clear_tcl, fbo_cursor_tcl, fbo_getcursor_tcl, fbo_refresh_tcl, fbo_listen_tcl, fbo_pixel_tcl, fbo_cell_tcl, fbo_flush_tcl, fbo_getheight_tcl, fbo_getwidth_tcl, fbo_getsize_tcl, fbo_rect_tcl, fbo_configure_tcl, to_fbs_callback, to_close_fbs, to_open_fbs, to_set_fb_mode, and to_listen; replaced unsafe sscanf with bu_sscanf and bu_vls_addr with bu_vls_cstr; in bn.c, fixed swapped parameter bug in tclcad_bn_eigen2x2 where matrix element b was parsed into c and c into b; prevented division by zero in tclcad_bn_mat_lookat by verifying hypot_xy with ZERO() macro before passing to bn_mat_lookat (CWE-369); corrected broken logic in bn_cmd_noise_slice which misread argv indices, discarded loop computations, and fell through to invalid noise types, replacing it with proper index reading, dimension validation (<= 4096), and returning the formatted noise list; fixed memory leak in tclcad_bn_mat_arb_rot on double conversion failure by routing to error label (CWE-401); added missing error messages on bn_decode_vect failures in vector functions; replaced unsafe atof with Tcl_GetDouble in bn_cmd_noise_perlin and bn_cmd_noise; replaced sscanf with bu_sscanf; guarded snprintf buffer sizes; and added comprehensive NULL checks on interp, argv, and clientData across all 35 math command wrappers. |
| `SEC-0323` | **Sev 2** | Use-After-Free, Memory Leaks, Buffer Underflow / Out-of-Bounds Reads, Wrong Argument Indexing, Port Range Validation, and NULL Pointer Dereferences | `src/libtclcad (Batch 81: polygons.c, dm.c)` | `FIXED` | In BRL-CAD libtclcad Batch 81 (polygons.c and dm.c, 4,781 lines): in dm.c, fixed critical use-after-free vulnerability in fb_cmd_common_file_size where dynamic string zerr was passed to Tcl_SetResult with TCL_STATIC and immediately freed with bu_free, leaving Tcl pointing to freed heap memory (CWE-416); fixed critical out-of-bounds argument vector read in dmo_logfile_tcl where argc == 3 erroneously accessed argv[3] instead of argv[2] (CWE-125); guarded out-of-bounds vector reads in error and help handlers across 28 display manager command callbacks; guarded vector index decodes in dmo_parseAxesArgs, dmo_parseDataAxesArgs, and dmo_parseModelAxesArgs; added port range validation (<= 65535) in dmo_listen_tcl; mapped return codes in dmo_cmd from BRLCAD_OK to TCL_OK/TCL_ERROR; replaced sprintf with snprintf; replaced raw atof/atoi with sscanf/bu_sscanf; replaced all bu_vls_addr calls with bu_vls_cstr; added comprehensive NULL checks on dmop, interp, dmo_dmp, and dmo_dmp->i across all 38 display manager routines; in polygons.c, implemented _free_partial_poly and _free_partial_polygon_state cleanup helpers to eliminate severe memory leaks on parse/split failures (CWE-401); freed contour_av on replace_poly success; freed allocated bg_polygon in import; fixed off-by-one out-of-bounds indexing in target_poly (CWE-125); prevented size_t underflow in clip when num_polygons == 0 and state corruption when num_polygons < 2; checked bg_clip_polygon result for NULL; guarded gdvp->dmp, current_top->to_gedp->u_data, current_top->to_interp, and gv_s across all polygon commands; and replaced bu_vls_addr with bu_vls_cstr. |
| `SEC-0324` | **Sev 2** | Memory Leaks, Uncomputed Model Coordinates Logic Bug, Buffer Overflow / Missing NULL-terminator, Division by Zero, Uninitialized Pointers, and NULL Pointer Dereferences | `src/libtclcad (Batch 82: mouse.c)` | `FIXED` | In BRL-CAD libtclcad Batch 82 (mouse.c, 3,594 lines): fixed critical logic bug in to_mouse_otranslate where model point was declared with VINIT_ZERO and never transformed by the inverse rotation matrix before printing into tran_x_vls, tran_y_vls, tran_z_vls and passing to ged_exec_otranslate (which caused all mouse translations to pass 0, 0, 0); eliminated persistent memory leaks of brep_name and bindings bu_vls on failure paths in to_mouse_brep_selection_append and to_mouse_brep_selection_translate (CWE-401); eliminated memory leaks of joint_name and bindings bu_vls on failure paths in to_mouse_joint_select and to_mouse_joint_selection_translate (CWE-401); fixed buffer allocation and missing NULL terminator in to_mouse_move_bot_pnts where allocating ac elements resulted in av[ac-1] being overwritten by the loop and leaving no NULL termination (CWE-125/CWE-787), allocating ac + 1 and properly terminating; fixed uninitialized gedp->ged_gvp pointer dereference and wrong view rotation matrix inversion in to_mouse_brep_selection_append, to_mouse_joint_select, to_mouse_poly_circ_func, to_mouse_poly_ell_func, to_mouse_poly_rect_func, and to_data_scale (CWE-476); prevented division by zero across to_mouse_constrain_trans, to_mouse_move_arb_edge, to_mouse_move_arb_face, to_mouse_move_bot_pnt, to_mouse_move_bot_pnts, to_mouse_move_pnt_common, to_mouse_oscale, to_mouse_otranslate, TO_COMMON_MOUSE_SCALE, to_mouse_pscale, to_mouse_ptranslate, and to_mouse_trans by clamping width <= 0 to 1 before calculating inv_width (CWE-369); corrected error messages in to_mouse_constrain_rot and to_mouse_constrain_trans on invalid axis; guarded wdbp returned from wdb_dbopen in to_mouse_move_bot_pnt; guarded gdvp->dmp in to_mouse_rect before calling dm_get_height; guarded current_top, current_top->to_interp, current_top->to_gedp, and u_data across all callback executions and polygon functions; and modernized all (~38) bu_vls_addr calls to bu_vls_cstr. |
| `SEC-0325` | **Sev 2** | Inverted Logic / Crasher, Resource Leaks, Buffer Overflow / Unchecked sprintf, Division by Zero, Type Confusion, Memory Leaks, and NULL Pointer Dereferences | `src/libtclcad (Batch 83: commands.c)` | `FIXED` | In BRL-CAD libtclcad Batch 83 (commands.c, 6,748 lines): completing all 31 files of src/libtclcad (100% complete): fixed critical inverted logic bug in to_pix where dm_make_current returning BRLCAD_OK (0) was treated as failure via !make_ret and aborted; fixed persistent resource leaks of PNG write structures in to_png on error and exit paths by properly invoking png_destroy_write_struct; fixed memory leak of callback_cmd bu_vls in to_rt_end_callback_internal; fixed severe buffer overflow vulnerability and memory leak in to_dplot where fixed stack buffer av[256] lacked bounds check on split list length, had an off-by-one indexing error on NULL terminator, and leaked memory on Tcl_Eval failure; fixed type confusion bug in free_path_edit_params by using correct struct dm_path_edit_params; fixed division-by-zero vulnerabilities in to_bounds, to_data_move_func, to_data_pick_func, to_view2screen, and to_vslew by validating clip boundaries and clamping non-positive width/height before computing scale factors and aspect ratios; prevented negative array indexing in to_make, to_mirror, to_bot_edge_split, and to_bot_face_split by enforcing argument count bounds; preserved ged_exec command output in to_bot_edge_split and to_bot_face_split before invoking redraw; replaced unchecked sprintf with snprintf in to_vmake; added NULL pointer guards across all commands validating gedp, gdvp, dmp, dbip, current_top, to_gedp, and to_interp; and modernized all (~60) bu_vls_addr calls to bu_vls_cstr. |
| `SEC-0326` | **Sev 2** | Division by Zero, Premature Dereference / NULL Pointer Crashes, Integer Overflow on Dimensions & Buffers, Out-of-Bounds Reads, and Unhandled Floating-Point NaNs | `src/libicv (Batch 84: 11 files)` | `FIXED` | In BRL-CAD libicv Batch 84 (asciiart.cpp, bw.c, color_space.c, crop.c, dpix.c, encoding.c, icv_private.h, operations.c, pix.c, ppm.c, stat.c, 2,400 lines): in stat.c, fixed critical premature NULL dereference in icv_hist where img->width and img->data were accessed prior to the ICV_IMAGE_VAL_PTR(img) check (CWE-476); eliminated multiple division-by-zero vulnerabilities in icv_mean, icv_var, and icv_skew when image width/height are zero (CWE-369); guarded against NULL bins, zero n_bins, and zero channels across all statistical routines; prevented out-of-bounds reads and NaN propagation in icv_max, icv_min, and icv_sum; in operations.c, fixed premature NULL dereference in icv_add_val by checking ICV_IMAGE_VAL_INT before accessing img->data; prevented division-by-zero crashes in icv_divide_val and icv_divide; fixed multi-channel desynchronization / out-of-bounds corruption in icv_saturate by advancing by img->channels instead of hardcoded 3; guarded img dimensions and scale factors against division by zero in icv_fit; in crop.c, fixed division-by-zero crash in icv_crop when img->channels is zero; added integer overflow checks on row byte calculations in icv_crop_rect and icv_crop (CWE-190); in color_space.c, guarded against out-of-bounds reads in icv_rgb2gray when channels < 3 (CWE-125); added integer overflow protection on dimensions and buffer allocations in icv_gray2rgb and icv_rgb2gray; in encoding.c, guarded against NULL data and integer overflows in icv_uchar2double and icv_data2uchar, and prevented division-by-zero and domain errors on negative or zero gamma; in dpix.c, safely handled NaNs/Infs during normalization to prevent divide-by-zero and infinite loops, replaced raw POSIX read/write with stdio fread/fwrite to eliminate short-read and buffering bugs, and added integer overflow validation on sample counts; in pix.c and bw.c, guarded against NULL data conversion pointers, checked dimensions against size_t overflow, eliminated truncation from int casts, and checked realloc limits on stream reads; in ppm.c, clamped RGB float values before lrint to avoid undefined integer conversions, replaced sprintf with snprintf for PPM headers (CWE-120), guarded against numeric overflow in parse_ppm_int, and validated buffer limits in ppm_read_mem; in asciiart.cpp, validated image pointer, data, channels, dimensions, and brightness multiplier; and in icv_private.h, properly positioned include guards. |
| `SEC-0327` | **Sev 2** | Division by Zero, Resource & Memory Leaks, NULL Pointer Dereference, Setjmp/Longjmp Undefined Behavior, Integer Overflow on Dimensions & Buffers, and Out-of-Bounds Access | `src/libicv (Batch 85: 6 files)` | `FIXED` | In BRL-CAD libicv Batch 85 (fileformat.c, filter.c, jpeg.c, pixcii.hpp, rot.c, size.c, 2,925 lines): in fileformat.c, fixed memory leak of ofilename on validation failure and fopen error paths in icv_write (CWE-401); prevented closing stdin on unsupported format; guarded against NULL bif->data, 0 width/height/channels, and integer overflows in icv_write, icv_write_mem, icv_writeline, and icv_writepixel; added NULL data check in icv_zero and invalidated magic in icv_destroy to prevent use-after-free; in jpeg.c, declared setjmp-lived pointers volatile to eliminate undefined behavior across longjmp; checked icv_data2uchar return values against NULL before scanline processing; eliminated memory leak of libjpeg buffer mem_buf on write failure; guarded dimensions against 0/invalid sizes and checked double-converted buffer allocations in jpeg_read and jpeg_read_mem; in rot.c, guarded argc/argv before calling bu_setprogname; validated pixel size, square size, and width/height options with strtol; set stdout to binary mode for piping binary image streams on Windows; added integer overflow checks on scanline bytes and buffer allocations in arbrot and icv_rot; hardened arbrot coordinates to size_t; supported negative rotation angles via !ZERO(angle); in size.c, guarded icv_image_size against NULL widthp/heightp and zero unit conversions; guarded shrink_image and under_sample against NULL image data, 0 channels, and integer overflows on realloc; removed truncating int casts on dimensions; prevented division by zero in resize_output_valid; in filter.c, validated kernel and offset pointers in get_kernel and get_kernel3; guarded icv_filter, icv_filter3, and icv_fade against NULL data, 0 channels/dimensions, NaN fraction multipliers, and integer overflows; and in pixcii.hpp, guarded against empty ascii character maps, handled NaN brightness boosts, converted signed int pixel indexing to size_t with overflow guards, and clamped double pixel color values safely. |
| `SEC-0328` | **Sev 2** | Division by Zero, Setjmp/Longjmp Undefined Behavior, Resource & Memory Leaks, Buffer Bounds & Out-of-Bounds Reads, Integer Overflow on Dimensions & Buffers, and Undefined Float-to-Int Conversions | `src/libicv (Batch 86: 5 files)` | `FIXED` | In BRL-CAD libicv Batch 86 (PImgHash.cpp, PImgHash.h, diff.cpp, diff_approx.cpp, png.cpp, 2,233 lines): in png.cpp, validated bif pointer, bif->data, dimensions, and channels in png_write and png_write_mem; declared setjmp-spanning local pointers volatile to prevent undefined behavior across longjmp (CWE-398); eliminated memory leak of converted pixel buffer data on write errors and used icv_destroy in setjmp handlers to prevent leaks of bif->render_info (CWE-401); prevented integer overflow in user_read_data bounds calculation (CWE-190); validated rowbytes against width * 3 in png_read to prevent heap out-of-bounds writes (CWE-122); validated rowbytes and buffer allocations in png_read and png_read_mem; in diff.cpp, guarded write_nirt_shots_for_ri against division by zero on aspect, width, height, and viewsize (CWE-369); guarded icv_diff_nirt_shots against NULL data, mismatched channel counts (< 3), and buffer allocation overflow; prevented heap out-of-bounds reads in icv_diff by indexing per-image channel counts instead of hardcoded 3 and guarded against signed integer overflow on off_by_many; validated 3-channel input, integer overflow on dimensions, and clean buffer freeing in icv_diffimg; in diff_approx.cpp, made load_icv static, guarded against NULL data, unsigned underflow when rows == 0, and integer overflow; validated image pointers and dimensions in pdiff_dct; guarded ssim_calc against NULL data, zero dimensions/channels, and sanitized non-finite NaN/Inf pixel values; in PImgHash.cpp and PImgHash.h, clamped float pixel values to [0.0, 1.0] with NaN check in convert_pix to prevent undefined float-to-int cast conversions (CWE-190/CWE-681); guarded DCTHasher::apply against zero dimensions; prevented out-of-bounds vector writes in tile_size when b == 0 or j >= b; guarded Preprocess::start and Preprocess::stop against division by zero and out-of-bounds histogram access; prevented NULL pointer dereferences and integer overflows in Image class; and guarded resize_row, resize, and add_row against division by zero on tile size. |
| `SEC-0329` | **Sev 2** | Integer Overflow on Dimensions & Buffers, Unsigned Underflow, Heap Buffer Overflows & Overreads, CPU Exhaustion DoS, Undefined Float Conversions, and NULL Pointer Dereferences | `src/libicv (Batch 87: anim.cpp, apngmini.hpp, rle.cpp, rle.hpp)` | `FIXED` | In BRL-CAD libicv Batch 87 (anim.cpp, apngmini.hpp, rle.cpp, rle.hpp, 3,778 lines): in anim.cpp, validated bif pointer, bif->data, dimensions, and channels in icv_to_apng preventing heap out-of-bounds reads on unexpected channel layouts (CWE-125); clamped float pixel values in float_to_u8 with std::isfinite check to prevent undefined float-to-uint8 cast conversions (CWE-190/CWE-681); guarded read_mjpeg_avi against chunk size underflow and unbounded memory allocation (CWE-191/CWE-400); guarded write_mjpeg_avi against 32-bit integer arithmetic overflows on data rate, frame bytes, and index blocks; validated image pointers and non-empty dimensions across icv_anim_write, icv_anim_add_frame, icv_anim_insert_frame, icv_anim_replace_frame, and icv_anim_get_frame; in apngmini.hpp, enforced maximum pixel limits, non-zero dimensions, and rowbytes buffer bounds in LibpngBackend decode/encode routines; guarded write_chunk against size_t overflow; ensured valid pixel bounds and buffer sizes before cropping and over-compositing; eliminated unsigned underflow and heap buffer corruption during background disposal in Animation::compose when frame.x_offset >= canvas_width (CWE-191/CWE-122); guarded chunk peeking against integer overflow and enforced minimum 4-byte length on fdAT chunks; capped maximum file read size to 512MB in read_file; in rle.cpp, sanitized double-to-uint8 conversions in dbl_to_u8 against non-finite NaN/Inf values; validated image data and dimensions in rle_write and rle_write_mem; guarded memory stream buffer allocation; in rle.hpp, implemented a per-row opcode counter in Decoder::read to prevent CPU exhaustion DoS attacks (CWE-400); clamped scanline and pixel skips to image boundaries to prevent unsigned integer wrap-around and out-of-bounds buffer writes (CWE-122/CWE-190); validated image buffer capacity before colormap transformations; ensured non-null buffer and positive dimensions in write_rgb; and prevented integer overflow in MemReadStream::tell. |
| `SEC-0330` | **Sev 2** | Memory Management Mismatch, Unchecked Vector & Buffer Bounds, Temporary File Leaks, Unbounded Allocation & Integer Overflows, Division by Zero, and NULL Pointer Dereferences | `src/libicv (Batch 88: tests/apngmini.cpp, tests/demo.c, tests/fileformat.c, tests/icv_diff_test.c, tests/icv_png_json_test.cpp, tests/pimghash.cpp, tests/rle.cpp, tests/robustness.c)` | `FIXED` | In BRL-CAD libicv Batch 88 (tests/apngmini.cpp, tests/demo.c, tests/fileformat.c, tests/icv_diff_test.c, tests/icv_png_json_test.cpp, tests/pimghash.cpp, tests/rle.cpp, tests/robustness.c, 4,882 lines, completing src/libicv to 100%): in rle.cpp, resolved allocator mismatch (CWE-762) by changing create_test_image from libc calloc to bu_calloc to match bu_free in free_test_image; guarded against arithmetic overflow in image data size calculation; added null data checks in pixels_match; ensured temporary test files in rle_roundtrip, test_write_invalid_channels, and test_write_oversized_dimensions are deleted on error and completion; and exercised null file stream handling in test_invalid_file; in apngmini.cpp, validated frame dimensions in make_frame to prevent integer overflow and excessive allocation; verified vector bounds before indexing composed frame pixels to prevent out-of-bounds reads (CWE-125); and ensured roundtrip temporary files are deleted via RAII cleanup; in demo.c, validated image creation and buffer allocations in demo_rgb and prevented division by zero when dimensions sum to zero; guarded against dimension overflow and null pointers in clone_image; added null checks across demo_memory_io, demo_file_io, demo_crop_filter_ascii, and demo_diffs; and ensured temporary animation test files are cleaned up unconditionally; in fileformat.c, validated image data allocation in make_pixel and guarded path parameter in write_auto_pix; in icv_diff_test.c, validated dimensions and arithmetic overflow in make_solid; added null data checks in test_icv_diff_counts and test_icv_diffimg_colors; and validated render_info pointers before dereferencing in test_png_metadata_roundtrip, test_diff_render_info, and test_nirt_shots; in icv_png_json_test.cpp, validated dimensions and data pointers in make_solid; capped maximum file read size to 100MB in png_read_text_chunk; guarded chunk parsing against 32-bit integer overflow; and verified render_info allocations before dereferencing; in pimghash.cpp, sanitized floating-point comparisons with std::isfinite in nearly_equal; and checked vector size before indexing hash bytes in test_hashing; in robustness.c, validated dimensions and memory allocations across all make_* helper functions; prevented division by zero in make_unit_rgb; checked statistics pointers (minv, maxv, sumv, meanv, bins, mode, median, var, skew) for null before access in test_crop_filters_and_stats; and guarded metadata and frame allocations in test_ascii_render_info_and_diff and test_animation_frame_management; and across all test harnesses, safely validated argc > 0 && argv && argv[0] before calling bu_setprogname. |
| `SEC-0331` | **Sev 2** | Buffer Overlapping Undefined Behavior, Stack & Heap Buffer Truncation / Overflow, Division by Zero, Unsigned Integer Underflow, Memory Leaks, Dangling / Unchecked Pointers, and NULL Pointer Dereferences | `src/libnmg (Batch 89: bool.c, ck.c)` | `FIXED` | In BRL-CAD libnmg Batch 89 (bool.c, ck.c, 2,801 lines): in ck.c, resolved critical undefined behavior (UB) and buffer corruption across all topological consistency check routines (nmg_ck_e, nmg_ck_vu, nmg_ck_eu, nmg_ck_lg, nmg_ck_l, nmg_ck_lu, nmg_ck_fg, nmg_ck_f, nmg_ck_fu) by replacing unsafe fixed-length heap allocations and overlapping snprintf calls (where the destination buffer was also passed as the %s source argument) with dynamically sized struct bu_vls formatting; fixed CWE-369 division-by-zero vulnerability in nmg_ck_eg_verts by guarding edge direction magnitude against zero before calling VUNITIZE; eliminated NULL pointer dereferences when logging or checking without parent strings by guarding string pointers; in nmg_ck_lueu, fixed backward/forward edge logging mismatch bug, corrected routine name typo in logs, and guarded circular list navigation against empty list heads; hardened all 17 nmg_v* validator routines (nmg_vvg, nmg_vvertex, nmg_vvua, nmg_vvu, nmg_veg, nmg_vedge, nmg_veu, nmg_vlg, nmg_vloop, nmg_vlu, nmg_vfg, nmg_vface, nmg_vfu, nmg_vsshell, nmg_vshell, nmg_vregion, nmg_vmodel) with comprehensive NULL checks, magic identification guards, and coordinate validation; in nmg_eu_2s_orient_bad, guarded radial and mate pointers during circular traversal; in nmg_ck_closed_surf and nmg_ck_closed_region, checked pointer validity before recursive verification; in nmg_ck_v_in_2fus and nmg_ck_vs_in_region, ensured vertex geometry and model pointers are valid and sanitized visited array allocation against negative or zero maxindex; in bool.c, guarded nmg_plot_open_edges against NULL magic, checked vertex coordinate pointers, and ensured plot_file_name bu_vls is unconditionally freed at exit; validated model and shell pointers in nmg_has_dangling_faces; eliminated unsigned integer underflow vulnerability in nmg_kill_anti_loops during loop deletion; safely bounded buffer formatting in nmg_show_each_loop; guarded edgeuse mate pointers in nmg_classify_shared_edges_verts; removed obsolete #if 0 dead code block; ensured bounding boxes exist before disjoint tests in nmg_bool; and guarded model maxindex against non-positive sizes before calloc/memcpy in boolean evaluation. |
| `SEC-0332` | **Sev 2** | Off-by-One Heap Buffer Overflows, Union Type Confusion, Division by Zero, Broken Radial Circular Loops, Dead Code Blocks, and NULL Pointer Dereferences | `src/libnmg (Batch 90: class.c, copy.c)` | `FIXED` | In BRL-CAD libnmg Batch 90 (class.c, copy.c, 3,392 lines): in copy.c, resolved critical off-by-one heap buffer overflow in nmg_clone_model by allocating maxelem = original->maxindex > 0 ? (size_t)original->maxindex + 1 : 1 instead of original->maxindex, preventing out-of-bounds writes and corruptions when elements with index == maxindex are cloned; introduced safe index-checked structArray accessor helpers get_struct and set_struct validating index >= 0 && (size_t)index < maxelem; fixed union type confusion in nmg_construct_face where case NMG_FACE_G_SNURB_MAGIC accessed original->g.plane_p->index instead of original->g.snurb_p->index; hardened all 20 structure constructors (nmg_construct_region_a, nmg_construct_region, nmg_construct_face_g_plane, nmg_construct_face_g_snurb, nmg_construct_face, nmg_construct_vertex_g, nmg_construct_vertex, nmg_construct_vertexuse_a_plane, nmg_construct_vertexuse_a_cnurb, nmg_construct_vertexuse, nmg_construct_edge, nmg_construct_edge_g_lseg, nmg_construct_edge_g_cnurb, nmg_construct_edgeuse, nmg_construct_loop_a, nmg_construct_loop, nmg_construct_loopuse, nmg_construct_faceuse, nmg_construct_shell_a, nmg_construct_shell) with input NULL checks, safe structArray index bounds validation, and non-null child insertion guards; validated knot vector sizes (u.k_size, v.k_size, k_size) and ctl_points array allocations before copying in SNURB and CNURB constructors; removed dead unused tolerance variable in nmg_clone_model; in class.c, fixed CWE-369 division-by-zero vulnerability in nmg_class_pnt_e by checking MAGSQ(ptvec) < SMALL_FASTF before calling VUNITIZE; eliminated off-by-one heap underallocations in nmg_class_pnt_e debug plot bits buffer, nmg_class_pnt_s faces_seen array, and class_lu_vs_s b buffer by allocating (size_t)maxindex + 1; replaced unsafe sprintf calls with snprintf across debug plot generators; deleted two large obsolete #if 0 dead code blocks (~200 lines: nmg_class_lu_fu and nmg_get_interior_pnt); guarded against NULL shell attributes (s->sa_p) before bounding box dereferences in nmg_class_pnt_s, class_eu_vs_s, and nmg_classify_s_vs_s by ensuring attributes via nmg_shell_a; hardened radial and mate pointer cycles against NULL dereference and infinite loops in class_eu_vs_s, class_shared_lu, and class_lu_vs_s; and prevented crashes and type confusion on empty or vertex loops in class_shared_lu and nmg_classify_s_vs_s by validating list emptiness, checking child magic, and ensuring vertex geometry pointers are non-null. |
| `SEC-0333` | **Sev 2** | Heap Buffer Overflows / OOB Writes, Memory Leaks, Copy-Paste Edge Intersection Defects, Denial of Service / Aborts, and NULL Pointer Dereferences | `src/libnmg (Batch 91: eval.c, extrude.c)` | `FIXED` | In BRL-CAD libnmg Batch 91 (eval.c, extrude.c, 2,024 lines): in extrude.c, resolved critical Cat 1 heap buffer overflow / OOB write vulnerabilities (CWE-122 / CWE-787) in nmg_hollow_shell and nmg_extrude_shell by allocating maxelem = (m->maxindex > 0) ? (size_t)m->maxindex + 1 : 1 instead of m->maxindex, preventing memory corruption when elements with index == maxindex are processed by NMG_INDEX_TEST_AND_SET; fixed critical copy-paste bug in nmg_fix_overlapping_loops where edge splitting on intersection endpoints incorrectly referenced eu2 instead of eu1 on dist[0] == 1.0, and nmg_esplit was erroneously confined to the interior-only else branch, leaving crossing edges completely unsplit when touching existing vertex endpoints; fixed multiple persistent memory leaks: loop_tab allocations in nmg_fix_overlapping_loops when tables were empty, outfaces in nmg_extrude_face on early error returns, and the verts table in nmg_extrude_shell when vertex recalculation failed before out: (CWE-401); replaced fatal bu_bomb abort in nmg_extrude_face on parallel extrusion with graceful error return (-1) and moved angle calculation before nmg_dup_face to prevent orphaned/leaked duplicated geometry; added loop bounds and magic number validation in nmg_start_new_loop to guard against infinite loops and type confusion; hardened verts_in_nmg_loop, verts_in_nmg_face, nmg_translate_face, nmg_find_vertex_in_lu, nmg_break_crossed_loops, and nmg_extrude_cleanup with comprehensive NULL checks, empty loop guards, and coordinate validation; in eval.c, hardened nmg_eval_action with classification table bounds checking (bs_maxindex) to prevent negative array indexing or heap out-of-bounds reads (CWE-125); added NULL guards, parent magic verification, and planar face geometry checks in nmg_ck_lu_orientation to avoid illegal dereferences on non-faceuse parents or SNURB faces; hardened nmg_eval_shell against crashing on empty loops or malformed wire edgeuse parents in BACTION_KILL; replaced unsafe sprintf with snprintf in debug plot file naming; and replaced fatal bu_bomb on plot file write failure with a non-fatal bu_log warning. |
| `SEC-0334` | **Sev 2** | Stack & Heap Uninitialized Memory / Sizeof Pointer, Persistent Memory Leaks, Division by Zero, Unsigned Underflow, Dead Code Elimination, and NULL Pointer Dereferences | `src/libnmg (Batch 92: fcut.c)` | `FIXED` | In BRL-CAD libnmg Batch 92 (fcut.c, 3,809 lines): in nmg_face_rs_init, resolved critical Cat 1 sizeof-pointer memory initialization defect (CWE-467) where memset((char *)rs, 0, sizeof(rs)) only zeroed 8 bytes (pointer size) leaving the remaining 90% of the nmg_ray_state structure filled with uninitialized stack memory; resolved multiple persistent memory leaks (CWE-401) in find_loop_to_cut and nmg_fcut_face where dynamically allocated struct loop_cuts objects in the cuts table were removed via bu_ptbl_rm or left in cuts when freeing the table without ever calling bu_free; fixed CWE-369 division-by-zero vulnerabilities across VUNITIZE calls on rs->left in nmg_face_rs_init, x_dir and y_dir in find_loop_to_cut, and x_dir and y_dir in nmg_eu_angle by guarding vector magnitude against zero before normalization; fixed CWE-191 unsigned integer underflow and infinite loop vulnerability in ptbl_vsort bubble sort loop bounds by using safe i + 1 < b->end comparison; eliminated type confusion crashes on lone vertex loops in find_best_vu by verifying parent magic (*vu->up.magic_p == NMG_EDGEUSE_MAGIC) before treating parents as edgeuses; eliminated out-of-bounds pointer reads and potential null dereferences in nmg_fcut_face traversal loops (prior_start, prior_end, next_end) by enforcing array bounds against rs->nvu; guarded ptbl_vsort against division by zero on dist_tol <= 0; added retry iteration limits and safe return paths in nmg_ck_vu_ptbl and nmg_face_cutjoin to prevent infinite loops; restored active exported implementations of nmg_sanitize_fu and nmg_wedge_class from dead code blocks; replaced fatal bu_bomb aborts across active routines with error logging and graceful failure returns; and eliminated ~2,500 lines of obsolete #if 0 dead code blocks from 1993/2017. |
| `SEC-0335` | **Sev 2** | Persistent Memory Leaks, Division by Zero, Control Point Misalignment, Infinite Loops, Denial of Service / Aborts, and NULL Pointer Dereferences | `src/libnmg (Batch 93: fuse.c)` | `FIXED` | In BRL-CAD libnmg Batch 93 (fuse.c, 3,468 lines): resolved multiple persistent memory leaks (CWE-401) by freeing dynamic sort_idx_xyp allocation in nmg_edge_g_fuse which was previously never deallocated, freeing etab table on zero-count exit in nmg_edge_g_fuse, and freeing tmp table on empty-length exits in nmg_vertex_fuse and nmg_edge_fuse; fixed control points stride misalignment and buffer bounds defects in nmg_cnurb_is_linear (CWE-125 / CWE-129) where ctl_points was indexed by i instead of i * coords and compared using 3D VEQUAL instead of dimension-aware coords comparisons with EQUAL macro, as well as fixing the loop upper bound to cnrb->c_size - 1; fixed multiple CWE-369 division-by-zero vulnerabilities: guarded rise-over-run slopes (dx and dy) in nmg_edge_g_fuse across XY, XZ, and YZ planes, guarded srf->s_size[0] * srf->s_size[1] <= 0 and plane normal magnitude MAGSQ(pl) <= SMALL_FASTF in nmg_snurb_is_planar, and guarded rational weights (xyz1[coords-1] and uvw[coords-1]) in nmg_eval_linear_trim_curve and nmg_eval_trim_curve; fixed potential infinite loop hangs (CWE-835) in nmg_radial_implement_decisions and nmg_do_radial_join by adding pass progress tracking (progress++) to prevent infinite looping when skipped elements make no forward progress; eliminated 43 fatal bu_bomb aborts (CWE-400 / DoS) across topological fusing, crack classification, and radial edge joining (nmg_region_v_unique, nmg_vertex_fuse, nmg_snurb_is_planar, nmg_split_trim, nmg_cnurb_lseg_coincident, nmg_cnurb_is_on_crv, nmg_edge_fuse, nmg_ck_fu_verts, nmg_break_all_es_on_v, nmg_radial_verify_pointers, nmg_radial_verify_monotone, nmg_radial_build_list, nmg_is_crack_outie, nmg_find_radial_eu, nmg_radial_mark_cracks, nmg_radial_find_an_original, nmg_radial_mark_flips, nmg_radial_join_eu_NEW), replacing them with informative error/debug logging and graceful non-fatal fallback returns; and hardened against NULL pointer dereferences and out-of-bounds reads (CWE-476 / CWE-125) in nmg_edge_fuse, nmg_edge_g_fuse, nmg_break_all_es_on_v, nmg_break_e_on_v, and radial utilities with comprehensive parameter validation and geometry checks. |
-158
View File
@@ -1,158 +0,0 @@
#!/usr/bin/env python3
import os
import sys
import json
import time
import argparse
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
AUDIT_DIR = os.path.join(REPO_ROOT, "audit")
FILES_LEDGER = os.path.join(AUDIT_DIR, "files_ledger.json")
ISSUES_LEDGER = os.path.join(AUDIT_DIR, "issues_ledger.json")
def load_files():
if not os.path.exists(FILES_LEDGER):
return {"files": []}
with open(FILES_LEDGER, "r", encoding="utf-8") as f:
return json.load(f)
def save_files(data):
with open(FILES_LEDGER, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
def load_issues():
if not os.path.exists(ISSUES_LEDGER):
return {"issues": []}
with open(ISSUES_LEDGER, "r", encoding="utf-8") as f:
return json.load(f)
def save_issues(data):
with open(ISSUES_LEDGER, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
def mark_reviewed(file_paths):
fdata = load_files()
path_map = {f["path"]: f for f in fdata.get("files", [])}
ts = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
updated = 0
for p in file_paths:
norm_p = os.path.relpath(os.path.join(REPO_ROOT, p), REPO_ROOT)
if norm_p in path_map:
path_map[norm_p]["status"] = "REVIEWED"
path_map[norm_p]["reviewed_at"] = ts
updated += 1
else:
print(f"Warning: file not found in ledger: {norm_p}")
save_files(fdata)
print(f"Marked {updated} file(s) as REVIEWED.")
def log_issue(file_path, line_range, severity, category, description):
fdata = load_files()
idata = load_issues()
issues = idata.get("issues", [])
next_id_num = len(issues) + 1
issue_id = f"SEC-{next_id_num:04d}"
norm_p = os.path.relpath(os.path.join(REPO_ROOT, file_path), REPO_ROOT)
new_issue = {
"id": issue_id,
"file": norm_p,
"lines": line_range,
"severity": int(severity),
"category": category,
"description": description,
"verification_status": "PENDING",
"verification_test": None,
"test_result": None,
"fix_status": "UNFIXED",
"fix_description": None,
"commit_hash": None,
"commit_message": None,
"created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
}
issues.append(new_issue)
idata["issues"] = issues
save_issues(idata)
# Link to file in files_ledger
path_map = {f["path"]: f for f in fdata.get("files", [])}
if norm_p in path_map:
path_map[norm_p]["issues_count"] = path_map[norm_p].get("issues_count", 0) + 1
if "issue_ids" not in path_map[norm_p]:
path_map[norm_p]["issue_ids"] = []
path_map[norm_p]["issue_ids"].append(issue_id)
save_files(fdata)
print(f"Logged issue {issue_id}: [{category}] Severity {severity} in {norm_p}:{line_range}")
return issue_id
def verify_issue(issue_id, status, test_desc, test_result):
idata = load_issues()
for issue in idata.get("issues", []):
if issue["id"] == issue_id:
issue["verification_status"] = status
issue["verification_test"] = test_desc
issue["test_result"] = test_result
issue["verified_at"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
save_issues(idata)
print(f"Updated {issue_id} verification status: {status}")
return
print(f"Error: Issue {issue_id} not found.")
def record_fix(issue_id, fix_desc, commit_msg, commit_hash=None):
idata = load_issues()
for issue in idata.get("issues", []):
if issue["id"] == issue_id:
issue["fix_status"] = "FIXED" if commit_hash else "PENDING_COMMIT"
issue["fix_description"] = fix_desc
issue["commit_message"] = commit_msg
issue["commit_hash"] = commit_hash
issue["fixed_at"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
save_issues(idata)
print(f"Updated {issue_id} fix status: {issue['fix_status']}")
return
print(f"Error: Issue {issue_id} not found.")
def main():
parser = argparse.ArgumentParser(description="Audit Ledger Management Tool")
subparsers = parser.add_subparsers(dest="action", required=True)
# mark-reviewed
rev_parser = subparsers.add_parser("mark-reviewed")
rev_parser.add_argument("files", nargs="+", help="Files to mark as reviewed")
# log-issue
log_parser = subparsers.add_parser("log-issue")
log_parser.add_argument("--file", required=True, help="File path")
log_parser.add_argument("--lines", required=True, help="Line range (e.g. 88-94)")
log_parser.add_argument("--severity", required=True, type=int, choices=[1, 2, 3], help="Severity 1-3")
log_parser.add_argument("--category", required=True, help="Vulnerability category")
log_parser.add_argument("--description", required=True, help="1-sentence description")
# verify-issue
ver_parser = subparsers.add_parser("verify-issue")
ver_parser.add_argument("--id", required=True, help="Issue ID (e.g. SEC-0001)")
ver_parser.add_argument("--status", required=True, choices=["CONFIRMED", "DISPROVEN", "PENDING"], help="Status")
ver_parser.add_argument("--test-desc", required=True, help="Test description")
ver_parser.add_argument("--test-result", required=True, help="Test outcome summary")
# record-fix
fix_parser = subparsers.add_parser("record-fix")
fix_parser.add_argument("--id", required=True, help="Issue ID (e.g. SEC-0001)")
fix_parser.add_argument("--fix-desc", required=True, help="Description of the fix")
fix_parser.add_argument("--commit-msg", required=True, help="Proposed lowercase commit message")
fix_parser.add_argument("--commit-hash", default=None, help="Commit hash if committed")
args = parser.parse_args()
if args.action == "mark-reviewed":
mark_reviewed(args.files)
elif args.action == "log-issue":
log_issue(args.file, args.lines, args.severity, args.category, args.description)
elif args.action == "verify-issue":
verify_issue(args.id, args.status, args.test_desc, args.test_result)
elif args.action == "record-fix":
record_fix(args.id, args.fix_desc, args.commit_msg, args.commit_hash)
if __name__ == "__main__":
main()
-148
View File
@@ -1,148 +0,0 @@
#!/usr/bin/env python3
import os
import json
import time
from collections import defaultdict
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
AUDIT_DIR = os.path.join(REPO_ROOT, "audit")
FILES_LEDGER = os.path.join(AUDIT_DIR, "files_ledger.json")
ISSUES_LEDGER = os.path.join(AUDIT_DIR, "issues_ledger.json")
DASHBOARD_MD = os.path.join(AUDIT_DIR, "DASHBOARD.md")
AUDIT_LEDGER_MD = os.path.join(AUDIT_DIR, "AUDIT_LEDGER.md")
def load_json(filepath, default):
if not os.path.exists(filepath):
return default
with open(filepath, "r", encoding="utf-8") as f:
return json.load(f)
def generate_dashboard():
fdata = load_json(FILES_LEDGER, {"files": []})
idata = load_json(ISSUES_LEDGER, {"issues": []})
files = fdata.get("files", [])
issues = idata.get("issues", [])
total_files = len(files)
reviewed_files = sum(1 for f in files if f.get("status", "").startswith("REVIEWED"))
pending_files = total_files - reviewed_files
pct_complete = (reviewed_files / total_files * 100) if total_files > 0 else 0.0
# Issues breakdown
sev_counts = {1: 0, 2: 0, 3: 0}
status_counts = {"PENDING": 0, "CONFIRMED": 0, "DISPROVEN": 0, "FIXED": 0}
cat_counts = defaultdict(int)
for iss in issues:
sev = iss.get("severity", 1)
sev_counts[sev] = sev_counts.get(sev, 0) + 1
vstat = iss.get("verification_status", "PENDING")
fstat = iss.get("fix_status", "UNFIXED")
if fstat == "FIXED":
status_counts["FIXED"] += 1
else:
status_counts[vstat] = status_counts.get(vstat, 0) + 1
cat = iss.get("category", "Unknown")
cat_counts[cat] += 1
# Subsystem breakdown
subsys_stats = defaultdict(lambda: {"total": 0, "reviewed": 0, "issues": 0})
for f in files:
ss = f.get("subsystem", "other")
subsys_stats[ss]["total"] += 1
if f.get("status", "").startswith("REVIEWED"):
subsys_stats[ss]["reviewed"] += 1
subsys_stats[ss]["issues"] += f.get("issues_count", 0)
# Render Markdown Dashboard
now_str = time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime())
md_lines = [
"# BRL-CAD RMF/STIG Cat 1 Security Audit Dashboard",
f"**Last Updated:** {now_str}",
"",
"## Overall Progress",
f"- **Total C/C++ Files:** {total_files}",
f"- **Files Reviewed:** {reviewed_files} ({pct_complete:.1f}%)",
f"- **Files Pending Review:** {pending_files}",
f"- **Total Issues Identified:** {len(issues)}",
"",
"### Issues by Severity Potential",
"| Severity Level | Count | Description |",
"|:---:|:---:|:---|",
f"| **3 (High)** | {sev_counts[3]} | Likely exploit or crash potential; widespread/library exposure |",
f"| **2 (Medium)** | {sev_counts[2]} | Possible exploit or crash under specific circumstances |",
f"| **1 (Low)** | {sev_counts[1]} | Localized / low-impact vulnerability |",
"",
"### Issues by Verification Status",
f"- **Confirmed:** {status_counts.get('CONFIRMED', 0)}",
f"- **Fixed (Committed):** {status_counts.get('FIXED', 0)}",
f"- **Pending Verification:** {status_counts.get('PENDING', 0)}",
f"- **Disproven:** {status_counts.get('DISPROVEN', 0)}",
"",
"## Subsystem Review Progress",
"| Subsystem | Total Files | Reviewed | Progress | Issues Found |",
"|:---|:---:|:---:|:---:|:---:|"
]
for ss in sorted(subsys_stats.keys()):
stats = subsys_stats[ss]
pct = (stats["reviewed"] / stats["total"] * 100) if stats["total"] > 0 else 0
md_lines.append(f"| `{ss}` | {stats['total']} | {stats['reviewed']} | {pct:.1f}% | {stats['issues']} |")
if issues:
md_lines.extend([
"",
"## Identified Issues Summary",
"| ID | Severity | Category | File & Location | Verification | Nature of Issue |",
"|:---|:---:|:---|:---|:---:|:---|"
])
for iss in issues:
v_badge = iss.get("verification_status", "PENDING")
if iss.get("fix_status") == "FIXED":
v_badge = "FIXED"
md_lines.append(
f"| `{iss['id']}` | **Sev {iss['severity']}** | {iss['category']} | `{iss['file']}:{iss['lines']}` | `{v_badge}` | {iss['description']} |"
)
md_content = "\n".join(md_lines) + "\n"
with open(DASHBOARD_MD, "w", encoding="utf-8") as f:
f.write(md_content)
# Render Markdown Ledger
ledger_lines = [
"# BRL-CAD RMF/STIG Cat 1 Vulnerability Tracking Ledger",
f"**Last Synchronized:** {now_str}",
"",
"| Issue ID | File | Lines | Cat 1 Type | Sev | Verification | Fix Status | 1-Sentence Nature of Issue |",
"|:---|:---|:---:|:---|:---:|:---:|:---:|:---|"
]
for iss in issues:
v_badge = iss.get("verification_status", "PENDING")
fix_badge = iss.get("fix_status", "UNFIXED")
ledger_lines.append(
f"| `{iss['id']}` | `{iss['file']}` | `{iss['lines']}` | {iss['category']} | {iss['severity']} | `{v_badge}` | `{fix_badge}` | {iss['description']} |"
)
with open(AUDIT_LEDGER_MD, "w", encoding="utf-8") as f:
f.write("\n".join(ledger_lines) + "\n")
# Terminal Output
print("=" * 68)
print(" BRL-CAD RMF/STIG Cat 1 Security Audit Dashboard")
print("=" * 68)
print(f" Total C/C++ Files: {total_files}")
print(f" Files Reviewed: {reviewed_files} / {total_files} ({pct_complete:.1f}%)")
print(f" Files Pending: {pending_files}")
print(f" Total Issues: {len(issues)}")
print(f" Severity Breakdown: High (3): {sev_counts[3]} | Med (2): {sev_counts[2]} | Low (1): {sev_counts[1]}")
print(f" Verification Status: Confirmed: {status_counts.get('CONFIRMED', 0)} | Fixed: {status_counts.get('FIXED', 0)} | Pending: {status_counts.get('PENDING', 0)} | Disproven: {status_counts.get('DISPROVEN', 0)}")
print("=" * 68)
print(f" Updated dashboard: {DASHBOARD_MD}")
print(f" Updated ledger: {AUDIT_LEDGER_MD}")
print("=" * 68)
if __name__ == "__main__":
generate_dashboard()
File diff suppressed because it is too large Load Diff
-91
View File
@@ -1,91 +0,0 @@
#!/usr/bin/env python3
import os
import json
import time
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
AUDIT_DIR = os.path.join(REPO_ROOT, "audit")
FILES_LEDGER = os.path.join(AUDIT_DIR, "files_ledger.json")
EXTENSIONS = {".c", ".cpp", ".cxx", ".cc", ".h", ".hpp", ".hxx", ".hh"}
EXCLUDE_DIRS = {".git", "build", "audit", ".github"}
def get_subsystem(rel_path):
parts = rel_path.split(os.sep)
if len(parts) > 1 and parts[0] == "src":
if parts[1] == "conv" and len(parts) > 2:
return f"src/conv/{parts[2]}"
return f"src/{parts[1]}"
elif len(parts) > 1 and parts[0] == "include":
return "include"
elif len(parts) > 1:
return parts[0]
return "root"
def count_lines(filepath):
try:
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
return sum(1 for _ in f)
except Exception:
return 0
def main():
existing_ledger = {}
if os.path.exists(FILES_LEDGER):
try:
with open(FILES_LEDGER, "r", encoding="utf-8") as f:
data = json.load(f)
for item in data.get("files", []):
existing_ledger[item["path"]] = item
except Exception as e:
print(f"Warning: could not load existing ledger: {e}")
files = []
for root, dirs, filenames in os.walk(REPO_ROOT):
dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS and not d.startswith("build")]
for fn in filenames:
ext = os.path.splitext(fn)[1].lower()
if ext in EXTENSIONS:
full_path = os.path.join(root, fn)
rel_path = os.path.relpath(full_path, REPO_ROOT)
files.append(rel_path)
files.sort()
ledger_entries = []
for idx, rel_path in enumerate(files, 1):
if rel_path in existing_ledger:
entry = existing_ledger[rel_path]
entry["id"] = idx
ledger_entries.append(entry)
else:
full_path = os.path.join(REPO_ROOT, rel_path)
lines = count_lines(full_path)
subsystem = get_subsystem(rel_path)
ledger_entries.append({
"id": idx,
"path": rel_path,
"subsystem": subsystem,
"lines": lines,
"status": "PENDING",
"reviewed_at": None,
"issues_count": 0,
"issue_ids": []
})
output_data = {
"metadata": {
"created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"total_files": len(ledger_entries),
"extensions": sorted(list(EXTENSIONS))
},
"files": ledger_entries
}
with open(FILES_LEDGER, "w", encoding="utf-8") as f:
json.dump(output_data, f, indent=2)
print(f"Successfully indexed {len(ledger_entries)} C/C++ files into {FILES_LEDGER}")
if __name__ == "__main__":
main()
File diff suppressed because it is too large Load Diff
+22 -53
View File
@@ -94,15 +94,13 @@ record(const char *fmt, ...)
bu_vls_vprintf(&str, fmt, ap);
va_end(ap);
if (!BU_STR_EMPTY(LOGFILE)) {
if (!BU_STR_EQUAL(LOGFILE, "")) {
FILE *fp = fopen(LOGFILE, "a");
if (fp) {
fprintf(fp, "%s", bu_vls_cstr(&str));
fclose(fp);
}
fprintf(fp, "%s", bu_vls_addr(&str));
fclose(fp);
}
if (bu_str_false(QUIET)) {
bu_log("%s", bu_vls_cstr(&str));
bu_log("%s", bu_vls_addr(&str));
}
bu_vls_free(&str);
@@ -286,15 +284,10 @@ main(int ac, char *av[])
void (*verbose_echo)(const char *, ...) = sink;
void (*echo)(const char *, ...) = record;
if (ac > 0 && av && av[0]) {
bu_setprogname(av[0]);
} else {
bu_setprogname("benchmark");
}
bu_setprogname(av[0]);
/* process the argument list for commands */
for (arg=1; arg<ac; arg++) {
char *eq;
if (BU_STR_EQUAL(av[arg], "clean")) {
bu_setenv("CLEAN", "1", 1);
continue;
@@ -312,7 +305,7 @@ main(int ac, char *av[])
bu_setenv("HELP", "1", 1);
continue;
}
if (bu_strncasecmp(av[arg], "instruct", 8) == 0) {
if (bu_strncasecmp(av[arg], "instruct", 8)) {
bu_setenv("INSTRUCTIONS", "1", 1);
continue;
}
@@ -331,12 +324,13 @@ main(int ac, char *av[])
bu_setenv("RUN", "1", 1);
continue;
}
eq = strchr(av[arg], '=');
if (eq) {
if (strchr(av[arg], '=')) {
/* TODO: !!! make sure this still works */
char *var = bu_strdup(av[arg]);
char *eq_in_var = var + (eq - av[arg]);
*eq_in_var = '\0';
bu_setenv(var, eq_in_var + 1, 1);
char *val = strtok(var, "=");
if (var && val) {
bu_setenv(var, val, 1);
}
bu_free(var, "strdup av[arg]");
continue;
}
@@ -349,7 +343,7 @@ main(int ac, char *av[])
* handle help before main processing
***/
if (bu_str_true(getenv("HELP"))) {
bu_log("Usage: %s [command(s)] [OPTION=value] [RT_OPTIONS]\n", bu_getprogname());
bu_log("Usage: %s [command(s)] [OPTION=value] [RT_OPTIONS]\n", av[0]);
bu_log("\n");
bu_log("Available commands:\n");
bu_log(" clean\n");
@@ -384,10 +378,7 @@ main(int ac, char *av[])
bu_log("BRL-CAD is a powerful cross-platform open source solid modeling system.\n");
bu_log("For more information about BRL-CAD, see http://brlcad.org\n");
bu_log("\n");
bu_log("Run '%s instructions' or see the manpage for additional information.\n", bu_getprogname());
bu_vls_free(&rtargs);
bu_vls_free(&vp);
bu_vls_free(&str);
bu_log("Run '%s instructions' or see the manpage for additional information.\n", av[0]);
bu_exit(1, NULL);
}
@@ -452,9 +443,6 @@ main(int ac, char *av[])
bu_log("The manual page has even more information and specific usage examples.\n");
bu_log("Run 'brlman benchmark'.\n");
bu_log("\n");
bu_vls_free(&rtargs);
bu_vls_free(&vp);
bu_vls_free(&str);
bu_exit(0, NULL);
}
@@ -478,7 +466,7 @@ main(int ac, char *av[])
sleep(5);
} else {
bu_log("Deleting most benchmark images and log files in %s\n", bu_getcwd(cwd, MAXPATHLEN));
bu_log("Running '%s clobber' will remove run logs.\n", bu_getprogname());
bu_log("Running '%s clobber' will remove run logs.\n", av[0]);
}
bu_log("\n");
@@ -558,9 +546,6 @@ main(int ac, char *av[])
} else {
bu_log("\nBenchmark clean complete.\n");
}
bu_vls_free(&rtargs);
bu_vls_free(&vp);
bu_vls_free(&str);
bu_exit(0, NULL);
}
@@ -570,19 +555,15 @@ main(int ac, char *av[])
***/
if (bu_str_false(getenv("RUN"))) {
bu_vls_free(&rtargs);
bu_vls_free(&vp);
bu_vls_free(&str);
bu_exit(1, "Type '%s help' for usage.\n", bu_getprogname());
bu_exit(1, "Type '%s help' for usage.\n", av[0]);
}
/* where to write results */
{
int fd;
const char *logfile;
bu_vls_trunc(&str, 0);
bu_vls_printf(&str, "run-%d-benchmark.log", bu_pid());
logfile = bu_vls_cstr(&str);
logfile = bu_vls_addr(&str);
bu_setenv("LOGFILE", logfile, 1);
fd = open(logfile, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR);
if (fd < 0 || !bu_file_writable(logfile)) {
@@ -592,9 +573,6 @@ main(int ac, char *av[])
/* FIXME: not valid logfile on windows, use 'nul' */
bu_setenv("LOGFILE", "/dev/null", 1);
}
if (fd >= 0) {
close(fd);
}
}
if (bu_str_true(getenv("QUIET"))) {
@@ -626,10 +604,9 @@ main(int ac, char *av[])
echo("B R L - C A D B E N C H M A R K\n");
echo("=================================\n");
echo("Running %s on %s\n", bu_getprogname(), rfc2822);
echo("Running %s on %s\n", av[0], rfc2822);
echo("Logging output to %s\n", logfile ? logfile : "disabled");
echo("%s\n\n", bu_vls_cstr(&v));
bu_vls_free(&v);
echo("%s\n\n", bu_vls_addr(&v));
}
@@ -836,7 +813,6 @@ main(int ac, char *av[])
estimate = maxtime;
echo("Estimated time is %s\n", format_elapsed(estimate));
bu_vls_free(&elapsed);
}
/************************
@@ -854,7 +830,7 @@ main(int ac, char *av[])
ret += bench("sphflake");
echo("\n... Done.\n");
echo("Total testing time elapsed: %s\n", format_elapsed(bu_gettime() - start));
echo("Total testing time elapsed: %.2lfs\n", format_elapsed(bu_gettime() - start));
if (ret != 0) {
echo("\n");
@@ -867,11 +843,8 @@ main(int ac, char *av[])
echo("please report your configuration information to benchmark@brlcad.org\n");
echo("\n");
echo("Output was saved to %s from %s\n", LOG, bu_dir(NULL, 0, BU_DIR_CURR, NULL));
echo("Run '%s clean' to remove generated pix files.\n", bu_getprogname());
echo("Run '%s clean' to remove generated pix files.\n", av[0]);
echo("Benchmark testing failed.\n");
bu_vls_free(&rtargs);
bu_vls_free(&vp);
bu_vls_free(&str);
return 2;
}
@@ -894,7 +867,7 @@ main(int ac, char *av[])
echo(" *.pix.* ... pix image files for previous frames and raytrace tests\n");
echo(" summary ... performance results summary, 2 lines per run\n");
echo("\n");
echo("Run '%s clean' to remove generated pix files.\n", bu_getprogname());
echo("Run '%s clean' to remove generated pix files.\n", av[0]);
echo("\n");
echo("Summary:\n");
@@ -927,7 +900,6 @@ main(int ac, char *av[])
echo("\n");
}
}
bu_vls_free(&performance);
}
{
@@ -966,9 +938,6 @@ main(int ac, char *av[])
echo("Output was saved to %s from %s\n", LOG, bu_dir(NULL, 0, BU_DIR_CURR, NULL));
echo("Benchmark testing complete.\n");
bu_vls_free(&vp);
bu_vls_free(&str);
return 0;
}
+2 -5
View File
@@ -70,21 +70,18 @@ clean_obstacles(const char *base_filename, int id)
if (bu_file_exists(bu_vls_cstr(&vpid), NULL)) {
bu_file_delete(bu_vls_cstr(&vp));
}
//bu_file_move(bu_vls_cstr(&vp), bu_vls_cstr(&vpid));
}
/* look for a log file */
bu_vls_trunc(&vp, 0);
bu_vls_trunc(&vpid, 0);
bu_vls_printf(&vp, "%s.log", base_filename);
if (bu_file_exists(bu_vls_cstr(&vp), NULL)) {
bu_vls_printf(&vpid, "%s-%d.log", base_filename, id);
if (bu_file_exists(bu_vls_cstr(&vpid), NULL)) {
bu_file_delete(bu_vls_cstr(&vp));
}
//bu_file_move(bu_vls_cstr(&vp), bu_vls_cstr(&vpid));
}
bu_vls_free(&vpid);
bu_vls_free(&vp);
}
+6 -7
View File
@@ -50,15 +50,14 @@ double
average(int ac, double av[])
{
double total = 0.0;
int count = ac;
if (ac < 1 || !av)
return 0.0;
if (ac < 1)
return -0.0;
while (ac-- > 0) {
total += av[ac];
}
return total / (double)count;
return total / ac;
}
@@ -69,8 +68,8 @@ variance(int ac, double av[])
double err = 0.0;
double num = ac;
if (ac < 1 || !av)
return 0.0;
if (ac < 1)
return -0.0;
else if (ac == 1)
return 0.0;
@@ -82,7 +81,7 @@ variance(int ac, double av[])
}
/* return the sample variance */
return err / (num - 1.0);
return err / (num - 1);
}
+21 -33
View File
@@ -201,7 +201,7 @@ compare_rgb(int r1, int g1, int b1, int r2, int g2, int b2, size_t *matching, si
int
main(int argc, char *argv[])
{
const char *argv0 = (argc > 0 && argv && argv[0]) ? argv[0] : "pixcmp";
const char *argv0 = argv[0];
FILE *f1 = NULL;
FILE *f2 = NULL;
@@ -227,9 +227,7 @@ main(int argc, char *argv[])
size_t f2_skip = 0;
size_t stop_after = 0;
if (argc > 0 && argv && argv[0]) {
bu_setprogname(argv[0]);
}
bu_setprogname(argv[0]);
/* process opts */
while ((c = bu_getopt(argc, argv, "sdbi:n:q?")) != -1) {
@@ -322,8 +320,6 @@ main(int argc, char *argv[])
f2 = stdin;
} else if ((f2 = fopen(argv[1], "rb")) == NULL) {
perror(argv[1]);
if (f1 != stdin)
fclose(f1);
exit(FILE_ERROR);
}
@@ -332,8 +328,6 @@ main(int argc, char *argv[])
/* setmode(fileno(stdout), O_BINARY); */
if (f1_skip != f2_skip && f1 == stdin && f2 == stdin) {
if (f1 != stdin) fclose(f1);
if (f2 != stdin) fclose(f2);
bu_exit(OPTS_ERROR, "ERROR: cannot skip the same input stream by different amounts\n");
}
@@ -348,33 +342,27 @@ main(int argc, char *argv[])
/* bu_log("FILE1_size(%zu) FILE1_skip(%zu) FILE2_size(%zu) FILE2_skip(%zu)\n", (size_t)sf1.st_size, f1_skip, (size_t)sf2.st_size, f2_skip); */
{
size_t s1_eff = (sf1.st_size > (off_t)f1_skip) ? ((size_t)sf1.st_size - f1_skip) : 0;
size_t s2_eff = (sf2.st_size > (off_t)f2_skip) ? ((size_t)sf2.st_size - f2_skip) : 0;
const char *f2_name = (argc > 1 ? argv[1] : "-");
if (!quiet && (s1_eff != s2_eff)) {
bu_log("WARNING: Different image sizes detected\n");
if (print_bytes) {
bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
argv[0], s1_eff, (size_t)sf1.st_size, f1_skip);
bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
f2_name, s2_eff, (size_t)sf2.st_size, f2_skip);
} else {
bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
argv[0], s1_eff/3, (size_t)sf1.st_size, f1_skip);
bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
f2_name, s2_eff/3, (size_t)sf2.st_size, f2_skip);
}
if (!quiet && ((sf1.st_size - f1_skip) != (sf2.st_size - f2_skip))) {
bu_log("WARNING: Different image sizes detected\n");
if (print_bytes) {
bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
argv[0], (size_t)sf1.st_size - f1_skip, (size_t)sf1.st_size, f1_skip);
bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
argv[1], (size_t)sf2.st_size - f2_skip, (size_t)sf2.st_size, f2_skip);
} else {
bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
argv[0], ((size_t)sf1.st_size - f1_skip)/3, (size_t)sf1.st_size, f1_skip);
bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
argv[1], ((size_t)sf2.st_size - f2_skip)/3, (size_t)sf2.st_size, f2_skip);
}
}
/* make sure we read all bytes */
if (stop_after == 0) {
stop_after = FMAX(s1_eff, s2_eff);
if (f1 == stdin && f2 == stdin) {
/* dual stdin is interleaved */
stop_after = (stop_after+1)/2;
}
/* make sure we read all bytes */
if (stop_after == 0) {
stop_after = FMAX((sf1.st_size - f1_skip), (sf2.st_size - f2_skip));
if (f1 == stdin && f2 == stdin) {
/* dual stdin is interleaved */
stop_after = (stop_after+1)/2;
}
}
+5 -16
View File
@@ -64,32 +64,21 @@ int
run(int ac, char *av[])
{
int retval;
const char *run_geomname;
const char *run_geometry;
const char *run_target;
long int hypersample;
if (ac < 3 || !av || !av[0] || !av[1] || !av[2])
return -1;
run_geomname = av[0];
run_geometry = av[1];
hypersample = strtol(av[2], NULL, 10);
const char *run_geomname = av[0];
const char *run_geometry = av[1];
long int hypersample = strtod(av[2], NULL);
av += 3;
ac -= 3;
run_target = (ac > 0 && av && av[0]) ? av[0] : "";
{
struct bu_vls args = bu_argv_to_string(ac, (const char **)av);
echo("DEBUG: Running %s -B -M -s512 -H%ld -J0 %s -o %s.pix %s/%s.g %s\n",
run_target, hypersample, bu_vls_cstr(&args), run_geomname, run_geomname, run_geometry);
echo("DEBUG: Running %s -B -M -s512 -H%ld -J0 %s -o %s.pix %s/%s.g %s\n", av[0], hypersample, args, run_geomname, run_geomname, run_geometry);
bu_vls_free(&args);
}
/* pipe(stdin_for_bu_exec); */
retval = bu_exec("program", NULL, NULL, NULL);
echo("DEBUG: Running %s returned %d\n", run_target, retval);
echo("DEBUG: Running %s returned %d\n", av[0], retval);
return retval;
}
+630
View File
@@ -0,0 +1,630 @@
buopt production-readiness checklist
====================================
This checklist records the issues found during the post-rebase review of the
buopt branch. An item is complete only when the implementation and relevant
tests are both in place.
[x] Make libged command schema/grammar registries safe during static
initialization and concurrent registration/lookup.
[x] Make semantic-provider initialization and access thread-safe.
[x] Separate semantic candidate values from command-line insertion encoding
and transient-display escaping. Cover whitespace, quoting characters,
Tcl metacharacters, newlines, and terminal control bytes.
[x] Add schema-selectable database-object completion filters. Ordinary
geometry roles should exclude _GLOBAL; metadata-aware and binary-object
commands should explicitly request the broader or specialized sets they
support.
[x] Make a bare Escape cancel gsh completion without blocking for subsequent
input bytes.
[x] Honor the completion layout API's character-cell contract for UTF-8,
including wide and combining characters.
[x] Make MGED terminal cursor positioning safe for wrapped input, and account
for wrapped input rows in the Tk one-third-prior-output policy.
[x] Repaint gsh transient completion displays when a Windows console resize
event is received.
[x] Define and enforce safe initialization/lifetime contracts for public
completion and validation result objects.
[x] Allow qged/libqtcad command completion at an empty prompt.
[x] Reject negative argc in bu_cmd_schema_parse_complete before size_t casts.
[x] Audit and either eliminate or explicitly constrain libged unbound schema
rows so execution and completion grammars cannot silently drift.
[x] Pass BRL-CAD's repository regression: portable string/file APIs,
bu_setprogname in test mains, required source headers, and editor footers.
[x] Keep public libbu schema declarations C-only; do not expose C++
constructors in public C data structures.
[x] Preserve attached short-option arguments (for example, draw -m3) across
native parsing, validation, option-presence checks, operand counting, and
option-span analysis.
[x] Preserve draw's established transparency and line-width defaults when
native options are absent.
[x] Update the GQA plotting test for canonical encoded display-list paths.
[x] Keep non-command database-attribute readers on the supported bu_opt API
and limit the native-schema source audit to actual command parsers.
[x] Keep independently launched fbserv stress suites from racing for
overlapping ports while preserving simultaneous worker/server startup;
report closed-peer writes as failures instead of terminating on SIGPIPE.
[x] Correct MGED's appended Configure binding so GUI initialization does not
execute a stray closing brace, and exercise GUI binding installation in a
display-independent Tcl regression test.
[x] Remove the quadratic candidate-validation path from empty database-object
completion, keep option spellings out of object listings, recognize an
editable `--` as a long-option prefix, and avoid sorting every possible
summary refinement during large completion layouts.
[x] Add regression coverage for all corrected behavior and run the full build,
bu_opt compatibility tests, schema/completion tests, frontend PTY tests,
available Qt tests, and regress-repository.
[x] Keep bu_opt as the approachable option-authoring API while exposing
side-effect-free completion and validation inferred from every standard
bu_opt reader.
[x] Add an ABI-safe per-option sidecar for aliases, custom value types,
candidates, hints, variable token counts, and context-aware validators.
[x] Add a reentrant builder macro so commands declare familiar option rows
once and use them for parsing, help, completion, and schema publication.
[x] Add a compact GED option specification for positional roles and command
constraints, retaining full native schemas and parser-owned grammars only
for cases that need their additional expressiveness.
[x] Convert representative ordinary, constrained, and context-sensitive GED
commands (bb, kill, and ls) to the compact facade and preserve hidden,
type-filtered, alias, and _GLOBAL completion behavior.
[x] Add and registration-time lint a compact positional DSL for ordinary
option specifications. Cover cardinalities, GED semantic providers,
inline keyword vocabularies, inclusive numeric domains, common positive
and nonnegative domains, and standard color/vector/pattern token shapes.
[x] Survey the remaining full schemas for repeated declarative patterns.
Keep keyword metadata with aliases/descriptions, command-specific
validation, heterogeneous repeated groups, subcommand trees, and
parser-owned languages in native C definitions rather than growing the
textual facade into a second programming language.
[x] Preserve and test punctuation short options used by legacy commands, and
make runtime-generated compact schemas own their command names rather than
relying on registration-call pointer lifetimes.
[x] Identify custom multi-token option values from the parser's structural
result rather than a fixed backward-search window; cover values wider than
the built-in color/vector forms.
[x] Reject overflowing option-builder row counts before allocating the
required terminal descriptor.
Deep tab-completion API and scaling review (2026-08-13)
-------------------------------------------------------
[x] Separate syntax/semantic validation from candidate generation. A
validation-only query must not enumerate candidates, and one completion
request must invoke its selected semantic completer at most once. The
public `ged_cmd_validate` API now has that direct behavior; the redundant
completion-free validation alias was removed.
[x] Remove generic per-candidate reconstruction and whole-command validation.
Select context-dependent providers once from parsed command state; expose
an explicit lightweight candidate predicate only for the rare rules whose
legality actually depends on the proposed value.
[x] Make cursor handling correct in the middle of command, option, quoted,
escaped, UTF-8, object, and database-path tokens. Track the full token,
decoded prefix through the cursor, raw prefix/suffix spans, and the exact
replacement range separately.
[x] Add deterministic provider-call-count and mid-line replacement tests, plus
scaling tests which prevent broad object/path completion from regressing
to quadratic behavior.
[x] Filter database directory entries by type and prefix before sorting,
encode each matching name once, and avoid a second whole-database search
for ordinary unescaped hierarchy paths.
[x] Add a database completion index with reliable mutation invalidation so
root-object prefixes are O(log N + matches), while retaining command-
selected hidden, _GLOBAL, binary, primitive, combination, and region
policies.
[x] Add a request-oriented completion API with a candidate budget, total and
returned counts, truncation state, and independently computed common
prefix. Keep a compatibility wrapper for existing callers.
[x] Bound transient-layout work independently of terminal dimensions. Limit
materialized candidates and summary-frontier size, precompute UTF-8 widths
within each layout, retain the candidate set for resize-only repaints, and
debounce Qt resize rendering. A 10,000-candidate/100-row regression test
guards the layout path.
[x] Reuse the cursor parse throughout one completion request, avoid growing-
prefix revalidation in native schema analysis, and replace recursive
"copy schema and clear custom_validate" patterns with the explicit
bu_cmd_schema_validate_syntax API.
[x] Improve experimental API ownership and clarity: const provider data,
status separate from count, explicit byte-offset terminology, documented
token-grammar candidate ownership, and removal of result fields duplicated
by `expected` or `hint`.
[x] Convert the last potentially large composite database provider
(geometry-or-primitive) and filesystem provider to bounded query
interfaces, including full-set total/common-prefix metadata. File
completion now scans a directory once and retains O(K) rather than O(N)
candidate storage for a K-entry request.
[x] Keep parser-owned grammar adapters on the same classify-then-enumerate
path as flat schemas. Native tree/form adapters and delegated commands
now use syntax-only validation, search publishes its context-selected
object provider instead of scanning directly, and custom BREP component
indices honor the caller's materialization budget while reporting
full-set count, truncation, and common-prefix metadata.
[x] Keep the compatibility fallback for metadata-free commands on that same
path: syntax-only validation classifies the object/path role without a
database scan, and the outer request performs one bounded query.
[x] Keep custom final-value predicates from breaking filesystem navigation or
bounded extension filtering. Directory candidates remain available as
intermediate paths, while graph's SVG role selects an extension-aware
provider before applying its final-value validator.
[x] Release the allocated NULL-only argv returned by empty command and
database queries; repeated no-match completion must not leak.
[x] Re-run the full targeted completion/schema/frontend suite, repository
regression, and measured large-database/layout benchmarks before declaring
this section complete.
Post-squash review and follow-up (2026-08-13)
---------------------------------------------
[x] Preserve bu_opt callback parsing without speculative NULL-storage calls.
Standard flags are classified from descriptor metadata, opaque callbacks
are invoked exactly once with their actual storage, and partially known
compact flag words remain untouched pass-through operands.
[x] Apply command candidate predicates inside bounded semantic providers before
the materialization limit. Report total, truncation, and common prefix for
the full valid set rather than for a filtered prefix of that set.
[x] Keep hierarchical completion proportional to the selected subtree. Slash
paths query only direct children of the decoded parent, and pathsum, paths,
and listeval now combine their space-separated path components before
selecting that parent.
[x] Reduce completion-index memory by storing stable directory-entry iterators
in the reverse map instead of a second copy of every database object name.
[x] Generate standard command help from schema data. libbu now emits a
POSIX-style synopsis plus description, options (including aliases),
operands, repeated groups, and constraint hints; libged exposes the same
output by registered command name. rm, list/l, and the straightforward BoT
command family now use generated help rather than duplicated option text.
[x] Remove rm's growing-prefix custom-validator cost. Its force-sensitive
hidden/global completion policy is selected once by a request-aware
semantic provider, keeping analysis of arbitrarily long rm commands linear.
[x] Replace the gsh, MGED, and QgConsole fixed candidate limits with a shared
viewport-derived budget. Truncated MGED and QgConsole displays requery
after resize so a larger console can expose more candidates; all frontends
retain the one-third-prior-output/two-thirds-completion policy.
[x] Rename private "legacy" parser symbols that actually implement the
supported bu_opt descriptor callback contract. Genuine compatibility
aliases remain documented as such, but bu_opt is no longer described as a
retirement shim.
[x] Compile and run qgconsole_completion_modes in the shared Qt-enabled build
after the viewport-budget API change. The test now declares its ProFont
data dependency and tells Qt's offscreen backend where build-tree fonts
are staged.
[x] Restore qged's intended Inconsolata console font. The font survived the
earlier console/resource refactors in the source tree, but its resource
entry and selection logic did not; qged once again embeds and selects it.
Standard help and documentation audit (2026-08-13)
--------------------------------------------------
[x] Add standard synopsis/help builders for bu_opt descriptors, native flat
schemas, native trees, and registered GED commands. Generated schema help
now includes aliases, operands, repeated groups, constraints, keyword
values (with aliases and descriptions), and numeric domains.
[x] Make a shaped multi-token operand appear once in a synopsis. For example,
a packed point or three XYZ words is one semantic `point`, not three
independently optional point values.
[x] Audit production bu_opt users which printed a literal Usage string. Every
such command/program now obtains its option list from bu_opt_help or
bu_opt_usage; the only metadata-free match left by the source audit is an
internal libbv test program.
[x] Convert schema-backed help sites to the standard generators wherever the
metadata describes the executable syntax. The pass touched 197 libged
implementation modules (229 help-producing source sites) and 22 executable
entry points, in addition to shared frontend support modules.
[x] Correct option-definition styling in 35 AsciiDoc man pages. Short and long
spellings are separate bold spans, argument metavariables are italic rather
than part of the option name, and definition-list punctuation is uniform.
All changed pages convert successfully with asciiquack's manpage backend.
[x] Correct the metaball point metadata uncovered by the help audit. Its
execution parser once again accepts both the packed and three-coordinate
forms, including the relative move option, and completion does not
revalidate an individual coordinate as a complete vector.
[x] Add a first-class alternative-form abstraction to libbu. A form should
have a label/description and a complete schema or tree; one form set must
drive validation, parsing, help, JSON, lint, and completion. The private
libged native-form adapter used by who and zap is a useful prototype, but
keeping this concept outside the common metadata leaves commands such as
make_name unable to publish `template` versus `-s [number]` as exclusive
standard synopses. Public form sets now drive selection, validation,
parsing/dispatch, help, JSON, lint, and GED completion adapters; ambiguous
partial forms remain incomplete and merge compatible candidates rather
than becoming prematurely invalid.
[x] Add a declarative grouped-value/form facility for non-vector alternatives,
notably orient's packed quaternion versus four scalar components. The
vector3 shape now documents ordinary packed-or-XYZ points correctly, but a
command-specific count validator remains opaque to help and JSON. Named
argument variants now publish each accepted spelling and token width, and
the standard color, RGB, vector, counted-vector, optional-scalar, orient,
edit, faceplate, and other custom shapes use them.
[x] Complete metadata for parser-owned and dynamically assembled command
families. Search needs human descriptions on its shared term vocabulary;
edit, joint, faceplate, and vdraw need inspectable command/form records;
env needs its list/get/set forms represented rather than a raw root tail.
Search terms now carry shared descriptions; edit publishes its generic
operation tree; joint, faceplate, and vdraw expose their command records;
and env publishes distinct list/get/set forms.
[x] Replace the remaining exact syntax prose in 20 production schema-bearing
libged modules. Most are incomplete nested leaves or mode-dependent
grammars (db, comb, arb/edbot, view objects/polygons, nmg, pnts, qray,
facetize, and related helpers), not simple missed calls to the generator.
Do not delete these strings until their schemas can generate equivalent
output; doing so would make help less correct while concealing missing
specifications. The nested db, comb, arb/BoT, view object/polygon/
faceplate, NMG, pnts, qray, analyze, and facetize paths now generate their
structural help from schemas or form/tree metadata.
[x] Correct executor/metadata mismatches found while replacing the remaining
faceplate help. Rectangle backgrounds are colors, the executable axes
spelling is `axes_color`, Boolean values are limited to zero or one,
positive/nonnegative numeric domains are shared by validation and help,
parameter setters read the supplied value rather than the subcommand name,
and invalid colors/font sizes no longer use uninitialized storage.
[x] Add concise one-sided integer and number range initializers and option/
operand macros so common positive, nonnegative, ceiling, and floor domains
do not need artificial maximum values or custom validators.
[x] Treat generated help metadata as the executable contract rather than
reproducing known defects in historical prose. Correct stale MGED help
exit-status expectations and make invalid hierarchical completion parents
return zero candidates instead of a positive error code that could be
mistaken for a materialized result.
Lower-priority follow-up opportunities
---------------------------------------
These are not recommended as merge blockers. They are deliberately deferred
because the current measured paths are bounded and the additional abstraction
would be a substantially larger API change without a demonstrated caller need.
* Continue opportunistically migrating schema-backed commands that still
assemble usage/options prose by hand. The generator is now the normative
path; command-specific examples, caveats, and extended explanations should
be appended after its output rather than restating syntax. This is ongoing
maintenance rather than a finite merge-readiness defect.
* A public parsed-command/scan object could share work across separate calls to
analysis, validation, option-presence, and completion. Within an individual
completion request the parse is already shared; most callers make only one of
these queries, so a public lifetime-bearing object would currently add more
ownership complexity than saved work.
* Structured candidate records could carry distinct insertion and display
strings. Providers currently return values in their declared token grammar
and frontends own shell/Tcl display encoding. Introduce records only if a
provider needs genuinely different insertion and display values; doing it
speculatively would make every simple provider more verbose.
* Parser-owned languages such as search may eventually expose one inspect tree
for execution, validation, completion, and JSON. They are intentionally
retained as parser-owned grammars today: forcing them into the ordinary
option schema would duplicate their language or turn the compact schema DSL
into a general parser generator.
Deep post-rebase review follow-up (2026-08-14)
----------------------------------------------
[x] Make every BU_CMD_VALUE_CUSTOM parser honor NULL storage as a
side-effect-free validation request. Correct the pnts radius, radii, and
thread-count consumers and test all three through schema validation.
[x] Fully initialize transient bu_cmd_schema records built by the bu_opt
adapters, including cases and terminal-action metadata. Exercise them
with poisoned stack storage in parsing and validation tests.
[x] Release ged_cmd_analysis storage on every completion path, including the
public context result, and add a repeated completion ownership regression.
[x] Make QgConsole completion rows genuinely transient: displaying, resizing,
and removing candidates must never evict or alter permanent console
history, even when the document is at its maximum block count.
[x] Pass QgConsole's complete editable command and cursor byte offset to GED
completion so mid-token and mid-line replacement preserves the suffix.
Apply the same rule to preview filtering.
[x] Recompute MGED wrapped-input erase geometry using the current terminal
width after resize. Cover both narrowing and widening long input.
[x] Separate executable form selection from interactive continuation so a
valid short form does not hide candidates from a viable longer form.
[x] Make command-tree/form dispatch honor the root schema and all child-phase
policies, including root options, fixed operands, aliases, and nesting.
[x] Replace the O(candidate_count * row_count) full-layout search with a
bounded or incremental algorithm and test the narrow/tall maximum-budget
case.
[x] Replace compact bu_opt's repeated prefix validations with one structural
analysis and one custom validation per actual option value.
[x] Bound the database completion cache by retained bytes/candidates, use a
useful eviction policy, and avoid retaining very large materialized query
vectors.
[x] Apply filesystem candidate predicates during the directory scan rather
than materializing an unbounded pre-filter result.
[x] On gsh resize, rebuild both the displayed and selectable completion state
while preserving the selected value when possible.
[x] Avoid repeated DSR timeout delays and preserve non-DSR input bytes when a
terminal does not answer cursor-position queries.
[x] Add one authoritative completion-result merger which preserves limits,
full-set totals, truncation, common prefixes, and deduplication when static
and semantic candidates are combined.
[x] Unify libbu and GED schema linting and run it transactionally on the exact
schema being registered. Diagnose unknown semantic providers without
emitting pre-main log output.
[x] Make rich keyword linting reject every canonical/alias collision,
including a later canonical matching an earlier alias and duplicate
aliases within one row.
[x] Use the shared Boolean reader for syntax validation so validation and
execution agree for empty and malformed attached values.
[x] Define a portable C++ binding policy for schema storage. Keep byte-offset
bindings limited to standard-layout records and provide an explicit
alternative for non-standard-layout command state.
[x] Reuse QgConsole's completion model rather than accumulating parented
QStringListModel objects over repeated updates.
[x] Extend the focused and stress suites to cover every defect above, then run
the all-target Ninja build, completion/schema/frontend suites, repository
regression, and git diff checks.
Post-squash deep review follow-up (2026-08-14)
-----------------------------------------------
[x] Preserve an explicit decoded-byte-to-raw-byte boundary map while MGED
normalizes Tcl words for completion. Use that map for replacement and
cursor offsets so quoting and backslash substitution cannot corrupt the
original command. Cover quoted words, escaped spaces, escaped slashes and
backslashes, UTF-8, and mid-token suffixes; the current m35.g reproducer
turns `draw component\/suspension/r2` into
`draw component\/suspensionr22`.
[x] Make dynamic command and schema loading one retained, transactional
operation. Never register schema pointers from the temporary inspection
handle when the generalized plugin load failed, and do not publish an
executable command if its metadata is malformed. Add a plugin fixture
with a rejected generic manifest and an otherwise readable schema
manifest to guard against dangling registry pointers.
[x] Publish each command implementation, compatibility alias, and exactly one
metadata kind atomically. Treat duplicate metadata as part of the same
first-wins decision, roll back on failure, serialize initialization
diagnostics, and stress simultaneous duplicate registration to prove that
an implementation cannot be paired with another declaration's schema.
[x] Make built-in semantic-provider ownership independent of call order.
Install built-ins before accepting public registrations, reserve the
`ged.*` namespace (or require an explicit override policy), and test an
attempted built-in-name registration before the first lookup.
[x] Give semantic providers a complete C-facing contract. Publish their
result value type and capability flags in the provider record rather than
classifying built-ins with string comparisons, document candidate/result
ownership, and keep the implementation free to own registration records
with C++17 RAII. Ensure shutdown removes custom provider data before its
documented lifetime ends.
[x] Define and test libged lifecycle semantics. Either make shutdown a
synchronized terminal state which rejects every later registry operation,
or make initialization and teardown repeatable; do not leave command,
schema, or semantic-provider registries in different generations. Clear
metadata before unloading the modules which own its callback and string
pointers.
[x] Compute every full-set common prefix on a valid UTF-8 boundary in the
shared completion layer rather than repairing it in individual
frontends. Make QgConsole's command, candidate, and source-offset
conversions explicitly UTF-8 instead of locale-dependent local-8-bit
conversions, and cover candidates whose first differing code points share
an initial UTF-8 byte.
[x] At an empty search path/expression position, merge bounded database-path
candidates with the valid static search options and expression terms.
Preserve hidden-object policy and exact total/truncation/common-prefix
metadata while ensuring `_GLOBAL` remains excluded from ordinary search
path completion.
[x] Validate and normalize semantic-provider output at the registry boundary:
candidate pointer/count consistency, total count no smaller than the
materialized count, truncation consistency, bounded materialization, and a
valid full-set common prefix. Clamp frontend summary arithmetic as a
defensive fallback and add malformed-provider tests.
[x] Reduce compact GED declaration boilerplate without inferring semantic
aliases from storage or help text. One typed GED_RULE_* table now holds
aliases, forms, database roles/type cases, semantic refinements,
constraints, and validators and is normalized into owned schema storage
once at registration. All 17 production sources which formerly needed
compact metadata sidecars use the table, identical metadata can name
multiple options in one row, and all 40 BU_OPT_DESC_BUILDER definitions
use the concise BU_OPT_* field-binding rows wherever the callback binds an
ordinary argument field. The remaining raw rows intentionally pass the
whole argument record to custom readers. Explicit compatibility aliases
are covered by registry JSON tests rather than guessed from shared
storage; the source audit prevents a return to per-kind sidecars or raw
conditional field bindings.
[x] Consolidate the duplicated bu_opt-to-native-schema adapter logic in libbu
and libged so type, arity, optional-value, shaped-value, alias, validator,
and standard-candidate inference have one implementation. Likewise share
and cache search's immutable type vocabulary instead of rebuilding and
maintaining it in both the generic provider and parser-owned grammar.
[x] Resolve aliases during the shared adapter build. An alias inherits the
canonical option's type, shape, cardinality, candidates, validator,
semantic role, and argument requirement unless it explicitly overrides
presentation metadata. Reject unknown targets and cycles, remove the
typed-alias workaround, and verify parse/help/JSON/completion equivalence
for standard and opaque option readers.
[x] Make flat-rule declarations counted. Add a rule count to ged_opt_spec,
derive it in declaration macros, and stop reading caller memory in search
of a missing sentinel. Preserve GED_RULE_NULL as an optional readability
marker only if doing so cannot conceal an incorrect count.
[x] Make the first broad root completion scale as well as repeated queries.
Add a genuinely cold 100k-object test, then replace the per-entry map build
and full matching-range scan for built-in policies with a prefix-oriented
index carrying aggregate count/common-prefix metadata and bounded ordered
materialization. Retain a scan fallback for arbitrary candidate filters
and verify database mutation invalidation.
[x] Debounce QgConsole semantic highlighting so ordinary edits do not
synchronously reparse the entire command on every keystroke. Split the
largest new implementation and test files by responsibility after the API
behavior is settled, preserving the existing focused and scaling
coverage.
[x] Modularize the corrected implementation along useful ownership boundaries.
Database completion generations and command-input parsing now have focused
C++17 modules; the immutable search vocabulary belongs to librt; registry
lifecycle/plugin transactions and scaling have independent tests; MGED and
QgConsole retain their frontend-offset suites. Keep the public libbu and
libged boundaries C-only and document the new public adapter functions.
Steady-state review follow-up (2026-08-14)
------------------------------------------
[x] Extend the libged activity lease beyond command execution. Help, JSON,
lint, validation, analysis, completion, form/tree adapters, and semantic
provider callbacks must remain valid while shutdown waits; registrations
attempted during teardown must be rejected deterministically.
[x] Enforce one metadata representation across every registration entry point,
reject malformed or reserved command names before normalization can split
implementation and metadata keys, and cover direct-API collisions.
[x] Preserve natural candidate ordering for bounded broad-prefix index queries.
Replace the lexical fast-path with a range-minimum natural-rank index so a
100,000-match query remains O(log N + K log N) without changing behavior.
[x] Reject truncated semantic-provider results that cannot prove a valid UTF-8
common prefix for the complete filtered set, and add a malformed bounded
provider regression.
[x] Give ged_cmd_lookup a stable documented result lifetime and omit synthetic
`_mged_` aliases; its current pointer refers to a destroyed foreach
snapshot as soon as the function returns.
[x] Propagate parser, grammar, and semantic-provider failures through the
bounded completion API; reject inconsistent truncated materializations,
distinguish a valid empty common prefix from missing metadata, and remove
the arbitrary 65,536-entry ceiling from explicitly unbounded queries.
[x] Make outward-facing validation, analysis, and completion metadata strings
result-owned before releasing the registry lease. Fix the command-name
completion snapshot leak, retain repeated analysis strings in one
deduplicated allocation instead of two allocations per token, and verify
retained results remain valid across shutdown and repeated clear
operations.
[x] Remove quadratic compact-schema highlighting. Resolve option-selected DB
providers once per complete argv with a private analysis plan, apply later
context options consistently to earlier operands, and cover a 5,000-value
`ls ... -a` analysis workload.
[x] Finish the completion-index and metadata ownership cleanup. Build policy,
natural-order, and range-minimum views only when requested; share the DB
path encoder and object-policy predicate rather than maintaining parallel
copies; make command-list snapshots explicitly owned/NULL-terminated; and
require every parser-owned grammar to provide generated help. Give the
analysis result the same explicit initializer/reusable-result contract as
validation and completion results.
[x] Release the temporary argv used by filtered bu_opt help generation; the
richer standard-help path makes repeated filtered descriptions a normal
API use rather than a one-shot process-lifetime allocation.
[x] Release gsh's owned command-list snapshot after `--command-schema all`;
the newly explicit ged_cmd_list ownership contract applies to early-exit
introspection paths as well as interactive completion. Update the schema
round-trip and plugin-enumeration tests to follow the same contract.
[x] Make natural completion ordering a total order. Numerically equivalent
spellings such as `1` and `01` must have a deterministic lexical tiebreak
so bounded index queries, heaps, and full-result normalization agree; use
relational comparison rather than overflowing unsigned subtraction for
maximum-width numeric suffixes.
[x] Enforce exact truncated-result metadata at the final completion boundary,
not only for named semantic providers. Parser-owned grammar callbacks
must supply a full-set total and allocated (possibly empty) common prefix;
never derive insertion text from an arbitrary displayed subset. Apply
the same UTF-8, prefix, uniqueness, filter, budget, and natural-order
normalization to grammar materializations as to named providers.
[x] Make every reusable public validation, analysis, and completion result
transactional on failure. Clear old contents before argument/lifecycle
checks and clear partially populated grammar/tree/form callback output on
error, so frontends never retain stale metadata or need callback-specific
failure cleanup. Exercise deliberately failing grammar callbacks and an
invalid bounded-completion request with previously populated results.
[x] Clamp cursor offsets once at the shared command-input parser boundary so
validation adapters cannot publish source spans beyond the supplied input
when an editor reports a stale or oversized cursor position.
[x] Make natural ordering independent of machine integer width and C numeric
syntax. Compare arbitrary-length decimal digit runs directly, retain a
deterministic lexical tiebreak for equivalent zero-padded spellings, and
cover values beyond ULONG_MAX in bounded and unbounded indexed queries.
[x] Enforce the counted flat-rule contract. A retained GED_RULE_NULL visual
terminator is valid only as the final counted row; reject a premature END
rather than silently hiding subsequent author declarations.
[x] Apply the reusable-result transaction contract uniformly at the libbu
boundary. Descriptor, builder, schema, shaped-value, tree, and form
validation now release stale and partially callback-populated candidates
on every failure. An empty command-schema result reports an unknown role
rather than misleadingly defaulting to string; focused tests reuse seeded
results across invalid arguments, builder failures, and failing callbacks.
[x] Bound the database index's policy-view cache, not only its returned
candidate vectors. Ignore unsupported flag bits when selecting a view
and evict least-recently-used O(database-size) policy arrays after a fixed
limit; exercise normalization and eviction against the 100,000-object
database.
[x] Document borrowed registration lifetimes consistently for command,
native-schema, compact-schema, grammar, and semantic-provider metadata,
including the transactional failure rule for parser-owned callbacks.
[x] Re-run the all-target build, focused 100,000-object and lifecycle races,
exhaustive completion corpus, frontend tests, repository/license checks,
and final diff audit after these fixes.
Verification notes
------------------
* The final steady-state pass completes warnings-as-errors all-target rebuilds
after the result-ownership and bounded policy-cache fixes (1,168 actions for
the consistent rebuild and 154 actions after the last source audit). All
126 selected libbu, schema, lifecycle, 100,000-object, exhaustive corpus,
Qt, gsh, MGED GUI/PTY, native-source, repository, license, and change-policy
tests pass in 14.19 seconds. The cold scale test, including 64 policy-cache
probes, finishes in 6.90 seconds. Focused Memcheck runs report no definite
leaks or invalid accesses for command schemas, failing bu_opt callbacks, or
registry/plugin shutdown. git diff --check is clean.
* The final post-squash implementation completes a 1,607-action all-target
Ninja rebuild. The 125-test focused selection passes in full after the new
lifecycle test was brought into repository-policy compliance: all bu_opt
and command-schema tests, both command-analysis datasets, the exhaustive
completion corpus, the cold 100,000-object scale test, registry/plugin
lifecycle transactions, Qt console behavior, gsh and MGED terminal/GUI
paths, native-schema source audit, license and change-policy checks, and
regress-repository. The scale test takes 5.12 seconds including database
construction, and the completion corpus takes 11.88 seconds.
* The post-squash follow-up adds a cold 100,000-object root benchmark, a
rejected-manifest plugin fixture, concurrent command/schema publication,
repeatable shutdown/provider cleanup, counted-rule, alias-chain, malformed
provider, UTF-8, Tcl quoting/backslash, Qt debounce, and search-union
regressions. The focused completion-scale test finishes in under four
seconds in the unoptimized warnings-as-errors build; warm broad-prefix
materialization is required to remain below 250 ms.
* The compact-rule and option-row cleanup completes an all-target Ninja build
and passes all 135 focused libbu option/schema/help, GED command/completion,
Qt console, gsh, MGED, source-audit, repository, license, and change-policy
tests. Runtime schema checks cover every compact command alias declaration,
and git diff --check is clean.
* The 2026-08-14 post-rebase follow-up completes an all-target Ninja build and
passes all 118 focused bu_opt, schema, file, line-editor, command-analysis,
completion-corpus, Qt console, gsh, MGED, and source-audit tests. The
repository and license regressions pass, and git diff --check is clean.
* The post-review all-target Ninja rebuild completes successfully. The final
focused pass covers all 100 libbu schema/bu_opt/line-editor tests, both
libged command-analysis suites, seven gsh/MGED terminal completion tests,
the MGED completion bridge, and the repository and license regressions.
git diff --check is clean.
* The final help/form follow-up completes a 1,762-action all-target Ninja
rebuild and passes 118 focused schema, bu_opt, completion-corpus, Qt console,
gsh, MGED, and license tests, plus regress-repository.
* The Ninja build completes successfully.
* The schema, command-analysis, completion-corpus, gsh PTY, MGED PTY/bridge,
bu_opt compatibility, BoT, license, and repository regression tests pass.
* The gsh resize/cursor PTY test passes repeatedly to exercise its timing path.
* The shared Qt-enabled Debug build compiles qged and libqtcad with warnings as
errors and passes qgconsole_completion_modes using its declared build-tree
font dependency.
* A post-rebase full 1,277-test CTest run completed with 1,274 passes. One
failure is the intentional test-target sentinel. The native-schema source
audit exposed an over-broad policy check and now passes after limiting the
bu_opt exemption to a non-command scalar-reader source. slow-bigdb_5gb was
killed under the eight-way full-suite memory load and passed alone in 70.6
seconds. All other tests, including bu_process_all, both fbserv stress
tests, changes-rules, GQA, and all drawing tests, passed in the full run.
* The fbserv quick and heavy stress suites pass ten consecutive runs with both
suites launched concurrently after assigning automatic invocations disjoint
bounded port slots.
* The MGED GUI binding test and all MGED CLI/completion tests pass after the
Configure binding correction; repository and license regressions also pass.
* All 97 bu_opt tests and both command-analysis suites, including the m35.g
completion corpus, pass with the compact positional DSL enabled.
* On m35.g in the Debug build, `ls ` completion generation drops from about
5.15 seconds to 11 milliseconds. A 100-column, 30-row summary drops from
about 486 to 315 milliseconds; the normal two-row GUI budget takes about 14
milliseconds. Empty `ls ` completion contains objects only, while `ls --`
offers all ten long options.
* The deep-review final tree completes the all-target Ninja build, passes
git diff --check and regress-repository, and passes all 118 targeted libbu,
schema, command-analysis, completion-corpus, gsh, and MGED tests. The
100,000-object analysis/scaling test, including the broad empty-prefix
`ls /` case, `draw /`, composite geometry-or-primitive queries, and cache
mutation checks, finishes in about 2.9 seconds. The 10,000-candidate/100-row
layout test finishes as part of a 0.27-second line-editor test.
* A focused Memcheck replay of the delegated `blast` grammar passes after
correcting its transferred common-prefix ownership. The exhaustive native
completion corpus passes in 11.4 seconds; its optional whole-corpus Memcheck
run was stopped after more than twelve CPU-bound minutes with stable memory
and no diagnostics.
+1 -1
View File
@@ -47,7 +47,7 @@ Set the output width in pixels.
*-n* _height_::
Set the output height in pixels.
*-h, -?*::
*-h*, *-?*::
Print a usage message and exit.
[[examples]]
+1 -1
View File
@@ -76,7 +76,7 @@ Outputs to the specified framebuffer instead of the one specified
by the `FB_FILE` environment variable. If this is the last option,
the *-F* prefix is optional.
*-h, -?*::
*-h*, *-?*::
Print a usage message and exit.
+34 -1
View File
@@ -56,6 +56,27 @@ display window of its own.
update logic instead of the traditional command set. Primarily of use for
development and testing of the next-generation command behavior.
*--completion-mode=mode*::
Select the interactive completion policy. Supported values are *filter*,
*cycle*, *prefix*, *legacy*, and *off*. See *brlcad-completion*(5).
*--command-schema=command|all*::
Print the registered static command grammar as JSON and exit. A command
name prints one grammar; *all* prints a JSON array for the full discoverable
LIBGED registry. Runtime-dependent semantic providers are identified by
name, allowing external syntax highlighters and ANTLR grammar adapters to
consume the static command structure without opening a database.
[[environment]]
== ENVIRONMENT
*BRLCAD_GSH_COMPLETION_MODE*::
Sets GSH's completion mode when *--completion-mode* is not specified.
*BRLCAD_COMPLETION_MODE*::
Sets the shared BRL-CAD completion mode when no GSH-specific setting is
present. See *brlcad-completion*(5) for mode behavior and precedence.
[[examples]]
== EXAMPLES
@@ -81,6 +102,18 @@ not a terminal, *gsh* executes each line in turn with no prompt, reporting the
database title, an object listing, and a summary of the contents of `moss.g`.
====
.Publish command grammars for an external tool
====
[source,bash]
----
gsh --command-schema draw > draw-schema.json
gsh --command-schema all > ged-schemas.json
----
The first form emits one flat command schema. The second emits every flat,
nested, context-selected, and parser-owned static grammar registered by
LIBGED.
====
.Inspect and modify geometry interactively
====
[source,bash]
@@ -100,7 +133,7 @@ LIBGED commands available here are shared with *mged*(1) and *archer*(1).
[[see_also]]
== SEE ALSO
*brlcad*(1), *mged*(1), *archer*(1), *btclsh*(1)
*brlcad*(1), *mged*(1), *archer*(1), *btclsh*(1), *brlcad-completion*(5)
[[author]]
== AUTHOR
+6 -1
View File
@@ -217,6 +217,11 @@ _MGED_ searches for a startup configuration file (`.mgedrc`) in three locations,
. If the environment variable `HOME` is set, `$HOME/.mgedrc` is used.
. If `.mgedrc` exists in the current working directory, it is used.
The command prompt completion policy may be persisted with
`set mged_default(completion_mode) mode` in _.mgedrc_, or selected with the
*BRLCAD_MGED_COMPLETION_MODE* and *BRLCAD_COMPLETION_MODE* environment
variables. See *brlcad-completion*(5) for the supported modes and precedence.
The first file found is used and the others are ignored. Use *--rcfile* to specify an explicit path, or *--no-rc* to skip rc file processing entirely.
Command-line options that affect MGED variables (all the long options listed above) are applied _after_ the rc file is processed, so they always take precedence.
@@ -350,7 +355,7 @@ user:~**mged --rset "g snap 1" --rset "g rh 10" model.g**
_Computer Graphics for Target Descriptions_, BRL Technical Report ARBRL-TR-02480, _GED: An Interactive Solid Modeling System for Vulnerability Assessments_
*brlcad*(1), *rt*(1), *comgeom-g*(1), *vdeck*(1), *librt*(3)
*brlcad*(1), *rt*(1), *comgeom-g*(1), *vdeck*(1), *librt*(3), *brlcad-completion*(5)
[[diagnostics]]
+5
View File
@@ -96,6 +96,11 @@ When standard input is not a terminal (for example, when it is redirected from a
*-B*::
Deprecated and no longer used; accepted but ignored.
For each color option, the three channels may be supplied as one packed
_r/g/b_, _r,g,b_, or _r;g;b_ argument, or as three separate _r g b_
arguments. The packed compatibility color forms historically accepted by
*nirt* continue to work as well.
*nirt* also checks for a `.nirtrc` start-up file, first in the current directory and then in the user's home directory. If found, it is read before interaction begins and may contain any *nirt* commands, which is useful for loading predefined states or output formats.
+1 -1
View File
@@ -126,7 +126,7 @@ WARNING: The terminology and output format of *rtarea* may change in future rele
*-X* _#_::
Set *rt* program/optical debug flags as a hexadecimal bit vector.
*-? or -h*::
*-?*, *-h*::
Print a usage summary and exit.
[[examples]]
+1 -1
View File
@@ -91,7 +91,7 @@ options most relevant to overlap checking are listed below.
Whether *librt*(3) retains air-coded regions (0 = discard air, the
default; 1 = keep air).
*-+ t*::
*-+* _t_::
Emit the plot data in ASCII text format rather than the default binary
*plot3*(5) encoding.
+1 -1
View File
@@ -107,7 +107,7 @@ also honored; see that manual page for the complete list.
*-X* _#_::
Set *rt* program/optical debug flags as a hexadecimal bit vector.
*-? or -h*::
*-?*, *-h*::
Print a usage summary and exit.
See *rt*(1) for the remaining shared options (e.g. *-g*/*-G* grid cell
+1 -1
View File
@@ -125,7 +125,7 @@ also honored; see that manual page for the complete list.
*-X* _#_::
Set *rt* program/optical debug flags as a hexadecimal bit vector.
*-? or -h*::
*-?*, *-h*::
Print a usage summary and exit.
See *rt*(1) for the remaining shared options (e.g. *-T* tolerances, *-c*
+496
View File
@@ -68,3 +68,499 @@ This software is Copyright (c) 2004-2026 United States Government as represented
== BUG REPORTS
Reports of bugs or problems should be submitted via electronic mail to devs@brlcad.org
== Compact command schemas
The `bu_cmd_schema` API in `bu/cmdschema.h` is the full-description face of the
command engine, adding typed operands, validation, completion metadata,
constraints, declarative numeric ranges, and machine-readable publication.
The established `bu_opt` API remains the succinct option-only face of the same
engine. Its descriptor table and `bu_opt_*` reader callbacks are appropriate
when a caller only needs conventional option parsing and a leftover argument
list. It also supplies lightweight completion and validation without forcing
the caller to rewrite those option rows as a second table.
`bu_opt_desc_value_type` recognizes every standard reader in `bu/opt.h`:
`bu_opt_bool`, `bu_opt_int`, `bu_opt_long`, `bu_opt_long_hex`,
`bu_opt_incr_long`, `bu_opt_fastf_t`, `bu_opt_char`, `bu_opt_str`,
`bu_opt_vls`, `bu_opt_color`, `bu_opt_vect_t`, `bu_opt_lang`, and
`bu_opt_man_section`; a null reader is a flag. `bu_opt_desc_validate` uses
that information to complete option spellings, validate supplied values, and
report incomplete multi-token colors and vectors without invoking a custom
reader or modifying caller state.
Opaque readers may be described by a `bu_opt_value_spec` sidecar. A row may
override the inferred value class, publish fixed candidates, specify a hint or
variable token cardinality, identify a separate spelling as an alias, and
install a side-effect-free validation callback.
The callback receives the full argv, cursor index, caller context, and row data
for context-dependent value rules. Standard readers need no sidecar.
For reentrant use, define one ordinary initializer-row macro and pass it to
`BU_OPT_DESC_BUILDER`. The generated file-local builder binds fields in a
caller-owned argument record during parsing and leaves them unbound for help
or validation. `bu_opt_parse_build`, `bu_opt_describe_build`, and
`bu_opt_validate_build` perform those projections. The generated row count is
derived from the local array rather than repeated by the command author.
The API provides three views of the same schema:
* `bu_cmd_schema_parse` binds command-line options to a caller-owned argument
structure. The argument pointer may be null for an optionless schema,
because there is then no storage to bind. `bu_cmd_schema_parse_complete`
additionally requires all positional roles to satisfy their declared
cardinality and scalar rules. `bu_cmd_schema_parse_known` consumes only
recognized options for layered parsing.
* `bu_cmd_schema_describe` produces command help, while
`bu_cmd_schema_describe_json` produces machine-readable metadata.
* `bu_cmd_schema_validate` performs side-effect-free incremental syntax and
scalar-type validation, returning static candidates for completion and
highlighting. `bu_cmd_schema_validate_ctx` adds an optional host context
for semantic rules that need live application state, while preserving the
same native option and operand grammar.
The validation result owns its candidate array. Initialize it with
`BU_CMD_VALIDATE_RESULT_NULL` and release it with
`bu_cmd_validate_result_clear` after each use.
For presentation, `bu_cmd_completion_layout_create` arranges a candidate set
for a known terminal width. It emits the complete sorted set, or a complete
optimized prefix-bin frontier, in no more than the requested number of rows
when that fits. Otherwise it emits one partial summary row ending in an
explicit omitted-candidate count, without changing the original candidate
array used for insertion and cycling. Initialize its result with
`BU_CMD_COMPLETION_LAYOUT_INIT_ZERO` and release it with
`bu_cmd_completion_layout_clear`.
=== Declaring a simple schema
Define an argument structure with the command defaults, then declare options
using the `BU_CMD_*` helpers. Each option names its short spelling, long
spelling, storage field, value type, argument label, and help text once.
Use `BU_CMD_COUNTING_FLAG` for a repeatable no-argument option whose integer
storage field must count occurrences (for example, `-vv`). Ordinary
`BU_CMD_FLAG` options remain boolean even when they are repeated.
`BU_CMD_CUSTOM_FLAG` is the deliberate escape hatch for an order-sensitive
no-argument state transition; its parser receives a NULL argument and the
selected storage-field address.
Use `BU_CMD_OPTIONAL_STRING` for a conventional `--option [text]` form. It
binds the next non-option word when present, but leaves a following option for
the regular option scanner; pass a literal text value beginning with `-` using
the attached `--option=value` spelling.
`BU_CMD_DB_OBJECT` and `BU_CMD_DB_PATH` are compact typed-option forms for
database object and path values. They keep libbu application-neutral: an
application such as GED may infer its default semantic provider from the value
type, while a specialized role may name an explicit provider in its full
`bu_cmd_option` or `bu_cmd_operand` row.
[source,c]
----
struct example_args {
int verbose;
fastf_t scale;
const char *output;
};
static const struct bu_cmd_option example_options[] = {
BU_CMD_FLAG("v", "verbose", struct example_args, verbose,
"Enable diagnostic output"),
BU_CMD_NUMBER("s", "scale", struct example_args, scale, "factor",
"Scale the result"),
BU_CMD_FILE("o", "output", struct example_args, output, "file",
"Write the result to a file"),
BU_CMD_OPTION_NULL
};
----
Aliases use `BU_CMD_ALIAS_SHORT` or `BU_CMD_ALIAS_LONG` and name the canonical
option. Hidden aliases remain accepted by the parser but are omitted from
help and completion. Custom values use `BU_CMD_CUSTOM`; their parser receives
a pointer to that option's storage during execution and a null storage pointer
during validation, so custom parsers must treat a null pointer as a
side-effect-free syntax check.
Typed options and operands may also use a `BU_CMD_*_VALIDATE` helper
(`BU_CMD_OPERAND_VALIDATE` for a positional role). Its validator is called
without storage during incremental validation; option parsing applies it when
binding execution storage, and a command's positional parser can reuse the
same function. This publishes constraints such as an integer range without
reducing the value to an opaque custom value.
For common scalar ranges, use `BU_CMD_POSITIVE_INTEGER`,
`BU_CMD_NONNEGATIVE_INTEGER`, `BU_CMD_POSITIVE_NUMBER`, or
`BU_CMD_NONNEGATIVE_NUMBER`. Their libbu validators use the same strict
base-zero integer or finite floating-point spelling accepted by the matching
typed option and produce a shared range diagnostic. Use a command-specific
validator only when its range or error explanation is genuinely
domain-specific.
When a typed positional role must be stored after schema validation, use
`bu_cmd_bool_from_str`, `bu_cmd_integer_from_str`, `bu_cmd_hex_integer_from_str`,
`bu_cmd_long_from_str`, `bu_cmd_hex_long_from_str`, `bu_cmd_number_from_str`, or
`bu_cmd_char_from_str` instead of adding another `strtol`, `strtod`, or
first-character reader to the command. They return nonzero on success and
leave the destination unchanged on failure, using exactly the native scalar
grammar. `BU_CMD_HEX_INTEGER`, `BU_CMD_LONG`, `BU_CMD_HEX_LONG`, and
`BU_CMD_CHAR` bind the same types to option storage. `BU_CMD_COUNTING_LONG_FLAG` is the long-counter
form for repeated flags, and `BU_CMD_VLS_APPEND` appends repeated text values
to a `bu_vls`, separating nonempty existing content with a space. These are
also the appropriate common readers and bindings for a command-owned record
assembled from several positional roles.
`BU_CMD_CHAR_VALIDATE` and `BU_CMD_VLS_APPEND_VALIDATE` attach a normal
side-effect-free validator to those storage forms. `BU_CMD_ISO639_1` uses the
latter with `bu_cmd_iso639_1_validate` to accept a lower-case ISO 639-1 code;
`BU_CMD_MAN_SECTION` uses `bu_cmd_man_section_validate` to accept one of the
BRL-CAD manual-page sections. Both validators reject input before altering
the command's storage, unlike the historical callback layering.
Use `bu_cmd_units_from_str` when execution needs the positive conversion
factor represented by a BRL-CAD unit expression such as `cm`, `in`, or
`25cm`; it leaves its destination unchanged on failure. `BU_CMD_UNITS`
binds a string-valued option with the corresponding
`bu_cmd_units_validate` preflight, so invalid units are rejected consistently
by completion, validation, and execution before a command applies its own
direction of conversion.
=== Canonical keyword values
Use a `bu_cmd_value_keyword` table when a keyword vocabulary needs stable
canonical spellings, accepted aliases, or per-value descriptions. Each row
contains a canonical spelling, an optional null-terminated alias list, and an
optional description. `BU_CMD_KEYWORD_VALUES` attaches such a table to a
keyword option; `BU_CMD_OPERAND_KEYWORD_VALUES` does the same for a positional
role.
Aliases are accepted during validation and parsing, but static completion
offers only the canonical spelling. For a keyword option, parsing also stores
the canonical spelling in its `const char *` field, so execution does not need
to duplicate alias normalization. JSON retains the compatible `values` array
of canonical spellings and adds `keyword_values`, whose entries include
`canonical`, `aliases`, and `description`. A string-valued role may publish
the same table as completion hints while a validator accepts a wider expression
grammar; in that case its original string is intentionally retained.
Native schema lint rejects an option or operand that mixes the legacy simple
keyword array with rich values, and rejects empty or duplicate canonical or
alias spellings.
=== Optional and shaped values
Every typed `BU_CMD_*` option takes one required scalar argument unless it is
a flag. Native schemas may instead declare `BU_CMD_ARG_OPTIONAL` or an
explicit `bu_cmd_arg_shape` using `BU_CMD_OPTION_SHAPED`. The shape records
the token range and one of `scalar`, `token_sequence`, `comma_list`,
`key_value_list`, `axis_keyed`, `range_pattern`, `rgb`, `color`, `vector3`,
or `custom`. It is emitted in JSON as `argument_requirement` and
`argument_shape`, so documentation and completion clients do not need a
separate mini-language table.
When a `comma_list` role also publishes static keyword values, completion
matches and replaces only the active list element. It retains all preceding
elements and preserves a leading `!` on that element, which supports sort
forms such as `name,!si` completing to `name,!size`. String or VLS-backed
roles may publish this vocabulary as completion guidance without rejecting
application-defined values such as attribute names.
An optional argument consumes zero or one following token; when supplied, it
is still checked as the option's declared value type. This deliberately
makes a command such as `make_name -s [num]` unambiguous: a following word is
the optional reset value and is rejected if it is not an integer, rather than
silently becoming a positional template.
For a multi-token shape, supply a `bu_cmd_value_consume_t` consumer. It
receives the complete selected token sequence and the address selected by the
option's `storage_offset`. With a null storage pointer it must perform only
side-effect-free validation; with storage it binds the execution value.
libbu therefore invokes the same shape parser for execution and incremental
validation. A multi-token shape without a consumer is rejected by native
schema lint.
A positional role whose value has a one-token mini-language may use
`BU_CMD_OPERAND_SHAPED`. Its shape is published as the operand's `shape` in
JSON and must describe exactly one token; the operand's normal cardinality
still determines how many such tokens the command accepts. For example, an
integer-or-inclusive-range operand can use `range_pattern` together with a
side-effect-free validator, making `100-200` and `100:200` visible as range
syntax without misrepresenting the role as a plain integer.
=== Declarative command relationships
Use a `bu_cmd_constraint` table for relationships that cannot be represented
by an individual option or positional role alone. The compact rows support
distinct-option counts (such as mutually exclusive modes) and conditional
operand counts (such as either `-f file` or exactly two object-name operands).
Options in a row are canonical names without dashes. `BU_CMD_CONSTRAINT_OPTIONS`
limits the number of selected options; `BU_CMD_CONSTRAINT_OPERANDS` applies an
operand range when any, none, or all of its named options are selected.
For new native schemas, attach all command-level properties with
`BU_CMD_SCHEMA_BOUND`. Its final four arguments are repeated groups,
constraints, a structural validator, and a context validator, so those
independent properties can be used together without positional tail macros:
[source,c]
----
static const char *mapping_file_option[] = {"f", NULL};
static const struct bu_cmd_constraint rename_constraints[] = {
BU_CMD_CONSTRAINT_OPERANDS(BU_CMD_CONDITION_ANY_OPTION_PRESENT,
mapping_file_option, 0, 0, "-f cannot be combined with object names"),
BU_CMD_CONSTRAINT_OPERANDS(BU_CMD_CONDITION_NO_OPTION_PRESENT,
mapping_file_option, 2, 2, "source and destination are required"),
BU_CMD_CONSTRAINT_NULL
};
static const struct bu_cmd_schema rename_schema =
BU_CMD_SCHEMA_BOUND("rename", "Rename objects", rename_options,
rename_operands, BU_CMD_PARSE_OPTIONS_FIRST, NULL,
rename_constraints, NULL, NULL);
----
libbu applies these rows to complete execution parsing and complete
incremental validation, and publishes them in generated help and JSON. They
therefore cannot silently disagree across parsing, validation, and completion.
For a genuinely command-specific side-effect-free syntax rule that cannot be
expressed as a constraint row, provide a validator in
`schema.validation.custom_validate`. The callback receives the token array
and cursor position and returns a normal `bu_cmd_validate_result`. It should
copy the schema, clear `flat.validation.custom_validate`, call
`bu_cmd_schema_validate` for the ordinary flat rules, then add only its
command-specific rule. `bu_cmd_schema_option_present`,
`bu_cmd_schema_operand_count`, and `bu_cmd_schema_option_span` expose the
parser's own alias-, cluster-,
shape-, and `--`-aware interpretation when such a rule depends on a selected
canonical option or the number of positional operands; do not duplicate an
option scanner in the command. Reserve non-flat languages for an explicit
grammar adapter.
When that additional rule needs host state--for example, a GED database lookup
to select primitive-specific operations--pass it as the final
`BU_CMD_SCHEMA_BOUND` argument and call `bu_cmd_schema_validate_ctx`. The callback receives an opaque context
pointer. It should copy the schema, clear
`flat.validation.constraint_data.context_validate`, and call
`bu_cmd_schema_validate` for the ordinary flat grammar before adding only the
context-dependent candidates or semantic checks. libbu itself never
interprets the context; command hosts choose when to provide it. This keeps
one native schema for execution, help, JSON, and completion without reviving
a parallel metadata table.
`BU_CMD_SCHEMA_EXTERNAL` is reserved for established commands whose executor
still owns option parsing. It explicitly permits `BU_CMD_*_UNBOUND` metadata
rows for help and completion; lint rejects such rows in a bound schema. New
commands should bind directly to an argument record. Native tables are
non-owning and must have static lifetime. `BU_CMD_ALIASES(...)` and
`BU_CMD_TREE(...)` shorten common tree declarations.
Positional roles use `BU_CMD_OPERAND`. Alongside their scalar type they may
carry an opaque semantic-provider identifier. libbu preserves that identifier
without depending on any application; GED uses identifiers such as
`ged.db_object` and `ged.db_path` to supply database-aware validation and
completion. A native schema therefore keeps its library-neutral core while
still describing application-specific operands precisely.
The compact parser is deliberately for flat option grammars. Commands with
subcommands, context-dependent expression languages, or nested commands
should publish an explicit syntax adapter instead of forcing that grammar into
option rows. Its execution parser preserves argv order for options-first and
stop-at-first-operand forms. For a flat interspersed-option command,
`bu_cmd_schema_parse` compacts recognized options and their arguments at the
front of the caller-owned argv pointer array, preserving positional operand
order in the remaining suffix; execution can therefore consume the same
native rows without a second option scanner. A schema-only option for such a
command uses
`BU_CMD_FLAG_UNBOUND`; it participates in help, validation, and completion but
deliberately refuses `bu_cmd_schema_parse`, which prevents a metadata table
from silently writing through an invented storage offset.
For conventional flat flag sets, the execution parser and validator accept a
compact short-option cluster when every member is a no-argument flag: `-ah`
has the same meaning as `-a -h`. Attached values and clusters containing an
option argument remain explicit, avoiding ambiguous getopt-style guessing.
An optionless schema treats ordinary leading-dash text as an operand, which
keeps raw commands such as `echo -literal` from inventing an option grammar.
For a schema with options, a dash-leading integer, long, hexadecimal long, or
finite-number token is likewise accepted as the next numeric positional role
(for example, `x -2`) without a preceding `--`; this narrow compatibility rule
does not apply to string or raw operands, so an unrecognized dash-leading
string is still reported as an option error. The standalone `--` marker
remains available to make every other operand phase explicit.
=== Native command trees
Use `bu_cmd_tree` when a command has a normal root option phase followed by
named subcommands. A tree root references its existing `bu_cmd_schema`; each
`bu_cmd_tree_node` references the existing schema for one child and may supply
its executor. The child name and help text come from that schema, so a tree
does not introduce a second option, help, or completion table. An optional
null-terminated alias list adds accepted child spellings without changing the
canonical child schema name.
`BU_CMD_TREE_NODE` and `BU_CMD_TREE_NODE_NULL` keep static declarations
compact. Set the root or node child phase to
`BU_CMD_TREE_CHILD_AFTER_OPTIONS` when the subcommand follows the parent's
option phase, or `BU_CMD_TREE_CHILD_FIRST` when it is the first parent
argument. Use `BU_CMD_TREE_CHILD_AFTER_FIXED_OPERANDS` for the common
`command [options] object subcommand` form: the child follows the parent's
fixed, scalar positional prefix. This phase deliberately rejects an
interspersed or variable-width root prefix, so the tree can identify the child
boundary without guessing whether a word is an operand or a subcommand. Nodes
may recursively reference further child arrays; a leaf node normally supplies
a `bu_cmd_tree_execute_t` callback. A grammar-only leaf may omit that callback
when its enclosing command owns execution dispatch.
`bu_cmd_tree_find_subcommand` resolves a direct canonical child or alias.
`bu_cmd_tree_dispatch` invokes that child's callback and reports dispatch
failure separately from the callback's command result. The generic
`bu_cmd_tree_describe`, `bu_cmd_tree_describe_json`, and `bu_cmd_tree_lint`
functions derive help, machine-readable structure, and duplicate-name/alias
checks from the same tree. A GED grammar adapter should use the tree for its
subcommand completion, child-schema validation, and analysis rather than
rebuilding a string list. `ged_cmd_tree_validate` and
`ged_cmd_tree_analyze`, declared by `ged/commands.h`, are the public adapter
entry points for an executable GED grammar. They recurse through nested node
arrays, preserving each child schema's option phase, operand validation, and
semantic token roles.
Some grammars have a parser-owned prefix before the reusable tree, such as an
object name followed by an operation. In that case use
`bu_cmd_tree_validate_argv` after the prefix has been recognized. Its `argv`
begins at the tree's root option/child phase (rather than at the root command
name), and it returns canonical child candidates, aliases, nested validation,
and `BU_CMD_EXPECT_SUBCOMMAND` exactly as `bu_cmd_tree_dispatch` would
interpret them. The prefix adapter remains responsible for adding its token
offset to the returned result and for any execution setup associated with the
prefix. This avoids maintaining a second hard-coded child vocabulary for
completion or help.
For an `AFTER_OPTIONS` root, a grammar adapter must find the child boundary
with `bu_cmd_schema_option_span`, not by searching for a word that happens to
match a child name. The function uses the schema's own option argument shape,
so a value such as `--view list` cannot be mistaken for a `list` subcommand.
=== GED registration
An ordinary GED command combines a `bu_opt` builder with positional and
constraint metadata in `ged_opt_spec`, then uses
`GED_DECLARE_COMMAND_SET_WITH_OPT_SPEC` and
`GED_DECLARE_PLUGIN_MANIFEST_WITH_OPT_SPEC`. Libged translates that compact
facade to its internal schema engine at registration. Commands with genuinely
advanced grammars use `GED_DECLARE_COMMAND_SET_WITH_NATIVE_SCHEMA` or
`GED_DECLARE_COMMAND_SET_WITH_GRAMMAR`. Plugin schema metadata is an internal
interface under active development, so a plugin must be rebuilt with matching
libged headers rather than relying on a compatibility adapter.
`GED_OPT` is the normal positional facade. For example,
`options-first file:file objects:object+` declares an output file followed by
one or more database objects. `?`, `*`, `+`, `{n}`, and `{min,max}` express
cardinality; `keyword(a|b)`, `int(min:max)`, and the positive/nonnegative
integer and number types cover common value domains. A semantic provider may
follow a type as `@provider.name`. This text is parsed once at command
registration and the resulting native schema is retained for all subsequent
validation and completion operations.
Once registered, native schemas participate in `ged_cmd_schema_json`,
`ged_cmd_validate`, `ged_cmd_complete_result`, `ged_cmd_analyze`, and
`ged_cmd_schema_lint`. This makes application frontends such as GSH, MGED,
and QGED consume the same command metadata without owning separate option
tables.
=== RGB command values
libbu provides one strict parser for ordinary 8-bit RGB command values.
`bu_rgb_from_argv` accepts a packed integer triple written as `r/g/b`,
`r,g,b`, `r;g;b`, or `r g b`, or it accepts three separate argument tokens
(`r g b`). Whitespace around a packed delimiter is accepted. Every channel
is a base-ten integer from 0 through 255; mixed packed delimiters, partial
values, decimal values, and trailing text are rejected. On success the
function reports whether it consumed one packed token or three channel tokens.
Use `bu_rgb_channel_validate` for command grammars that explicitly expose
three separate `red`, `green`, and `blue` operands. The legacy
`bu_opt_color` reader delegates integer RGB parsing to this API while retaining
its established packed hexadecimal and normalized floating-point compatibility
forms for external callers.
For a native command option bound to a `struct bu_color` field, use
`BU_CMD_RGB`. It publishes the standard `rgb` argument shape and accepts both
the one-token and three-token forms. Its parser determines the actual token
boundary: a packed color consumes one token and leaves the following operand
alone, while three separate channels are consumed together. `BU_CMD_COLOR`
is the scalar packed-color form when a command intentionally accepts the
broader `bu_color_from_str` syntax instead.
`BU_CMD_COLOR_COMPAT` is the one-or-three-token native replacement for the
full `bu_opt_color` value grammar. It accepts every one-token
`bu_color_from_str` spelling (including hexadecimal and normalized
floating-point triples) and also three separate RGB components. It publishes
the `color` shape, so a packed value preserves the following operand while an
unfinished numeric triple is reported as incomplete. Prefer `BU_CMD_RGB` for
new 8-bit command colors; use this compatibility form only when a migrated
command intentionally retains the broader legacy grammar.
For a positional query-or-set color rather than an option binding, use
`bu_cmd_rgb_optional_validate` for strict 8-bit RGB or
`bu_cmd_color_optional_validate` for the compatibility grammar. Both accept
zero arguments as a query, one packed value, or three separate components;
they classify a valid unfinished component sequence as incomplete. After a
successful validation, `bu_cmd_color_from_argv` converts the accepted one- or
three-token group without a second local color parser.
New command implementations must use these native helpers rather than
reintroducing `sscanf`, `strtol`, delimiter checks, range clamps, or bespoke
RGB completion validators.
=== Three-component vector command values
For an ordinary finite XYZ point or vector, `bu_cmd_vector3_from_argv`
accepts the corresponding packed forms `x/y/z`, `x,y,z`, and `x;y;z`, a
single quoted `x y z` argument, or three separate numeric arguments. All
components use the native finite-number grammar, so partial values, nonfinite
values, and trailing text are rejected. It reports one or three consumed
tokens and does not alter the output vector on failure.
Use `BU_CMD_VECTOR3` for a native option bound to a `point_t` or `vect_t`
field. Its published `vector3` shape lets the parser preserve the operand
boundary after a packed or quoted vector, consume three separate components
when supplied, and classify an unfinished separate vector as incomplete for
completion. New command implementations should use this shared reader and
shape instead of `sscanf` or command-local XYZ token scans.
For a common _count x y z_ form, use
`bu_cmd_counted_vector3_from_argv` and
`bu_cmd_counted_vector3_arg_shape`. They accept an integer count followed by
either one packed vector or three separate components, consuming two or four
tokens. The reader keeps the count and vector as separate outputs so a
command-specific consumer can bind them to its own record without duplicating
the token-selection or finite-number grammar.
For positional query/set triples, `bu_cmd_vector3_optional_validate` accepts
zero or one/three vector words; `bu_cmd_vector3_required_validate` is the
set-only form. `bu_cmd_integer_pair_optional_validate` provides the matching
zero-or-two integer pattern. Commands with a domain range (for example,
nonnegative screen coordinates) add the appropriate shared scalar validator
instead of replacing these cardinality helpers with another argv scan.
=== Expression languages
Some commands have a grammar that is not a flat option list. For example,
the parser-owned find-style vocabulary of `db_search` is available through
`db_search_syntax_terms` in `rt/search.h`. Its terms report argument kinds
such as ordinary strings, integers, primitive types, and variadic `-exec`
commands. Completion clients should use that exported view rather than copy
the `db_search` parser table. `db_search_syntax_plan_start` and
`db_search_syntax_exec_substitution` expose the parser's boundary and `{}`
substitution rules for the same reason.
GED registers such a command with a `ged_cmd_grammar` adapter rather than
inventing flat option rows. The adapter supplies cursor-aware validation,
whole-line token analysis, JSON description, and lint hooks; the command's
ordinary GED execution callback remains responsible for execution. Its JSON
uses `kind: grammar_adapter` and must describe parser-owned terms from the
same vocabulary used by execution. Consequently GSH, MGED, and QGED invoke
the same adapter through the normal GED completion and analysis APIs without
special-casing a command name.
+42
View File
@@ -54,6 +54,48 @@ structures and function signatures -- is defined in _raytrace.h_ and the
headers in the _rt/_ subdirectory, and is documented in the
Doxygen-generated reference for the LIBRT module.
== DATABASE PATH ENCODING
`db_full_path_encode()` and `db_full_path_decode()` convert between a
`struct db_full_path` and its unambiguous, variable-length text representation.
They are the appropriate APIs for text that will be saved, passed between
components, or interpreted again as a database path. `db_full_path_encode()`
replaces a caller-supplied `bu_vls` only after successful encoding;
`db_full_path_decode()` similarly replaces an initialized `db_full_path` only
after successful parsing and database validation. A failed call leaves its
output unchanged and returns a `db_full_path_status_t` error code without
logging a diagnostic for malformed user input.
The canonical representation begins with `/`. Unescaped `/` separates
directory entries; literal `/`, `\`, and `@` bytes in an entry name are written
as `\/`, `\\`, and `\@`, respectively. A non-root combination member with a
nonzero instance number is written as an unescaped zero-based `@N` suffix. For
example:
[source,text]
----
/assembly/bolt.s
/name\/with\/slashes
/assembly/member\@name
/repeat.c/bolt.s@1
----
`/all.g/child.s` is therefore a hierarchy, whereas `/all.g\/` is the
single root-level object named `all.g/`. Empty interior components, a trailing
unescaped slash, dangling or unsupported escapes, and malformed instance
suffixes are rejected. Decoding also verifies that every entry exists and
that each child is actually a member of the preceding combination. Boolean
operation values are reconstructed from the combination tree; they are not
part of the textual representation.
The older `db_path_to_string()`, `db_path_to_vls()`, and
`db_string_to_path()` functions retain the historical raw slash-separated
presentation for API compatibility. They cannot faithfully distinguish a
literal slash, backslash, or instance-like `@` suffix from path syntax, and
new code needing a round trip must use `db_full_path_encode()` and
`db_full_path_decode()` instead. Use the legacy functions only at deliberate
compatibility boundaries where their established raw presentation is required.
[[warning]]
== WARNING
+2
View File
@@ -2,6 +2,7 @@ if(BRLCAD_EXTRADOCS)
add_asciidoc("MAN5" STEP.adoc man5 "" REQUIRED "step-g")
add_asciidoc("MAN5" attributes.adoc man5 "" REQUIRED "librt")
add_asciidoc("MAN5" benchmark.adoc man5 "" REQUIRED "benchmark")
add_asciidoc("MAN5" brlcad-completion.adoc man5 "" REQUIRED "libged")
add_asciidoc("MAN5" bw.adoc man5 "" REQUIRED "libicv")
add_asciidoc("MAN5" cmap.adoc man5 "" REQUIRED "libdm")
add_asciidoc("MAN5" dpix.adoc man5 "" REQUIRED "libicv")
@@ -17,6 +18,7 @@ cmakefiles(
STEP.adoc
attributes.adoc
benchmark.adoc
brlcad-completion.adoc
bw.adoc
cmap.adoc
dpix.adoc
@@ -0,0 +1,308 @@
= BRLCAD-COMPLETION(5)
:doctype: manpage
:mansource: BRL-CAD
:manmanual: BRL-CAD User Configuration
== NAME
brlcad-completion - configure BRL-CAD command prompt completion behavior
== SYNOPSIS
[source,sh]
----
BRLCAD_COMPLETION_MODE=filter|cycle|prefix|legacy|off
BRLCAD_GSH_COMPLETION_MODE=mode
BRLCAD_MGED_COMPLETION_MODE=mode
BRLCAD_QGED_COMPLETION_MODE=mode
----
== DESCRIPTION
The interactive command prompts in *gsh*(1), *mged*(1), and QGED obtain
context-sensitive completion candidates from LIBGED. Candidate generation is
independent of presentation: the command schema determines which candidates
are valid, while the command prompt's completion mode determines how pressing
Tab previews and accepts those candidates.
The default mode is *filter*. Mode names are case-insensitive.
== MODES
*filter*::
Tab previews the first matching candidate and subsequent Tab presses cycle
through the remaining matches. The preview does not replace the user's
original seed until it is accepted. Typing a printable non-space character
discards the preview, applies the character to the original seed, and starts
the next completion cycle from that refined seed. If the refined seed has
no matches but appending the character to the displayed candidate does, the
candidate is accepted and edited instead. When both interpretations have
matches, refining the original seed takes precedence. Space accepts the
preview and begins the next command argument. Slash accepts a completed
database path component and begins the next component. This is the default.
*cycle*::
Tab previews and cycles through candidates. Editing input accepts the
displayed candidate and continues from it. This resembles Readline menu
completion and PowerShell's TabCompleteNext behavior.
*prefix*::
Tab inserts the longest prefix shared by all matching candidates. A later
Tab request operates on that more-specific seed. This resembles traditional
shell completion.
*legacy*::
Preserve the historical completion interaction of the selected frontend.
The exact presentation may differ between GSH, MGED, and QGED.
*off*::
Disable context-sensitive command completion. This does not disable command
parsing, validation, or execution.
== KEYS
In *filter* and *cycle* modes, Tab selects the next candidate and Shift-Tab
selects the previous candidate when the frontend and terminal can distinguish
Shift-Tab. Selection wraps at either end of the candidate list. Space accepts
the displayed candidate and inserts an argument separator. Escape cancels an
active filtering preview and restores the original seed. Backspace in
filtering mode removes one visible character from the candidate and confirms
the text that remains. This matches ordinary editable-buffer behavior; use
Escape to discard the whole candidate and restore the original seed.
Characters supplied by the selected candidate but not yet confirmed by the
user are drawn with a dimmer foreground than the typed seed. The dim suffix is
presentation only: it is removed when the candidate is accepted, cancelled, or
refined, and it is never added to command text sent to LIBGED. Terminal GSH
honors *NO_COLOR* and terminal color capability detection, so its dim rendering
is suppressed when styled output is disabled.
== CANDIDATE DISPLAY
GSH, MGED, and QGED show the candidate set without inserting it into the
command or command-history text. The display remains available while Tab and
Shift-Tab cycle through inline previews, then is removed when completion is
accepted, cancelled, or refined. No frontend asks for confirmation before
displaying a large set.
When every candidate fits within the frontend's available row budget, the
complete set is arranged in columns. A larger set is summarized using the
most specific complete prefix frontier that fits within that budget, for
example:
[source,text]
----
aab (3) aac (20) d5m (300)
----
The parenthesized number in this compact multi-row form is the number of
matching candidates in that prefix bin. A long unique candidate may initially
use its shortest branch prefix, such as `B (1)`, when spelling out its full
name would prevent the complete frontier from fitting.
If even one bin for every broad prefix cannot fit within the available rows,
the display falls back to one row containing the most informative
non-overlapping bins and ends with `... (N more)` so the omitted candidate
count remains explicit.
The binning is presentation only. Tab still visits the individual candidates
in their original order. GSH, MGED, and QGED derive their row budget from the
current console height. They reserve the input row (or rows, for wrapped QGED
input) and at least one third of the viewport for prior output, allowing
candidates to use the remaining space, up to two thirds. The input scrolls
upward only when the candidate rows need room.
The MGED Tk and QGED consoles insert transient, styled candidate rows into the
console text itself while keeping those rows outside the command and history
buffers. Classic MGED and GSH draw the same rows below their terminal input
lines. All presentations erase the rows before the next edit and recompute
their column layout and row budget when the console is resized. These visual
differences do not change the mode semantics. QGED's legacy mode retains its
historical completion popup.
== DATABASE PATH SPELLING
Completion and semantic validation use LIBRT's unambiguous database-path
spelling. A slash separates hierarchy components. A literal slash,
backslash, or at-sign in an object name is written `\/`, `\\`, or `\@`.
A nonzero repeated-member instance is written as `@N` after a component.
[source,text]
----
/assembly/bolt.s hierarchy: assembly contains bolt.s
/all.g\/ one object whose name is all.g/
/assembly/member\@name object name containing @
/repeat.c/bolt.s@1 second instance of bolt.s in repeat.c
----
This distinction matters when both a combination named `all.g` and an object
named `all.g/` exist: `/all.g/child.s` addresses the child of the combination,
while `/all.g\/` addresses the object with the trailing slash in its name.
An unescaped trailing slash is not a complete path.
The examples above show the string received by LIBGED. The command prompt
may consume a backslash while forming an argument. In GSH and QGED, type a
double backslash for each database-path escape, for example
`draw /all.g\\/`. In MGED, use a braced Tcl word to preserve the database
escape, for example `draw {/all.g\/}`; in a Tcl double-quoted word, double the
backslash instead. Programmatic callers of `db_full_path_decode()` supply the
single-backslash spelling shown in the examples.
== LINE-EDITOR COLORS
GSH, MGED, and QGED share an optional semantic line-editor palette. It
controls command-line feedback only; it does not replace QGED's application
theme or MGED's display and color-scheme settings. Roles omitted from the
file inherit each frontend's accessible dark- or light-theme defaults.
By default, BRL-CAD reads
_$XDG_CONFIG_HOME/brlcad/lineedit.json_ when *XDG_CONFIG_HOME* is set, or
_.config/brlcad/lineedit.json_ beneath the BRL-CAD user configuration
directory otherwise. Set *BRLCAD_LINEEDIT_COLORS* to an explicit file to use
another palette. Set it to *off* or *none* to suppress user palette loading.
The palette is read as each frontend starts; restart a frontend after editing
the file.
The file is a JSON object with version 1 and a *colors* object. The available
roles are *command*, *option*, *valid*, *invalid*, *incomplete*, and
*completion-preview*. The underscore spelling *completion_preview* is also
accepted. A role can be a three- or six-digit RGB hexadecimal value, or an
object with *color* and *style* members. *style* is *dim* or *normal*;
*dim* may also be a Boolean. A completion preview is dim by default.
[source,json]
----
{
"version": 1,
"colors": {
"command": "#75b7ff",
"option": "#e9ca4e",
"valid": "#48d7d7",
"invalid": "#ff6969",
"incomplete": "#e178e1",
"completion-preview": { "color": "#a0a0a0", "style": "dim" }
}
}
----
Use *"default"* or *"inherit"* as a role's color to return that role to the
frontend default. Unknown role names are ignored for forward compatibility.
An invalid value for a recognized role rejects the file as a whole, leaves the
defaults in effect, and produces one startup warning. GSH maps configured
colors to ANSI terminal styling and continues to honor *NO_COLOR*; exact
terminal color fidelity depends on the terminal's color support. MGED applies
the same palette to its Tk command prompt, including a blended dim preview,
and QGED applies it to its console editor.
== SEMANTIC FEEDBACK
GSH, MGED, and QGED use the same LIBGED command schemas that supply completion
candidates to color command names, options, and semantically checked arguments.
Invalid and incomplete tokens are distinguished from recognized syntax. This
feedback is advisory; command execution remains authoritative.
Within a *search -exec* expression, the prompts treat the words following
*-exec* as an embedded GED command. The embedded command name, its
command-specific options and arguments, `{}` result substitutions, and the
required standalone `;` terminator are checked independently. Parsing resumes
as a search expression after the terminator, allowing subsequent search
operators to be checked normally. Tab completion likewise follows the
embedded command's schema.
Quoted forms such as `"{}"` and `";"` are interpreted with GSH's argv quoting
rules before semantic checking, matching what GSH and QGED pass to *search*.
MGED instead parses Tcl syntax before consulting LIBGED: quoted `"{}"` is a
literal result substitution, braced `{}` is an empty Tcl word, and a bare `;`
ends the outer Tcl command. Words containing Tcl variable or command
substitutions are left unclassified until runtime. When MGED object-name
globbing may rewrite a word, that word and subsequent arguments are shown as
pending rather than being given potentially incorrect validation.
== CONSISTENCY CHECKS
BRL-CAD's automated tests audit completion as a contract rather than checking
only a hand-written set of command lines. The registry-wide audit walks every
discoverable command and subcommand schema in both legacy and new-command
modes. Each offered option is inserted using its reported replacement range
and analyzed again. Static option-argument candidates are checked in both
the _--option value_ and _--option=value_ forms.
A second audit mines command examples from the AsciiDoc manual pages. It
checks every prefix and replacement range it can construct, then reparses each
completed command fragment. A candidate that becomes an unknown or invalid
token is a test failure. These checks are intentionally complementary: the
registry audit covers schemas that are absent from examples, while the manual
corpus exercises realistic argument order and database paths.
Canonical aliases are suggested only when the schema can parse the canonical
spelling. Commands with context-dependent syntax also revalidate each option
candidate before it is returned, preventing a frontend or compatibility mode
from advertising an option that its active validator rejects.
== CONFIGURATION
*BRLCAD_COMPLETION_MODE* sets the default for all supporting BRL-CAD command
prompts. The frontend-specific environment variables override the global
variable for one application:
* *BRLCAD_GSH_COMPLETION_MODE*
* *BRLCAD_MGED_COMPLETION_MODE*
* *BRLCAD_QGED_COMPLETION_MODE*
GSH also accepts *--completion-mode=mode*. Its command-line option has highest
precedence, followed by the GSH-specific environment variable, the global
environment variable, and finally the *filter* default.
MGED users may set the following in _.mgedrc_. The _.mgedrc_ value has
precedence over environment variables and is preserved by MGED's Save Settings
operation:
[source,tcl]
----
set mged_default(completion_mode) filter
----
QGED provides an exclusive Completion menu. A choice made there is stored in
QGED's user settings and has precedence over environment variables on later
runs. Delete or change the saved setting to return control to the environment.
Invalid environment or saved-setting values are ignored. An invalid explicit
GSH *--completion-mode* argument is reported as an error.
== EXAMPLES
.Use filtering completion in every BRL-CAD prompt
====
[source,sh]
----
export BRLCAD_COMPLETION_MODE=filter
----
====
.Use cycling completion only in MGED
====
[source,sh]
----
export BRLCAD_COMPLETION_MODE=filter
export BRLCAD_MGED_COMPLETION_MODE=cycle
----
====
.Temporarily start GSH with common-prefix completion
====
[source,sh]
----
gsh --completion-mode=prefix model.g
----
====
== SEE ALSO
*gsh*(1), *mged*(1)
== AUTHOR
BRL-CAD Team
== COPYRIGHT
This software is Copyright (c) 1989-2026 by the United States Government as represented by U.S. Army Research Laboratory.
+4
View File
@@ -141,6 +141,7 @@ set(
garbage_collect.adoc
gdiff.adoc
get.adoc
get_bot_edges.adoc
glob.adoc
gqa.adoc
gr.adoc
@@ -306,6 +307,7 @@ set(
reid.adoc
release.adoc
relos.adoc
reopen.adoc
remat.adoc
repair.adoc
rfarb.adoc
@@ -381,6 +383,8 @@ set(
view2model_lu.adoc
view2model_vec.adoc
view_func.adoc
view_obj_axes.adoc
view_obj_polygon.adoc
viewdir.adoc
viewsize.adoc
vnirt.adoc
+14 -14
View File
@@ -17,7 +17,7 @@ adc [-i] subcommand
[[description]]
== DESCRIPTION
This command controls the angle/distance cursor. The *adc* command with no arguments toggles the display of the angle/distance cursor (ADC). The _-i_ option, if specified, causes the given value(s) to be treated as increments. Note that the _-i_ option is ignored when getting values or when used with subcommands where this option makes no sense. You can also control the position, angles, and radius of the ADC using a knob or the knob command. This command accepts the following subcommands:
This command controls the angle/distance cursor. A subcommand is required. The _-i_ option, if specified before the subcommand, causes applicable value-setting operations to treat their values as increments. It is ignored by query and reset operations. You can also control the position, angles, and radius of the ADC using a knob or the knob command. This command accepts the following subcommands:
*vars*::
@@ -36,20 +36,20 @@ Set or get angle1 in degrees.
Set or get angle2 in degrees.
*dist [distance]*::
*dst [distance]*::
Set or get radius (distance) of tick in local units.
*odist [distance]*::
*odst [distance]*::
Set or get radius (distance) of tick (+-2047).
*hv [position]*::
Set or get position (grid coordinates and local units).
*hv [horizontal vertical]*::
Set or get position using exactly two grid-coordinate values in local units.
*xyz [position]*::
Set or get position (model coordinates and local units).
*xyz [x y z]*::
Set or get position using exactly three model-coordinate values in local units.
*x [xpos]*::
@@ -80,8 +80,8 @@ Add to _y_ position (model coordinates and local units).
Add to _z_ position (model coordinates and local units).
*anchor_pos [0|1]*::
Anchor ADC to current position in model coordinates.
*anchor_pos [0|1|2]*::
Set or get position anchoring: 0 is free, 1 anchors to model coordinates, and 2 anchors to grid coordinates.
*anchor_a1 [0|1]*::
@@ -96,16 +96,16 @@ Anchor angle2 to go through anchorpoint_a2.
Anchor tick distance to go through anchorpoint_dst.
*anchorpoint_a1[x y z]*::
Set or get anchor point for angle1 (model coordinates and local units).
*anchorpoint_a1 [x y z]*::
Set or get anchor point for angle1 using exactly three model-coordinate values in local units.
*anchorpoint_a2 [x y z]*::
Set or get anchor point for angle2 (model coordinates and local units).
Set or get anchor point for angle2 using exactly three model-coordinate values in local units.
*anchorpoint_dst [x y z]*::
Set or get anchor point for tick distance (model coordinates and local units).
Set or get anchor point for tick distance using exactly three model-coordinate values in local units.
*reset*::
@@ -144,7 +144,7 @@ Sets angle1 to 37.5 degrees.
.Get angle1
[example]
====
mged> **adc a1 37.5**
mged> **adc a1**
Gets angle1.
+17 -7
View File
@@ -16,25 +16,25 @@ analyze [options] [subcommand] [subcmd_options]...
[source]
----
summarize {obj1 [...]}
analyze [options] summarize obj1 [obj2 ...]
----
[source]
----
intersect [-o output_obj] [-h] {obj1 obj2 [...]}
analyze [options] intersect [-o output_obj] obj1 obj2 [obj3 ...]
----
[source]
----
subtract [-o output_obj] [-h] {obj1 obj2 [...]}
analyze [options] subtract [-o output_obj] obj1 obj2 [obj3 ...]
----
[source]
----
inside {obj1} {x} {y} {z}
analyze [options] inside obj x y z
----
@@ -46,14 +46,19 @@ generation capabilities. The classic behavior (and the behavior users
will see if calling without specifying a subcommand) is a report
summarizing geometric information about the specified solid(s). This
behavior may also be explicitly invoked by the *summarize* subcommand.
Thus, *analyze obj1 [obj2 ...]* is equivalent to
*analyze summarize obj1 [obj2 ...]*. The top-level options precede either
the explicit subcommand or the first object in this shorthand form.
The *inside* subcommand will take an object and the x y z coordinates
of a point, and report whether the point is inside or outside the
object in question (returning 1 if inside and 0 otherwise.)
object in question (returning 1 if inside and 0 otherwise.) The point may
be supplied as three coordinate arguments or as one packed XYZ value using
the standard BRL-CAD slash, comma, or semicolon separators.
The *intersect* subcommand will take the first object specified and
intersect it with any subsequently specified objects - in effect,
building up a new object with the geoemtry common to all objects
building up a new object with the geometry common to all objects
specified.
The *subtract* subcommand will take the first object specified and
@@ -69,6 +74,11 @@ Print help.
*-v*, *--verbose*::
Increase reporting verbosity for the top-level analyze reporting mode.
The *-h*/*--help* option is also accepted by each explicit subcommand. The
*-o*/*--output* option of *intersect* and *subtract* names the object to
receive the Boolean result; it may appear before, between, or after object
operands.
[[examples]]
== EXAMPLES
@@ -254,7 +264,7 @@ point#, (point)
....
mged>**analyze subtract -o outside.s pnts.s sph**
mged>**analyze subtract -o outside.s pnts.s sph.s**
....
+2 -2
View File
@@ -10,14 +10,14 @@ bev - Performs the operations indicated in the __Boolean_formula__ and stores th
[source]
----
bev [-t] [-P#] {new_obj} {Boolean_formula}
bev [-t] {new_obj} {Boolean_formula}
----
[[description]]
== DESCRIPTION
Performs the operations indicated in the __Boolean_formula__ and stores the result in __new_obj__. The __new_obj__ will be stored as an NMG shape (it may be converted to a polysolid by using the *nmg_simplify* command). If the -t option is specified, then the resulting object will consist entirely of triangular facets. The default is to allow facets of any complexity, including holes. The _-P_ option specifies the number of CPUs to use for the calculation (however, this is currently ignored). Only simple __Boolean_formulas__ are allowed. No parentheses are allowed and the operations are performed from left to right with no precedence. More complex expressions must be expressed as BRL-CAD objects using the *r*, *g*, or *c* commands and evaluated using the *facetize* or *ev* commands.
Performs the operations indicated in the __Boolean_formula__ and stores the result in __new_obj__. The __new_obj__ will be stored as an NMG shape (it may be converted to a polysolid by using the *nmg_simplify* command). If the -t option is specified, then the resulting object will consist entirely of triangular facets. The default is to allow facets of any complexity, including holes. Only simple __Boolean_formulas__ are allowed. No parentheses are allowed and the operations are performed from left to right with no precedence. More complex expressions must be expressed as BRL-CAD objects using the *r*, *g*, or *c* commands and evaluated using the *facetize* or *ev* commands.
[[examples]]
+4 -2
View File
@@ -21,8 +21,10 @@ The *E* command draws one or more objects using Boolean evaluation. Unlike *draw
=== Options
*-C r/g/b*::
Override the display color for all drawn objects using the specified RGB values (each 0–255), separated by `/`.
*-C* _r/g/b_::
Override the display color for all drawn objects with 8-bit RGB values.
Specify the channels as `r/g/b`, `r,g,b`, `r;g;b`, or as three separate
arguments. Each channel must be in the range 0–255.
*-s*::
Enable shading on the evaluated result display.
+1 -1
View File
@@ -26,7 +26,7 @@ At least one object name must be provided.
=== Options
*-C r/g/b*::
*-C* _r/g/b_::
Override the display color for all drawn objects using the specified RGB triple (each 0–255), separated by `/`. This overrides any color assigned to the objects in the database.
[[examples]]
+128 -31
View File
@@ -10,14 +10,14 @@ bot - Perform operations on a Bag of Triangles (BoT) primitive.
[source]
----
bot [-v] [-V] [-C [0-255|0-255|0-255]] {subcommand} {subcommand arguments}
bot [-h] [-v] [-V] [-C r/g/b] {subcommand} {subcommand arguments}
----
[source]
----
check {degen_faces | extra_edges | flipped_edges | open_edges | solid} {objname}
check [{degen_faces | extra_edges | flipped_edges | manifold | open_edges | solid}] {objname}
----
@@ -31,14 +31,21 @@ chull {input_bot} {output_bot}
[source]
----
decimate [-f #] [-e #] {input_bot} {output_bot}
decimate [--help] [-c error] [-n error] [-e length] [-f size] [-t tolerance] {input_bot} [output_bot]
----
[source]
----
extrude {input_bot} {output_bot}
dump [--help] [-b] [-n] [-F] [-m directory | -o file] [-t dxf|glb|gltf|obj|sat|stl] [-u units] [--materials | --no-materials] [{input_bot} ...]
----
[source]
----
extrude [--help] [-q] [-R] [-F] [-i | -C] [--max-area-delta ratio] [--min-tri-delta ratio] {input_bot} [output_name]
----
@@ -52,7 +59,7 @@ flip {objname}
[source]
----
get {faces | minEdge | maxEdge | orientation | type | vertices} {objname}
get {faces | minEdge | maxEdge | orientation | type | thickness | vertices} {objname}
----
@@ -66,21 +73,42 @@ isect {objname} {objname2}
[source]
----
remesh {input_bot} {output_bot}
info {objname} [F | V] [index_or_range ...]
----
[source]
----
set {orientation | type} {objname} {value}
pick {objname} {E | F | V} [--first] [px py pz dx dy dz]
----
[source]
----
smooth [-c [0|1|2]] [-d [0|1|2]] [-e #] [-E #] [-I #] {input_bot} {output_bot}
remesh [--help] [--vdb] [-o output_name] {input_bot} [output_name]
----
[source]
----
repair [--help] [-p percent] [-a area] [-o output_name] {input_bot} [{input_bot} ...]
----
[source]
----
set {orientation | type | thickness} {objname} {value}
----
[source]
----
smooth [--help] [-c [0|1|2]] [-d [0|1|2]] [-e error] [-E error] [-I positive_integer] {input_bot} [output_bot]
----
@@ -101,7 +129,7 @@ stat {objname}
[source]
----
subd [-A [1|2|3|4|5]] [-l #] {input_bot} {output_bot}
subd [--help] [-A [1|2|3|4|5]] [-l positive_integer] {input_bot} [output_bot]
----
@@ -134,6 +162,8 @@ Visualize results when supported by the selected subcommand.
*-C* _r/g/b_, *--color* _r/g/b_::
Set the RGB plotting color used by visualization-oriented subcommands.
The color may be written as _r/g/b_, _r,g,b_, _r;g;b_, or as three separate
values (_r g b_).
[[subcommands]]
@@ -141,7 +171,10 @@ Set the RGB plotting color used by visualization-oriented subcommands.
*check*::
Performs the requested check on the provided solid. Checks are __degen_faces__, __extra_edges__, __flipped_edges__, __open_edges__, or _solid_. The command will return a 1 (if the specified check finds an issue) or 0.
Performs a topology or geometry check on the provided BoT. With only an object
name, *solid* is the default check. The available checks are *degen_faces*,
*extra_edges*, *flipped_edges*, *manifold*, *open_edges*, and *solid*. The
command returns 1 when the selected check finds an issue and 0 otherwise.
*chull*::
@@ -149,21 +182,47 @@ Generates the BoT's convex hull and store it in an object.
*decimate*::
Decimates the BoT. The default error metric is Quadric.
Reduces the BoT triangle count. With no method option it uses GCT with its
default feature size. Use exactly one method family: GCT (`-f`), classical
decimation (`-c`, `-n`, and/or `-e`), or simple vertex merging (`-t`).
+
*-f #*::
Specifies the features size (implies use of GCT decimater)
*-c* _error_, *--max-cord-error* _error_::
Specifies the maximum chord error for classical decimation.
*-n* _error_, *--max-normal-error* _error_::
Specifies the maximum normal error for classical decimation.
*-e* _length_, *--min-edge-length* _length_::
Specifies the minimum edge length for classical decimation.
*-f* _size_, *--feature-size* _size_::
Specifies the GCT feature size.
*-t* _tolerance_, *--merge-tol* _tolerance_::
Specifies the simple-decimator vertex merge tolerance.
*-e #*::
Specifies the maximum allowed error introduced by decimation (OpenMesh).
*dump*::
Exports one or more BoTs to an external mesh file. With no object operands it
exports all BoTs in the database. Choose at most one of `-m`/`--output-directory`
and `-o`/`--output-file`, and at most one of `--materials` and
`--no-materials`. `-t` selects `dxf`, `glb`, `gltf`, `obj`, `sat`, or `stl`;
the format otherwise follows the output-file extension or defaults to STL.
`-u` accepts a BRL-CAD unit expression such as `mm`, `cm`, `in`, or `25cm`.
See *bot_dump*(nged) for format-specific details.
*extrude*::
Generates an ARB6 representation of the specified plate mode BoT object
Generates a volumetric BoT or, with `-C`/`--comb`, a CSG tree from the specified
plate-mode BoT. Normal volumetric output requires an output name unless
`-i`/`--in-place` is used. CSG output may omit its name and defaults to an
`_extrusion.r_` combination. `--in-place` and `--comb` are mutually exclusive.
The simplification ratios accepted by `--max-area-delta` and `--min-tri-delta`
are in the inclusive range 0 through 1.
*flip*::
@@ -171,7 +230,22 @@ Flips the BoT triangle normal directions (turns the BoT "inside out"). This will
*get*::
Returns the requested parameter of the provided BoT solid. Valid parameters are _faces_, _minEdge_, _maxEdge_, _orientation_, _type_, or _vertices_.
Returns the requested parameter of the provided BoT solid. Valid parameters are
_faces_, _minEdge_, _maxEdge_, _orientation_, _type_, _thickness_, or
_vertices_.
*info*::
Reports BoT summary counts when used with only an object name. Add `F` for face
information or `V` for vertex information, optionally followed by integer
indexes, ranges (`first-last` or `first:last`), or separated index lists.
*pick*::
Identifies the BoT edge (`E`), face (`F`), or vertex (`V`) nearest to the
current viewport ray, or to the explicit six-coordinate ray `px py pz dx dy
dz`. `--first` chooses the first comparable edge or vertex along the ray; it
is not valid with face picks.
*isect*::
@@ -179,35 +253,56 @@ Tests if the two provided BoTs intersect (work in progress).
*remesh*::
Creates a new meshed version of the provided object.
Creates a remeshed version of the provided BoT. If no output name is supplied,
the input BoT is replaced. Supply the output name either positionally or with
`-o`/`--output`, but not both. `--vdb` selects the OpenVDB implementation when
that optional build support is available.
*repair*::
Attempts to repair solid BoTs into manifold geometry. With no output option,
each input is repaired in place. `-o`/`--output-name` writes a repaired copy
and consequently requires exactly one input. `-p`/`--max-hole-percent` accepts
a percentage from 0 through 100; `-a`/`--max-hole-area` supplies a nonnegative
absolute limit in millimetres.
*set*::
Sets the specified property of the provided bot. Properties that can be set are _orientation_ and _type_. Potential values for _orientation_ are none (no), ccw (rh), or cw (lh). Potential values for _type_ are surface, solid, plate, or plate_nocos.
Sets the specified property of the provided BoT. Properties that can be set are
_orientation_, _type_, and _thickness_. Potential values for _orientation_ are
none (no), ccw (rh), or cw (lh). Potential values for _type_ are surface
(surf), solid (sol), plate, or plate_nocos; _mode_ is accepted as a
compatibility alias for _type_. Thickness applies only to plate-mode BoTs. Its
value is either one finite number for every face, or `face_index:number` to set
one face.
*smooth*::
Smooths the BoT using OpenMesh's Jacobi Laplace smoother.
Smooths the BoT using the Jacobi-Laplace smoother.
+
*-c [0|1|2]*::
Specifies the continuity. The default value is 0, meaning shape is continuous, but not the tangent. A value of 1 means the shape and tangent are continuous, and a value of 2 preserves curvature.
*-c* _[0|1|2]_, *--continuity* _[0|1|2]_::
Specifies continuity. The default is 1 (C1), where shape and tangent are
continuous. A value of 0 selects C0, and 2 selects C2 (which preserves the
input positions).
*-d [0|1|2]*::
Specifies the direction. The default is 0,smoothing in tangential direction. A value of 1 smooths in normal direction, and a value of 2 smooths in both tangential and normal directions.
*-d* _[0|1|2]_, *--direction* _[0|1|2]_::
Specifies the component direction. The default is 0, smoothing in the
tangential direction. A value of 1 smooths in the normal direction, and 2
smooths in both directions.
*-e #*::
*-e* _error_, *--max-local-error* _error_::
Specifies the max local error.
*-E #*::
*-E* _error_, *--max-abs-error* _error_::
Specifies the max absolute error.
*-I #*::
Specifies the iterations for smoothing.
*-I* _positive_integer_, *--iterations* _positive_integer_::
Specifies the positive number of smoothing iterations.
@@ -239,11 +334,13 @@ Returns information about the provided BoT.
Subdivides the provided BoT.
+
*-A [1|2|3|4|5]*::
Specifies the algorithm used to subdivide the BoT. The default is 1 which specifies the loop algorithm. A value of 2 specfies the sqrt3 algorithm, a value of 3 specifies the sqrt3 interpolating algorithm, a value of 4 specifies modified the butterfly algorithm, and a value of 5 specifies the midpoint alorithm.
*-A* _[1|2|3|4|5]_, *--algorithm* _[1|2|3|4|5]_::
Specifies the algorithm used to subdivide the BoT. The default is 1, the Loop
algorithm. A value of 2 selects Sqrt3, 3 selects interpolating Sqrt3, 4
selects modified Butterfly, and 5 selects Midpoint.
*-l #*::
*-l* _positive_integer_, *--level* _positive_integer_::
Specifies the level of subdivision refinement iterations. Note that the number of triangles generated grows _very_ rapidly with increasing iteration counts - it is recommended that users start with small refinements on the target bot to get a feel for the tradeoff between triangle count and smoothness.
+6 -1
View File
@@ -10,7 +10,7 @@ bot_condense - Used to eliminate unused vertices from a BOT primitive.
[source]
----
bot_condense {new_bot_primitive} {old_bot_primitive}
bot_condense [--help] {new_bot_primitive} {old_bot_primitive}
----
@@ -19,6 +19,11 @@ bot_condense {new_bot_primitive} {old_bot_primitive}
Used to eliminate unused vertices from a BOT primitive. It returns the number of vertices eliminated.
=== Options
*-h*, *--help*::
Print command help without opening a database.
[[examples]]
== EXAMPLES
+2 -2
View File
@@ -10,14 +10,14 @@ bot_decimate - Reduces the number of triangles in the __old_bot_primitive__ and
[source]
----
bot_decimate [-f feature_size] [-c maximum_chord_error] [-n maximum_normal_error] [-e minimum_edge_length] {new_bot_primitive} {old_bot_primitive}
bot_decimate [--help] [-f feature_size | [-c maximum_chord_error] [-n maximum_normal_error] [-e minimum_edge_length]] {new_bot_primitive} {old_bot_primitive}
----
[[description]]
== DESCRIPTION
Reduces the number of triangles in the __old_bot_primitive__ and saves the results to the __new_bot_primitive__. The reduction is accomplished through an edge decimation algorithm. Only changes that do not violate the specified constraints are performed. Specifying the __feature_size__ parameter will result in use of the new GCT decimator (this parameter is mutually exclusive with the other tolerances). The __maximum_chord_error__ parameter specifies the maximum distance allowed between the original surface and the surface of the new BOT primitive in the current editing units. The __maximum_normal_error__ specifies the maximum change in surface normal (degrees) between the old and new surfaces. The __minimum_edge_length__ specifies the length of the longest edge that will be decimated. At least one constraint must be supplied. If more than one constraint is specified, then only operations that satisfy all the constraints are performed.
Reduces the number of triangles in the __old_bot_primitive__ and saves the results to the __new_bot_primitive__. The reduction is accomplished through an edge decimation algorithm. Only changes that do not violate the specified constraints are performed. Specifying the __feature_size__ parameter selects the GCT decimator and is mutually exclusive with the other tolerances. Alternatively, specify one or more of __maximum_chord_error__, __maximum_normal_error__, and __minimum_edge_length__ to select the classical decimator. The chord-error parameter specifies the maximum distance allowed between the original surface and the surface of the new BOT primitive in the current editing units. The normal-error parameter specifies the maximum change in surface normal (degrees) between the old and new surfaces. The minimum-edge-length parameter specifies the length of the longest edge that will be decimated.
[[examples]]
+8 -5
View File
@@ -10,7 +10,7 @@ bot_dump - export Bag-of-Triangles (BOT) geometry to a mesh file format
[source]
----
bot_dump [-b] [-n|--normals] [-F|--full-precision]
bot_dump [--help] [-b] [-n|--normals] [-F|--full-precision]
[-m|--output-directory dir] [-o|--output-file file]
[-t dxf|glb|gltf|obj|sat|stl] [-u unit]
[--materials|--no-materials]
@@ -34,6 +34,9 @@ Output formats supported:
=== Options
*-h*, *--help*::
Print command help without opening a database.
*-b*::
Write output in binary format where supported (e.g., binary STL, binary glTF/GLB).
@@ -45,16 +48,16 @@ Write full floating-point precision for coordinate values where supported.
glTF and GLB require standard single-precision coordinates and reject
this option.
*-m dir*, *--output-directory dir*::
*-m*, *--output-directory* _dir_::
Write each BOT to a separate file in the specified directory `dir`. Mutually exclusive with `-o`.
*-o file*, *--output-file file*::
*-o*, *--output-file* _file_::
Write all output to the single specified `file`. Mutually exclusive with `-m`.
*-t fmt*::
*-t* _fmt_::
Specify the output format type. Accepted values: `dxf`, `glb`, `gltf`, `obj`, `sat`, `stl`. Default is `stl`.
*-u unit*::
*-u* _unit_::
Specify the output units for coordinate values (e.g., `mm`, `cm`, `in`, `ft`). Defaults to the database's native units.
*--materials*::
+5 -3
View File
@@ -11,15 +11,17 @@ bot_exterior - Reduce a BoT solid to only its exterior (outward-facing) faces.
[source]
----
bot exterior [options] {input_bot} [output_name]
bot_exterior [options] {input_bot} [output_name]
----
[[description]]
== DESCRIPTION
*bot exterior* analyses a closed solid, non-plate-mode BoT (Bag of Triangles)
mesh and removes every face that is not classified as exterior, retaining only
those triangles that belong to the exterior shell.
*bot exterior* (also available as the standalone *bot_exterior* command)
analyses a closed solid, non-plate-mode BoT (Bag of Triangles) mesh and
removes every face that is not classified as exterior, retaining only those
triangles that belong to the exterior shell.
=== Methods
+6 -1
View File
@@ -10,7 +10,7 @@ bot_face_fuse - Eliminates duplicate faces from a BOT solid.
[source]
----
bot_face_fuse {new_bot_primitive} {old_bot_primitive}
bot_face_fuse [--help] {new_bot_primitive} {old_bot_primitive}
----
@@ -19,6 +19,11 @@ bot_face_fuse {new_bot_primitive} {old_bot_primitive}
Eliminates duplicate faces from a BOT solid. It returns the number of faces eliminated.
=== Options
*-h*, *--help*::
Print command help without opening a database.
[[examples]]
== EXAMPLES
+8 -1
View File
@@ -10,7 +10,7 @@ bot_face_sort - Sorts the list of triangles that constitutes the BOT primitive t
[source]
----
bot_face_sort {triangles_per_piece} {bot_primitive1} [bot_primitive2 bot_primitive3]...
bot_face_sort [--help] triangles_per_piece bot_primitive1 [bot_primitive2 ...]
----
@@ -19,6 +19,13 @@ bot_face_sort {triangles_per_piece} {bot_primitive1} [bot_primitive2 bot_primiti
Used to sort the list of triangles that constitutes the BOT primitive to optimize it for raytracing with the specified number of triangles per piece. Most BRL-CAD primitives are treated as a single object when a model is being prepared for raytracing, but BOT primitives are normally broken into "pieces" to improve performance. The raytracer normally uses four triangles per piece.
`triangles_per_piece` must be a positive integer.
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
[[examples]]
== EXAMPLES
+6 -1
View File
@@ -10,7 +10,7 @@ bot_flip - Reverse (i.e. flip) all the facet normals within a BOT primitive.
[source]
----
bot_flip {bot} [bot2 bot3]...
bot_flip [--help] bot [bot2 ...]
----
@@ -21,6 +21,11 @@ Reverse (i.e. flip) all the facet normals within a BOT primitive. When viewing a
Note: using the *bot_flip* will toggle the orientation of right and left-handed BOT primitives. The orientation of unoriented BOT primitives will not change.
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
[[examples]]
== EXAMPLES
+6 -2
View File
@@ -10,7 +10,7 @@ bot_fuse - fuse duplicate vertices and faces in a BOT mesh
[source]
----
bot_fuse [-s|-p] new_bot old_bot
bot_fuse [--help] [-s | -p] new_bot old_bot
----
@@ -25,13 +25,17 @@ After fusing, open edges (edges shared by only one face) may be detected. The op
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
*-s*::
Show open edges by drawing them in the display as colored lines after the operation.
*-p*::
Plot open edges to a temporary plot file for subsequent inspection.
Without either flag, open edge detection runs silently and results are not visualized.
The `-s` and `-p` modes are mutually exclusive. Without either flag, open
edge detection runs silently and results are not visualized.
[[examples]]
== EXAMPLES
+6 -1
View File
@@ -10,7 +10,7 @@ bot_merge - merge multiple BOT meshes into a single BOT object
[source]
----
bot_merge bot_dest bot1_src [botn_src ...]
bot_merge [--help] bot_dest bot1_src [botn_src ...]
----
@@ -21,6 +21,11 @@ The *bot_merge* command combines two or more BOT (Bag-of-Triangles) primitive ob
At least one source BOT must be specified in addition to the destination name.
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
NOTE: *bot_merge* concatenates vertex lists without fusing shared vertices. If the input BOTs share vertices at the same position, those vertices will be duplicated in the result. Use *bot_fuse* afterward to merge duplicate vertices.
[[examples]]
+2 -2
View File
@@ -36,7 +36,7 @@ Note that this command will _not_ (currently) perform any work on plate mode or
== OPTIONS
*-a #*::
*-a* _#_::
Specify an absolute maximum area in mm for a hole size on which repair will be attempted. Unset by default. Overrides the *p* if specified.
@@ -44,7 +44,7 @@ Specify an absolute maximum area in mm for a hole size on which repair will be a
Print command help.
*-p #*::
*-p* _#_::
Specify the largest viable hole size for repair as a percentage (0-100) of the mesh area. By default the limit is set to 5 percent. 0 and 100 are interpreted as attempting to fill all holes, which may produce unexpected results. If the *a* is specified it overrides this option.
+5 -2
View File
@@ -10,7 +10,7 @@ bot_smooth - compute and store surface normals in a BOT mesh
[source]
----
bot_smooth [-t angle_tolerance] new_bot old_bot
bot_smooth [--help] [-t angle_tolerance] new_bot old_bot
----
@@ -25,7 +25,10 @@ NOTE: This command requires the database to be at the current version with suppo
=== Options
*-t angle_tolerance*::
*-h*, *--help*::
Print command help without requiring an open database.
*-t* _angle_tolerance_::
Maximum angle (in degrees) between adjacent face normals for them to be averaged together. Faces separated by a larger angle produce a hard edge in the normal map. Default is `180.0` (all faces smoothed together).
[[examples]]
+6 -1
View File
@@ -10,7 +10,7 @@ bot_split - Split a single BOT primitive, containing disjoint groups of facets,
[source]
----
bot_split {bot} [bot2 bot3]...
bot_split [--help] bot [bot2 ...]
----
@@ -33,6 +33,11 @@ are based on the original BOT name with an available sequential suffix. Object
attributes are copied to every result, and the result names are listed when
the command completes.
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
[[examples]]
== EXAMPLES
+6 -1
View File
@@ -10,7 +10,7 @@ bot_sync - Synchronizes the normals of all facets within a BOT primitive so they
[source]
----
bot_sync {bot} [bot2 bot3]...
bot_sync [--help] bot [bot2 ...]
----
@@ -19,6 +19,11 @@ bot_sync {bot} [bot2 bot3]...
Synchronizes the normals of all facets within a BOT primitive so they are all in the same direction. When viewing a BOT with the MGED 'e -m1' or 'draw -m1' command, if some of the exterior facets are black and some shaded (red by default), this indicates the black facets have their normal in the wrong direction. To correct this, it is recommended to first run the commands 'bot_vertex_fuse' then 'bot_face_fuse' followed by 'bot_sync'. If the result is all exterior facets are black, then use the MGED 'bot_flip' command to reverse (i.e. flip) all the BOT facet normals. The result should be all exterior facets become shaded.
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
[[examples]]
== EXAMPLES
@@ -10,14 +10,21 @@ bot_vertex_fuse - Used to eliminate duplicate vertices from a BOT solid.
[source]
----
bot_vertex_fuse {new_bot_solid} {old_bot_primitive>}
bot_vertex_fuse [--help] new_bot_solid old_bot_primitive
----
[[description]]
== DESCRIPTION
Used to eliminate duplicate vertices from a BOT solid. It returns the number of vertices eliminated. No tolerance is used, so the vertices must match exactly to be considered duplicates.
Used to eliminate duplicate vertices from a BOT solid. It returns the number of
vertices eliminated. Vertices within the database tolerance are considered
duplicates.
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
[[examples]]
+26 -3
View File
@@ -10,7 +10,7 @@ brep - The *brep* command is the primary means in BRL-CAD for working with NURBS
[source]
----
brep {obj} [bool | bot | bots | brep | csg | flip | info | intersect | pick | plate_mode | plot | selection | solid | split | shrink_surfaces | tikz | valid] [arguments]
brep [options] {obj} {bool | bot | bots | brep | csg | dump | flip | geo | info | intersect | pick | plate_mode | plot | repair | selection | solid | split | shrink_surfaces | tikz | topo | valid} [arguments]
----
@@ -71,6 +71,10 @@ Generates plotting output for the object using the TikZ plotting language. The o
*valid*::
Report if the BRep object is topologically valid.
*topo*::
Inspect or edit low-level BRep topology. This is primarily an advanced
diagnostic and construction interface.
== OPTIONS
*-h*, *--help*::
@@ -79,11 +83,30 @@ Print help for the selected *brep* subcommand.
*-v*, *--verbose*::
Increase reporting verbosity for subcommands that support additional diagnostic output.
*-C*, *--color* _r/g/b_::
*-C*, *--color* _color_::
Set the color used by subcommands that create plotted or highlighted output.
The value accepts the normal BRL-CAD color spellings, including packed
_r/g/b_, _r,g,b_, or _r;g;b_ values, three separate _r g b_ channel words,
and other scalar color forms accepted by `bu_color_from_str`.
*--plotres* _#_::
Set plotting resolution for subcommands that sample curves or surfaces for display output.
Set a positive plotting resolution for subcommands that sample curves or
surfaces for display output.
== SUBCOMMAND OPTIONS
*brep* _[--no-evaluation] [--suffix suffix] [output_name]_::
Convert the selected object to BRep form. `--no-evaluation` preserves a
combination as a CSG BRep tree instead of evaluating its booleans; `--suffix`
sets the naming suffix used for that form.
*split* _[-t thickness] [-o output_object] [-O] [face_indices...]_::
Create plate-mode BRep output. Face indices may be individual values, ranges,
or comma-, slash-, or semicolon-separated lists. `-O` writes one BRep object
per face; otherwise `-o` selects the combined output-object root.
*intersect* _other_object first_index second_index [PP|PC|PS|CC|CS|SS]_::
Calculate the requested component intersection. `SS` is the default mode.
== EXAMPLES
+17 -1
View File
@@ -10,7 +10,7 @@ brep plot - Plot specific components of brep objects in a 3D scene.
[source]
----
brep {obj}plot [C2|C3|E|F|F2d|FSBB|FSBB2d|FTBB|FTBB2d|FTD|I|L|L2d|S|SCV|SK|SK2d|SN|SUV|SUVP|T|T2d|V|CDT|CDT2d|CDTw] [arguments]
brep {obj} plot [C2|C3|E|F|F2d|FSBB|FSBB2d|FTBB|FTBB2d|FTD|I|L|L2d|S|SCV|SK|SK2d|SN|SUV|SUVP|T|T2d|V|CDT|CDT2d|CDTm2d|CDTp2d|CDTw|CDTn|CDTn2d|CDTnw] [indices ...]
----
@@ -21,6 +21,22 @@ If _obj_ is not a brep object, then report that fact and exit. Otherwise, genera
This command has quite a few subcommands, as it is the primary means in BRL-CAD for visually inspecting properties of BRep objects:
The optional index arguments select components of the collection associated
with the operation. A single index, a comma/slash/semicolon-separated list,
or an inclusive range (using `-` or `:`) may be supplied. The component
collection is operation-specific: `C2` and `C3` select geometric curves, `E`
selects edges, `L` and `L2d` select loops, `S` and its surface diagnostic
variants select surfaces, `T` and `T2d` select trims, `V` selects vertices, and
the face operations (`F*`, `I`, and `CDT*`) select faces. Omitting indices
plots the complete collection.
MGED, QGED, and gsh use the selected BRep while completing an index: after a
plot mode and a space, completion offers only indices present in that
collection. A completed numeric index, list element, or range endpoint that
is outside the selected collection is rejected before plotting. This check
is intentionally performed by the `brep` command rather than by a global
completion rule, so it remains accurate for each object and plot mode.
Plot one or more 2D parametric space geometric curves.
+1 -1
View File
@@ -10,7 +10,7 @@ cat - Displays a brief description of each item in the list of _objects_.
[source]
----
cat {objects}
cat object [object ...]
----
+28 -19
View File
@@ -35,6 +35,12 @@ object hierarchy and placing the copies in a regular spatial pattern.
It can produce a simple linear series, a rectangular grid, or radial
layouts on spherical and cylindrical coordinate systems.
Where an option takes an XYZ vector, it accepts either three separate
numbers or one packed value using _x/y/z_, _x,y,z_, or _x;y;z_ notation.
A quoted _"x y z"_ value is also accepted for Tcl-compatible command
input. This applies to *--origin*, *--pivot*, *--dir*, *--translate*,
*--rotate*, *--atrans*, and *--arot*.
== AXIS-AWARE OPTIONS
Each pattern publishes a fixed list of axes that any of the four
@@ -52,26 +58,26 @@ becomes the default for every axis whose attribute is otherwise unset)
or an *AXIS=value* form (which binds to that axis only). All four are
repeatable; later occurrences override earlier ones.
*-n, --copies _N_ | _AXIS=N_*::
*-n*, *--copies* _N_ \| _AXIS=N_::
Number of copies along the named axis (or every axis when bare).
*-d, --delta _D_ | _AXIS=D_*::
*-d*, *--delta* _D_ \| _AXIS=D_::
Step size between copies along the axis. Degrees for _az_ and _el_;
model-space distance otherwise.
*--start _V_ | _AXIS=V_*::
*--start* _V_ \| _AXIS=V_::
Starting value for the named axis. Defaults to 0 for non-angular
axes; defaults to -90° for the _el_ axis (south pole) so that a single
elevation produces a layer at the equator only when explicitly set.
*--list _AXIS=v1 v2..._*::
*--list* _AXIS=v1,v2,..._::
Provide an explicit list of values for the named axis. Overrides
*-n*, *-d*, and *--start* for that axis. Only the *AXIS=* form is
accepted.
== SPATIAL & ORIENTATION OPTIONS
*-O, --origin _x y z_*::
*-O*, *--origin* _x y z_::
Pattern origin in model space. Per-pattern interpretation:
+
*lin*: starting position offset (no-op when 0,0,0). +
@@ -79,13 +85,13 @@ Pattern origin in model space. Per-pattern interpretation:
*sph*: centre of the sphere. +
*cyl*: centre of the cylinder base.
*-p, --pivot _x y z_*::
*-p*, *--pivot* _x y z_::
Pivot point baked into each copy when any rotation is applied — that
is *-r* in *lin*, or *--align* in *sph*/*cyl*. Defaults to the model
origin (0,0,0). In *lin* mode, this option doubles as the legacy
rotation centre for *-r* (formerly *--rpoint*).
*--align _KEYS_*::
*--align* _KEYS_::
Comma-separated list of orientation keys. Each copy is rotated so
that the listed direction(s) follow its position. Valid keys per
pattern:
@@ -94,7 +100,7 @@ pattern:
*cyl*: *az* (yaw — also accepts the alias *tan*). +
*lin*, *rect*: not applicable.
*--dir _AXIS x y z_*::
*--dir* _AXIS x y z_::
Direction vector for the named axis. Defaults:
+
*rect*: x → (1,0,0), y → (0,1,0), z → (0,0,1). +
@@ -104,22 +110,25 @@ Direction vector for the named axis. Defaults:
== HOUSEKEEPING OPTIONS
*-h, --help*::
*-h*, *--help*::
Display help and exit.
*-i, --increment _#_*::
*-i*, *--increment* _number_::
Increment used when generating copy names. The first numeric run found
in each source name is incremented by this value; if no number is
present the increment is appended. Default 100.
*-c, --second-number*::
*-c*, *--second-number*::
Move the naming cursor to the _next_ numeric run in object names. May
be repeated for the third, fourth, etc. number.
*--depth top|regions|primitives*::
*--depth* _top_\|_regions_\|_primitives_::
Controls how deeply the copy hierarchy is constructed. Default is
*top* for any pattern that produces more than one copy, *primitives*
for the single-copy linear case.
The short spellings *reg* and *prim* are accepted aliases for
*regions* and *primitives*, respectively.
+
*top* — wrapper combination, source geometry shared. +
*regions* — every combination down to (and including) the first region
@@ -130,11 +139,11 @@ copied; primitives shared. +
Before producing the final clone, flatten any matrices that hang
above the combination members of the source object.
*-g, --group _name_*::
*-g*, *--group* _name_::
Collect the produced clones into a top-level combination called
_name_.
*-s, --subs _sstr_ _rstr_*::
*-s*, *--subs* _sstr rstr_::
Substitute the first occurrence of _sstr_ with _rstr_ in every
generated object name.
@@ -143,22 +152,22 @@ generated object name.
The compact short forms below are accepted only in *lin* mode. They
exist so that any rel-7-42-2 invocation continues to parse identically:
*-t, --translate _x y z_*::
*-t*, *--translate* _x y z_::
Per-copy translation vector. Equivalent to *--dir step _x y z_ -d step
|x y z|*.
*-r, --rotate _x y z_*::
*-r*, *--rotate* _x y z_::
Per-copy rotation in degrees about the X, Y, Z axes (in that order).
Replaced by *--align* in pattern modes.
*-a, --atrans _n x y z_*::
*-a*, *--atrans* _n x y z_::
Total translation _x y z_, split over _n_ copies. Equivalent to *-n n
-t x/n y/n z/n*.
*-b, --arot _n x y z_*::
*-b*, *--arot* _n x y z_::
Total rotation _x y z_ in degrees, split over _n_ copies.
*-m, --mirror _axis_ _d_*::
*-m*, *--mirror* _axis d_::
Mirror the source about the plane perpendicular to _axis_ (x, y, or z)
at distance _d_.
+16 -11
View File
@@ -25,35 +25,40 @@ All dimensional parameters are in the current working units unless otherwise not
=== Options
*-d mean_outer_diameter*::
*-d* _mean_outer_diameter_::
Mean outer diameter of the coil. Defaults to 10× the wire diameter if unspecified. If both are zero, defaults to 1000 (with wire diameter defaulting to 100).
*-w wire_diameter*::
*-w* _wire_diameter_::
Diameter of the coil wire. Defaults to 1/10 of the mean outer diameter if unspecified.
*-H helix_angle*::
*-H* _helix_angle_::
Helix angle of the coil in degrees. Affects the pitch of the winding relative to the axis. (Unsupported when `-l` is used.)
*-p pitch*::
*-p* _pitch_::
Distance between adjacent turns along the coil axis. Must be ≥ wire diameter; if smaller, it is automatically set to the wire diameter.
*-n number_of_turns*::
*-n* _number_of_turns_::
Number of full coil turns.
*-s start_cap_type*::
End cap style at the start of the coil: `0` = open (no cap), `1` = squared, `2` = squared and ground.
*-s* _start_cap_type_::
End cap style at the start of the coil: `0` = open (no cap), `1` = squared,
`2` = ground, or `3` = squared and ground.
*-e end_cap_type*::
*-e* _end_cap_type_::
End cap style at the end of the coil. Same values as `-s`.
*-l overall_length*::
*-l* _overall_length_::
Constrain the coil to a total axial length. When set, pitch and/or number of turns are adjusted automatically to fit. Caps are forced to open (0) and helix angles are ignored.
*-L*::
Use left-hand winding (default is right-hand).
*-S coil_data_structure*::
Advanced: provide an explicit section data structure to override the automatic coil generation.
*-S* _coil_data_structure_::
Advanced: provide one explicit section as
`turns,outer_diameter,wire_diameter,helix_angle,pitch,handedness`. Multiple
`-S` options stack sections in the coil. `handedness` is `1` for right-handed
and `0` for left-handed winding. This form overrides automatic single-section
generation.
[[examples]]
== EXAMPLES
+4
View File
@@ -19,6 +19,10 @@ color [-e] [low high r g b]
Creates an entry in the database that functions as part of a color lookup table for displayed regions. The ident number for the region is used to find the appropriate color from the lookup table. The _low_ and _high_ values are the limits of region ident numbers to have the indicated _rgb_ color (0-255) applied. The current list of color table entries may be displayed with the *prcolor* command, and the entire color table may be edited using the _-e_ option and/or using the *edcolor* command. If a color lookup table exists, its entries will override any color assigned using the *mater* command.
The numeric form requires exactly `low high red green blue`. The color channels
are decimal integers from 0 through 255. The `-e` editing form cannot be
combined with numeric color-record values.
[[examples]]
== EXAMPLES
+6
View File
@@ -113,6 +113,12 @@ Conflicts with *-w* and *-f*.
Use *comb combination lift* for the command form.
*-d*::
Decimates the BoT members below an existing combination. This action accepts
only the combination name and cannot be combined with the other *comb* action
or region-setting options.
*-S*::
Stop if the combination object already exists.
+2 -2
View File
@@ -25,10 +25,10 @@ With member arguments, it sets the transformation for each listed member, constr
=== Options
*-i type*::
*-i* _type_::
Set the input format type for interpreting transformation data. Affects how the `az el tw x y z sa sx sy sz` parameters are parsed and assembled into a matrix.
*-r type*::
*-r* _type_::
Set the representation type for matrix output when reading.
=== Member specification
+3 -3
View File
@@ -10,7 +10,7 @@ constraint - manage parametric geometric constraints stored on database objects
[source]
----
constraint set constraint_name key [expression_parts ...]
constraint set object key [expression_parts ...]
constraint get constraint_name1 [constraint_name2 ...]
constraint show constraint_name1 [constraint_name2 ...]
constraint eval constraint_name1 [constraint_name2 ...]
@@ -27,8 +27,8 @@ Constraints are stored as named attributes on database objects. The *constraint*
=== Subcommands
*set constraint_name key [expression_parts ...]*::
Add or update the constraint attribute named `key` on the existing database object `constraint_name`. The expression value is assembled from all remaining arguments `expression_parts`. The `constraint_name` object must already exist in the database.
*set object key [expression_parts ...]*::
Add or update the constraint attribute named `key` on the existing database object `object`. The expression value is assembled from all remaining arguments `expression_parts`. The `object` must already exist in the database.
*get constraint_name1 [constraint_name2 ...]*::
Print the raw constraint attributes for one or more named objects. Output format per attribute: `object_name attribute_name value`.
+8 -5
View File
@@ -10,7 +10,7 @@ dbot_dump - export currently displayed BOT objects to a mesh file format
[source]
----
dbot_dump [-b] [-n|--normals] [-F|--full-precision]
dbot_dump [--help] [-b] [-n|--normals] [-F|--full-precision]
[-m|--output-directory dir] [-o|--output-file file]
[-t dxf|glb|gltf|obj|sat|stl] [-u unit]
[--no-materials]
@@ -34,6 +34,9 @@ All other options are identical to *bot_dump*, including `--no-materials` to exp
=== Options
*-h*, *--help*::
Print command help without requiring a display manager.
*-b*::
Write output in binary format where supported.
@@ -44,16 +47,16 @@ Write per-vertex normals if the output format supports them.
Write full floating-point precision for coordinate values where supported.
glTF and GLB reject this option.
*-m dir*, *--output-directory dir*::
*-m*, *--output-directory* _dir_::
Write each BOT to a separate file in the specified directory `dir`. Mutually exclusive with `-o`.
*-o file*, *--output-file file*::
*-o*, *--output-file* _file_::
Write all output to the single specified `file`. Mutually exclusive with `-m`.
*-t fmt*::
*-t* _fmt_::
Specify the output format type: `dxf`, `glb`, `gltf`, `obj`, `sat`, or `stl` (default: `stl`).
*-u unit*::
*-u* _unit_::
Output coordinate units (e.g., `mm`, `cm`, `in`, `ft`).
[[examples]]
+55 -114
View File
@@ -4,168 +4,109 @@
:manmanual: BRL-CAD User Commands
== NAME
dm - Provides a means to interact with the display manager at a lower level.
dm - Interact with display-manager instances.
== SYNOPSIS
[source]
----
dm [-h] [-v] {subcommand} [args]
dm [-h] [-v] subcommand [args]
dm attach [--dm name] [--view name] type [name]
dm bg [color [color]]
dm debug [level]
dm get [--dm name] [variable ...]
dm set [--dm name] [variable [value]]
dm {width | height | type} [name]
dm {types | list | initmsg}
----
[[description]]
== DESCRIPTION
Provides a means to interact with the display manager at a lower level. The *dm* command accepts the following subcommands:
The *dm* command interacts with display-manager instances at a lower level.
Top-level options must precede the subcommand. The `-v`/`--verbose` option may
be repeated to increase report detail.
The *attach* subcommand creates a display manager of the specified _type_.
Its optional positional _name_ and `--dm name` name the new manager; supplying
both with different values is an error. Without a name, a unique name based on
the manager type is generated. `--view name` associates the manager with an
existing view. Otherwise it uses the current view when available, or creates a
view for the manager.
The *bg* subcommand queries the current background without arguments. One
color sets a solid background; two colors set the two gradient endpoints.
Colors accept common BRL-CAD forms, including `r/g/b`, `r,g,b`, `r;g;b`, and
three separate components.
The *debug* subcommand queries or sets the display manager's integer debug
level. *type*, *width*, and *height* query the selected manager; their
optional _name_ selects a manager other than the current one. *types* lists
the display manager types supported by the current build, *list* lists known
instances, and *initmsg* prints display-manager plug-in initialization
messages.
The *get* and *set* subcommands query display-manager variables. `dm get`
and `dm set` with no variable print all variables. `dm set variable` queries
one variable, while `dm set variable value` assigns it. `dm get variable ...`
queries each requested variable. `--dm name` selects a manager for either
subcommand.
[[options]]
== OPTIONS
*-h*, *--help*::
Print help.
Print native command-tree help. When followed by a subcommand, print help for
that child.
*-v*, *--verbose*::
Increase top-level command verbosity.
*set* _var_ _val_::
The "set" subcommand provides a means to set or query display manager-specific variables. Invoked without any arguments, the _set_ subcommand will return a list of all available internal display manager variables. If only the _var_ argument is specified, the value of that variable is returned. If both _var_ and _val_ are given, then _var_ will be set to _val_.
*size* _width height_::
The "size" subcommand provides a means to set or query the window size. If no arguments are given, the display manager's window size is returned. If _width_ and _height_ are specified, the display manager makes a request to have its window resized. Note that a size request is just that, a request, so it may be ignored, especially if the user has resized the window using the mouse.
*m* _button_ _x y_::
The "m" subcommand is used to simulate an *M* command. The _button_ argument determines which mouse button is being used to trigger a call to this command. This value is used in the event handler to effect dragging the faceplate scrollbars. The _x_ and _y_ arguments are in X screen coordinates, which are converted to MGED screen coordinates before being passed to the *M* command.
*am* [r] [t] [s] _xy_::
The "am" subcommand effects _mged's_ alternate mouse mode. The alternate mouse mode gives the user a different way of manipulating the view or an object. For example, the user can drag an object or perhaps rotate the view while using the mouse. The first argument indicates the type of operation to perform (i.e., _r_ for rotation, _t_ for translation, and _s_ for scale). The _x_ and _y_ arguments are in X screen coordinates and are transformed appropriately before being passed to the knob command.
*adc* [1] [2] [t] [d] _xy_::
The "adc" subcommand provides a way of manipulating the angle distance cursor while using the mouse. The first argument indicates the type of operation to perform (i.e., _1_ for angle 1, _2_ for angle 2, _t_ for translate, and _d_ for tick distance). The _x_ and _y_ arguments are in X screen coordinates and are transformed appropriately before being passed to the *adc* command (i.e., not "dm adc").
*con* [r] [t] [s] [x] [y] [z] _xpos ypos_::
This form of the "con" subcommand provides a way to effect constrained manipulation of the view or an object while using the mouse. This simulates the behavior of sliders without taking up screen real estate. The first argument indicates the type of operation to perform (i.e., _r_ for rotation, _t_ for translation, and _s_ for scale). The <_x_|_y_|_z_> argument is the axis of rotation, translation, or scale. The _xpos_ and _ypos_ arguments are in X screen coordinates and are transformed appropriately before being passed to the knob command.
*con* [a] [x] [y] [1] [2] [d] _xpos ypos_::
This form of the "con" subcommand provides a way to effect constrained manipulation of the angle distance cursor while using the mouse. This simulates the behavior of sliders without taking up screen real estate. The first argument indicates that this is to be applied to the angle distance cursor. The next argument indicates the type of operation to perform (i.e., _x_ for translate in the _x_ direction, _y_ for translate in the _y_ direction, _1_ for angle 1, _2_ for angle 2, and _d_ for tick distance). The _xpos_ and _ypos_ arguments are in X screen coordinates and are transformed appropriately before being passed to the knob command.
*valid* [ogl] [X] [wgl] [rtgl] [...]::
The "valid" subcommand provides a way to determine if a particular type of display manager (X Windows, OpenGL, etc.) is available - if the display manager type is supported the string denoting that type (X, ogl, etc.) is returned back, otherwise nothing is returned.
Increase top-level report detail. This option may be repeated.
[[examples]]
== EXAMPLES
The examples show the use of the *dm* command with its various subcommands as presented in the Description section.
.List the display-manager types available in this build.
[example]
====
mged>**dm types**
.List the available display manager internal variables.
Lists available types.
====
.List the current display manager's variables.
[example]
====
mged>**dm set**
Lists the available display manager internal variables.
Prints its internal variables.
====
.Turn on perspective projection in the display using _var_ and _val_ arguments.
.Set a display-manager variable.
[example]
====
mged>**dm set perspective 1**
Turns on perspective projection in the display.
Sets `perspective` when that variable is supported.
====
.Query the display manager's window size.
.Set a two-color background gradient.
[example]
====
mged>**dm size**
mged>**dm bg 0/0/32 32/32/96**
The display manager's window size is returned.
Sets the two background endpoints.
====
.Resize the display manager window.
[example]
====
mged>**dm size 900 900**
The display manager window is resized to 900 x 900.
====
.Simulate a button2 press at specific screen coordinates.
[example]
====
mged>**dm m 2 100 200**
Simulates a button2 press at (100, 200) in X screen coordinates.
====
.Use the alternate mouse mode to rotate an image.
[example]
====
mged>**dm am r 400 100**
Starts an alternate mouse mode rotation at (400, 100).
====
.Start a tick distance manipulation with the mouse.
[example]
====
mged>**dm adc d 300 200**
Starts a tick distance manipulation at (300, 200).
====
.Start a constrained translation down the Z axis using the mouse.
[example]
====
mged>**dm con t z 200 200**
Starts a constrained translation down the Z axis.
====
.Start a constrained tick distance manipulation using the mouse.
[example]
====
mged>**dm con a d 200 100**
Starts a constrained tick distance manipulation.
====
.End the mouse drag.
[example]
====
mged>**dm idle**
Ends the drag.
====
[[author]]
== AUTHOR
BRL-CAD Team
[[bug_reports]]
== BUG REPORTS
+4 -2
View File
@@ -4,13 +4,15 @@
:manmanual: BRL-CAD User Commands
== NAME
draw - Adds _objects_> to the display list so that they will appear on the _MGED_ display. The *e* command is a synonym for *draw*.
draw - Adds _objects_ to the display list so that they will appear on the display. The *e* command is a synonym for *draw*.
== SYNOPSIS
[source]
----
draw [-A attribute name/value pairs] [-s] [-A -o attribute name/value pairs] [-C#/#/#] [-L #] [-R] [-S] [-m1] {objects}
draw [--mode 0|1|2|3|4|5] [options] {objects}
----
@@ -23,7 +25,7 @@ Adds _objects_ to the display list so that they will appear on the MGED display.
* The _-C_ option provides the user a way to specify a color that overrides all other color specifications including combination colors and region-id-based colors.
* The _-s_ option specifies that subtracted and intersected objects should be drawn with shape lines rather than dot-dash lines.
* The _-A_ option specifies that the arguments provided to this command are attribute name/value pairs, and only objects having the specified attributes and values are to be displayed. The default (without _-o_) is that only objects having all the specified attribute name/value pairs will be displayed. With _-o_, objects that match any of the specified attribute name/value pairs will be displayed.
* The _-m1_ option will display BOTs shaded if the display manager is OpenGL and the zbuffer and lighting is enabled. To enable these settings, from the MGED GUI, choose "Modes/Display Manager/OpenGL", "Misc/Z-buffer" and "Misc/Lighting". If the zbuffer and lighting is already enabled, toggle them off then back on to ensure they are enabled.
* The _-m_ or _--mode_ option accepts an integer from 0 through 5. The value may be a separate argument, as in _--mode 1_, joined with an equals sign, as in _--mode=1_, or joined to the short option, as in _-m1_. In QGED and GSH's _--new-cmds_ mode, the meanings are 0 (wireframe), 1 (shaded BoTs, B-Reps, and polysolids), 2 (all solids shaded without evaluating Boolean operations), 3 (wireframe with Boolean operations evaluated), 4 (hidden-line), and 5 (point-sampled triangles). In the legacy MGED and GSH draw implementation, modes 3 and 5 instead mean evaluated shading and evaluated wireframe, respectively. Values outside 0 through 5 are invalid.
* The _-L_ option allows the user to specify a face count. BoT primitives with more faces than the user set threshold will be represented in wireframe drawing by their bounding boxes rather than the full BoT wireframe.
* The _-R_ option tells draw to not change the view size when drawing new objects. Without this flag, *draw* will automatically size the view to make the new object(s) visible when the view was previously empty.
* The _-S_ option tells draw to be "simplified" by skipping subtraction objects when drawing, not drawing NMG interior surfaces, and potentially more. Skipping subtractions is useful in situations where an object has many large objects subtracted from it but those objects have relatively minimal impact on the shape. This results in the default wireframe bearing little resemablance to the evaluated shape.
+4 -1
View File
@@ -10,7 +10,7 @@ edcolor - Puts the user into an editor to edit a file that has been filled with
[source]
----
edcolor [] []
edcolor [-E editor]
----
@@ -19,6 +19,9 @@ edcolor [] []
Puts the user into an editor to edit a file that has been filled with the ident-based color lookup table. The entire table may be seen with the *prcolor* command, and entries may be added using the color command. The editor used is whatever the user has set in the environment variable _EDITOR_. If _EDITOR_ is not set, then _/bin/ed_ is used.
The optional *-E editor* argument selects a specific editor command instead of
the default. With no options, *edcolor* opens the default editor.
[[examples]]
== EXAMPLES
+7 -7
View File
@@ -166,7 +166,7 @@ complete option reference and examples.
*-x*, *-y*, *-z*::
Restrict the translation to the specified axis only.
*-k FROM*::
*-k* _FROM_::
Set the reference keypoint. *FROM* may be an object name or a
position `x y z`.
@@ -199,13 +199,13 @@ model, and examples.
*-x*, *-y*, *-z*::
Restrict the rotation to the specified axis (Euler mode).
*-k AXIS_FROM*, *-a/-r AXIS_TO*::
*-k* _AXIS_FROM_, *-a*\|*-r* _AXIS_TO_::
Supply an explicit axis of rotation (axis mode).
*-c CENTER*::
*-c* _CENTER_::
Set the pivot center (defaults to bounding-box center).
*-O ANGLE_ORIGIN*, *-d DEGREES*::
*-O* _ANGLE_ORIGIN_, *-d* _DEGREES_::
Set the angle origin and explicit rotation angle.
.Quick examples
@@ -229,14 +229,14 @@ Scales the object by a uniform or per-axis factor. See
*edit scale*(nged) for the complete option reference, the SCALE
reference-frame model, and examples.
*-k FROM*::
*-k* _FROM_::
Reference "from" position. Defaults to the object keypoint.
*-a TO*, *-r TO*::
*-a* _TO_, *-r* _TO_::
"To" position (absolute or relative). Together with *-k*, defines
the reference scale vector.
*-c CENTER*::
*-c* _CENTER_::
Center of the scaling operation.
.Quick examples
+5 -6
View File
@@ -10,9 +10,7 @@ editit - open a file in an external text editor
[source]
----
editit [opts] <filename>
editit -f <file>
editit -e <editstring> <filename>
editit [-e editstring] (-f file | file)
----
@@ -21,14 +19,15 @@ editit -e <editstring> <filename>
The *editit* command opens a file in an external text editor. The editor used is determined by the current environment (typically the `EDITOR` environment variable or a system default).
The file to edit can be specified as a positional argument or via the `-f` option. Only one file specification is allowed per invocation.
The file to edit can be specified as a positional argument or via the `-f`
option. Exactly one file specification is required per invocation.
=== Options
*-f file*::
*-f* _file_::
Specify the file to edit. Equivalent to providing `filename` as a positional argument.
*-e editstring*::
*-e* _editstring_::
Specify an edit string to pass to the editor (deprecated; prefer specifying the editor via the environment).
[[examples]]
+7 -2
View File
@@ -10,14 +10,19 @@ edmater - Places the user in an editor ready to edit a file filled with shader a
[source]
----
edmater {combinations} []
edmater [-E editor] {combination} ...
----
[[description]]
== DESCRIPTION
Places the user in an editor ready to edit a file filled with shader arguments for the combinations listed on the command line. The arguments placed in the file for editing are the _shader_ name and its own arguments, RGB color,__RGB_valid__ flag, and the inheritance flag. The editor used is whatever the user has set in the environment variable _EDITOR_. If _EDITOR_ is not set, then _/bin/ed_ is used.
Places the user in an editor ready to edit a file filled with shader arguments
for the combinations listed on the command line. The arguments placed in the
file for editing are the _shader_ name and its own arguments, RGB color,
_RGB_valid_ flag, and the inheritance flag. By default the editor is selected
by the environment variable _EDITOR_, or _/bin/ed_ when it is unset. The
optional `-E editor` argument supplies the editor command for this invocation.
[[examples]]
+29 -3
View File
@@ -10,20 +10,43 @@ env - Print the current environmental variables.
[source]
----
env
env [options] [pattern ...]
env get variable
env set variable value
----
[[description]]
== DESCRIPTION
Print the current environmental variables.
Without a subcommand, *env* lists the BRL-CAD environment variables that are
currently set. Optional shell-style patterns limit the listed variable names.
*env get* reports one known variable's current value. *env set* changes one
known variable for the current process and reports the new value.
== OPTIONS
*-h*, *--help*::
Print command usage.
*-A*, *--all*::
List known variables even when they are not set.
*-S*, *--system*::
Include known variables used by external system or third-party software.
*-C*, *--context*::
Show the BRL-CAD library or executable associated with each listed variable.
*-M*, *--memory*::
Report the current memory totals and page size instead of listing variables.
[[examples]]
== EXAMPLES
Print the current environmental variables.
List variables associated with BRL-CAD:
.Enter *env* to display the current environmental variables.
[example]
@@ -32,6 +55,9 @@ Print the current environmental variables.
mged> **env**::
The current environmental variables and their values are displayed.
mged> **env --all BRLCAD_***::
All known BRL-CAD-prefixed variables are listed, including unset ones.
====
+6
View File
@@ -14,6 +14,7 @@ erase object [object ...]
erase -r object [object ...]
erase -A attr value [attr value ...]
erase -o -A attr value [attr value ...]
erase [--view name] [--mode number] object [object ...]
----
@@ -33,6 +34,11 @@ objects are erased from the display. By default all specified pairs must match;
the *-o* option changes attribute mode so that matching any one of the supplied
pairs is sufficient.
In the new command form used by QGED and other view-aware clients, *--view*
selects an independent view and *--mode* limits erasure to a drawing mode.
Those options are not available in the legacy command form; conversely, the
legacy *-r*, *-A*, and *-o* modes are not available in the new command form.
[[examples]]
== EXAMPLES
+16 -16
View File
@@ -10,7 +10,7 @@ facetize - Creates __new_object__ using __old_object__ as a guide, creating an e
[source]
----
facetize [-h] [-v] [-q] [-n] [-r] [-j jobs] [-s suffix] [-p prefix] [--in-place] [--max-time #] [--max-pnts #] [--resume] [--methods m1,m2,...] [--method-opts METHOD opt1=val opt2=val...] [--no-empty] [--log-file filename] [--nmg-booleval] [--disable-fixup] [--perturb] [--no-perturb] [--perturb-sa-tol #] [--perturb-vol-tol #] [--tolerate-failures] [-B -t threshold] {old_object new_object}
facetize [-h] [-v] [-q] [-n] [-r] [-j jobs] [-s suffix] [-p prefix] [--in-place] [--max-time #] [--max-pnts #] [--resume] [--methods m1,m2,...] [--method-opts "METHOD opt1=val opt2=val..."] [--no-empty] [--log-file filename] [--nmg-booleval] [--disable-fixup] [--perturb] [--no-perturb] [--perturb-sa-tol #] [--perturb-vol-tol #] [--tolerate-failures] [-B -t threshold] {old_object new_object}
----
@@ -84,23 +84,23 @@ If a child fails before acknowledging that its write has started, the working da
== Options
*-h, --help*::
*-h*, *--help*::
Print help and exit.
*-v[v..], --verbose*::
*-v*, *--verbose*::
Prints extra (verbose) information in results. May be overridden by the *--quiet* flag.
*-q, --quiet*::
*-q*, *--quiet*::
Suppress all output (overrides verbosity flag.)
*-n, --nmg-output*::
*-n*, *--nmg-output*::
Instructs *facetize* to produce NMG solids rather than BoT solids.
*-r, --regions*::
*-r*, *--regions*::
Rather than converting all specified inputs to one top level object, walk specified trees and individually convert regions to facetized objects. This mode is useful when wanting to display models in shaded mode while preserving color and region ID properties. If no regions are present a normal conversion is performed instead.
@@ -108,11 +108,11 @@ Rather than converting all specified inputs to one top level object, walk specif
Set the maximum number of facetize worker processes. A value of 1 forces serial processing. The default value of 0 selects a conservative automatic limit based on available CPUs and memory. Memory checks may delay or reduce parallel work even when a larger value is requested. In per-region BoT mode the same limit controls parallel CSG reference sampling and initial Manifold Boolean evaluation.
*-s, --suffix*::
*-s*, *--suffix* _suffix_::
User specified suffix to use avoiding naming conflicts (naming conflict avoidance is needed when creating objects in *-r* mode.)
*-p, --prefix*::
*-p*, *--prefix* _prefix_::
User specified prefix to use avoiding naming conflicts (naming conflict avoidance is needed when creating objects in *-r* mode.)
@@ -120,11 +120,11 @@ User specified prefix to use avoiding naming conflicts (naming conflict avoidanc
Replace the specified object(s) with their facetizations. (WARNING: this option is destructive and will change pre-existing geometry!)
*--max-time #*::
*--max-time* _seconds_::
Maximum time to spend per object (in seconds). Default is method specific. Note that specifying shorter times may cut off conversions (particularly using sampling methods) that could succeed with longer runtimes. Per-method time limits can also be adjusted to allow longer runtimes on slower methods.
*--max-pnts #*::
*--max-pnts* _count_::
Maximum number of pnts per object to use when applying ray sampling methods.
@@ -132,19 +132,19 @@ Maximum number of pnts per object to use when applying ray sampling methods.
Resume an incomplete facetization process (will utilize cached data from a previous run rather than starting from scratch.) Re-running without this option will clear any old data and start from the beginning.
*--methods*::
*--methods* _method[,method...]_::
Accepts a comma separated list of one or more facetization methods to use. The default tries NMG tessellation first, Manifold Dual Contouring (MDC) second, and SPSR as a final fallback. Other listed methods may be selected explicitly if a user wants to try a specific methodology.
*--method-opts*::
This option can be used to pass parameter values to specific facetize methods. The argument format is "METHOD opt1=val1 opt2=val2 ...". See the *--help* output for which methods and parameters are supported by *facetize*.
*--method-opts* _"METHOD option=value ..."_::
This option can be used to pass parameter values to specific facetize methods. Its complete argument must be quoted: *--method-opts "METHOD opt1=val1 opt2=val2 ..."*. Each setting is a *key=value* pair. See the *--help* output for which methods and parameters are supported by *facetize*.
*--no-empty*::
Do not write out empty BoT objects when a Boolean evaluation results in an empty mesh.
*--log-file*::
*--log-file* _file_::
Specify a log file in which to store the full verbose output of a facetization process. This is recommended for large or long running facetize runs to allow users to better understand what steps were taken and what problems might have arisen.
@@ -162,10 +162,10 @@ Enable the coplanarity-avoidance perturbation step. In per-region mode this beha
*--no-perturb*::
Disable the coplanarity-avoidance perturbation retry machinery in BoT Manifold Boolean evaluation. This option conflicts with *--perturb*.
*--perturb-sa-tol #*::
*--perturb-sa-tol* _percent_::
Surface-area percentage threshold (0–100) that triggers the coplanarity-avoidance perturb retry when the per-region Crofton-sampled CSG surface area differs from the initial facetized BoT surface area by more than this amount. Default is 10 (percent).
*--perturb-vol-tol #*::
*--perturb-vol-tol* _percent_::
Volume percentage threshold (0–100) that triggers the coplanarity-avoidance perturb retry when the per-region Crofton-sampled CSG volume differs from the initial facetized BoT volume by more than this amount. Default is 10 (percent).
*--tolerate-failures*::
+3 -3
View File
@@ -22,9 +22,9 @@ The available options are:
* *-c* : Crunch the colormap (apply colormap to pixel values).
* *-i* : Inverse mapping (draws the image upside down).
* *-s squaresize* : Sets both the output width and height to the specified `squaresize`.
* *-w width* : Sets the output width.
* *-n height* : Sets the output height.
* *-s squaresize* : Sets both the output width and height to the specified positive `squaresize`.
* *-w width* : Sets the output width to a positive value.
* *-n height* : Sets the output height to a positive value.
* *-h* or *-?* : Prints the command usage and exits.
If size parameters are omitted, it defaults to capturing a 512x512 region.
+1 -1
View File
@@ -10,7 +10,7 @@ find - find all references to objects
[source]
----
find [-a] <objects>
find [-a] object [object ...]
----
[[description]]
+6 -1
View File
@@ -10,7 +10,7 @@ find_bot_edge - find and identify a BOT (Bag of Triangles) edge
[source]
----
find_bot_edge bot "view_x view_y view_z"
find_bot_edge [--help] bot "view_x view_y view_z"
----
[[description]]
@@ -18,6 +18,11 @@ find_bot_edge bot "view_x view_y view_z"
The *find_bot_edge* command searches a BOT (Bag of Triangles) primitive and identifies the edge that is closest to a given view coordinate.
=== Options
*-h*, *--help*::
Print command help without requiring an open database or active view.
If successful, the command returns two integers:
1. The numeric ID of the first vertex (`vi1`) forming the edge.
2. The numeric ID of the second vertex (`vi2`) forming the edge.
+6 -1
View File
@@ -10,7 +10,7 @@ find_bot_pnt - find and identify a BOT point
[source]
----
find_bot_pnt bot "view_x view_y view_z"
find_bot_pnt [--help] bot "view_x view_y view_z"
----
[[description]]
@@ -18,6 +18,11 @@ find_bot_pnt bot "view_x view_y view_z"
The *find_bot_pnt* command searches a BOT (Bag of Triangles) primitive and identifies the vertex that is closest to a given view coordinate.
=== Options
*-h*, *--help*::
Print command help without requiring an open database or active view.
If successful, the command returns a single integer representing the numeric ID of the closest vertex.
The arguments are:
@@ -44,7 +44,7 @@ The example shows the use of the *garbage_collect* command to delete unused spac
[example]
====
mged> **garbage_collect**:: -c
mged> **garbage_collect -c**
Cleans out unused space in the database.
+1 -1
View File
@@ -10,7 +10,7 @@ get - Retrieves parameter values of database objects.
[source]
----
get {object_name_pattern} [param_name]
get object_or_path [property]
----
@@ -0,0 +1,37 @@
= GET_BOT_EDGES(nged)
:doctype: manpage
:mansource: BRL-CAD
:manmanual: BRL-CAD User Commands
== NAME
get_bot_edges - list the edges of a BOT primitive
== SYNOPSIS
[source]
----
get_bot_edges [--help] bot
----
== DESCRIPTION
The *get_bot_edges* command lists the unique edges of a BOT (Bag-of-Triangles)
primitive. Each edge is written as a pair of vertex indices.
=== Options
*-h*, *--help*::
Print command help without requiring an open database.
== SEE ALSO
*find_bot_edge*(nged), *find_bot_pnt*(nged)
== AUTHOR
BRL-CAD Team
== BUG REPORTS
Report bugs and problems to devs@brlcad.org.
+46 -26
View File
@@ -4,57 +4,77 @@
:manmanual: BRL-CAD MGED Commands
== NAME
graph - Used to query and manipulate properties of the graph that corresponds to the currently opened .g database.
graph - generate a database hierarchy graph
== SYNOPSIS
[source]
----
graph [show] [positions]
graph [options] output.svg
graph --igraph [show|positions]
----
[[description]]
== DESCRIPTION
Used to query and manipulate properties of the graph that corresponds to the currently opened .g database. The "show" subcommand displays a list of names and types of the objects from the database along with the positions within the graph of their corresponding nodes and their connection edges. The "positions" subcommand displays for each object in the geometric database its name, type, and node and positions within the graph.
The *graph* command creates a diagram of the currently open database's
hierarchy. Its normal form writes an SVG document to _output.svg_. The
output filename must use the `.svg` suffix.
The `--igraph` form retains the textual graph operations used by older
GraphEditor/igraph scripts. It takes exactly one operation: `show` reports
nodes and connections, and `positions` reports object-node positions.
The command requires the Adaptagrams support library. Builds without that
library register the command but report that graph generation is unavailable.
== OPTIONS
*-h*, *--help*::
Print command usage.
*--tree*::
Collapse the diagram to a spanning tree, limiting each node to at most one
incoming graph edge.
*--skip-routing*::
Write nodes without calculating connector routes.
*--depth* _depth_::
Limit hierarchy traversal to a non-negative depth.
*--root-obj* _object_::
Use _object_ as a traversal root. This option may be repeated to draw several
rooted subgraphs.
*--igraph*::
Select the legacy textual mode. Follow it with `show` or `positions` rather
than an SVG filename.
[[examples]]
== EXAMPLES
The examples demonstrate the use of the *graph* command and subcommands to access information about the representation of the objects of a database.
.Displays a list with the name and type of the objects along with the nodes' and edges' positions.
.Write an SVG of the complete hierarchy
[example]
====
mged> **graph show**::
Displays a list with the name and type of the objects along with the nodes' and edges' positions.
mged> *graph hierarchy.svg*
====
.Lists the names, types, positions of the corresponding nodes within the graph for the objects in the .g database.
.Write a depth-limited graph rooted at an assembly
[example]
====
mged> **graph positions**::
Lists the names, types, positions of the corresponding nodes within the graph for the objects in the currently opened .g database.
mged> *graph --root-obj all.g --depth 3 assembly.svg*
====
.Use the legacy textual position report
[example]
====
mged> *graph --igraph positions*
====
[[author]]
== AUTHOR
BRL-CAD Team
[[bug_reports]]
== BUG REPORTS
Reports of bugs or problems should be submitted via electronic mail to devs@brlcad.org
Report problems to devs@brlcad.org.
+27 -12
View File
@@ -10,7 +10,7 @@ grid - control the display grid and snap-to-grid behavior
[source]
----
grid vname parameter [value]
grid parameter [value ...]
----
@@ -19,7 +19,10 @@ grid vname parameter [value]
The *grid* command controls the view grid: a regular overlay of horizontal and vertical lines drawn on the display to aid in alignment and measurement. It also controls snap-to-grid behavior, which constrains view center movement to the nearest grid intersection.
The first argument `vname` is the name of the view to configure. The second argument `parameter` specifies which grid attribute to get or set. If a value is provided it sets the attribute; if omitted the current value is returned.
The `parameter` selects a grid attribute or action for the current view. If a
value is provided it sets that attribute; if omitted the current value is
returned. `help` prints the command syntax and `vars` prints every current
grid value.
=== Parameters
@@ -28,9 +31,13 @@ The first argument `vname` is the name of the view to configure. The second argu
|Parameter |Value |Description
|`color`
|`r g b`
|`r/g/b`, `r,g,b`, `r;g;b`, or `r g b`
|Get or set the grid line color as three integers (0–255). With no value, returns current color.
|`anchor`
|`x/y/z`, `x,y,z`, `x;y;z`, or `x y z`
|Get or set the grid anchor in current working units. With no value, returns the current anchor.
|`draw`
|`0` or `1`
|Enable (`1`) or disable (`0`) grid display. With no value, returns current draw state.
@@ -59,6 +66,14 @@ The first argument `vname` is the name of the view to configure. The second argu
|(none)
|Snap the current view center to the nearest grid intersection. Takes no value argument.
|`vars`
|(none)
|Print all current grid values.
|`help`
|(none)
|Print grid command syntax.
|===
[[examples]]
@@ -67,16 +82,16 @@ The first argument `vname` is the name of the view to configure. The second argu
.Enable the grid
[example]
====
mged> **grid default draw 1**
mged> **grid draw 1**
Turns on grid display for the view named `default`.
Turns on grid display for the current view.
====
.Set grid spacing to 10 mm
[example]
====
mged> **grid default rh 10**
mged> **grid default rv 10**
mged> **grid rh 10**
mged> **grid rv 10**
Sets horizontal and vertical grid spacing to 10 units in the current working units.
====
@@ -84,15 +99,15 @@ Sets horizontal and vertical grid spacing to 10 units in the current working uni
.Enable snap-to-grid
[example]
====
mged> **grid default snap 1**
mged> **grid snap 1**
Enables snap-to-grid for the `default` view. The view center will snap to the nearest grid point during interactive navigation.
Enables snap-to-grid for the current view. The view center will snap to the nearest grid point during interactive navigation.
====
.Set grid color to green
[example]
====
mged> **grid default color 0 200 0**
mged> **grid color 0;200;0**
Sets the grid line color to green (R=0, G=200, B=0).
====
@@ -100,7 +115,7 @@ Sets the grid line color to green (R=0, G=200, B=0).
.Get the current horizontal resolution
[example]
====
mged> **grid default rh**
mged> **grid rh**
Returns the current horizontal grid resolution in working units, for example: `10`.
====
@@ -108,7 +123,7 @@ Returns the current horizontal grid resolution in working units, for example: `1
.Snap view center to nearest grid point
[example]
====
mged> **grid default vsnap**
mged> **grid vsnap**
Moves the view center to the nearest grid intersection.
====
+3 -1
View File
@@ -26,7 +26,9 @@ The optional `op` argument specifies the Boolean relationship:
* `-` — subtraction
* `+` — intersection
The combination `comb` must already exist. To create a new combination at the same time, use *group*, *comb*, or *region*.
If the combination `comb` does not already exist, *instance* creates it. A
new combination is created as a non-region combination; use *region* when
region attributes are required.
[[examples]]
== EXAMPLES
+6 -7
View File
@@ -10,14 +10,16 @@ knob - Provides a method for simulating knob input. With no options, it will dis
[source]
----
knob [-e -i -m -v] [[-o] | [v] | [m] | [e] | [k]] [[zap] | [zero] | [id [val]]]
knob [--help] [--incr] [--view-coords | --model-coords] [--origin v|m|e|k] [action [value] ...]
----
[[description]]
== DESCRIPTION
*The *knob* command is used internally by MGED in the processing of knob input devices and is not recommended for users.* The *knob* command provides a method for simulating knob input. With no options, it will display the current values for the knobs. With the *zap or zero* command provided, all the knob values will be reset to zero. If an _id_ and _value_ are provided, the specified knob setting will be simulated. If the _-i_ option is specified, then the value provided will be used as an increment to be applied to the indicated knob. The knobs have different functions depending on the current mode. For example, if in primitive or matrix edit mode and a rotation or translation function is selected, the knob effects are applied to the edited object by default. However, the _-v_ (view coordinates) and _-m_ (model coordinates) options may be used to adjust the view without modifying primitives or matrices. The _-e_ option allows the knob effects to be applied to the edited object when they would normally be applied to the view. The _-o_ option allows the origin of rotation to be specified with _v, m, e,_ and _k_, indicating view, model, eye, and keypoint, respectively. The units for _value_ are degrees for rotation and local units for translation. The available _knob ids_ are:
*The *knob* command is used internally by MGED in the processing of knob input devices and is not recommended for users.* The *knob* command provides a method for simulating knob input. With no options, it displays the current knob values. It accepts a sequence of actions: *zap*, *zero*, *clear*, *stop*, and *calibrate* take no value; every knob identifier takes one finite numeric value. *zap*, *zero*, *clear*, and *stop* reset the rate-based values. *calibrate* resets the absolute translation baselines.
If the _-i_ / _--incr_ option is specified, each numeric value is applied as an increment. The _-v_ / _--view-coords_ and _-m_ / _--model-coords_ options select the coordinate system and cannot be combined; if neither is given, the current view coordinate setting is used. The _-o_ / _--origin_ option selects the rotation origin: _v_ (view, the default), _m_ (model), _e_ (eye), or _k_ (the current keypoint). Rotation values are in degrees and translation values are in local units. The available knob identifiers are:
* *x* -- rate-based rotation about horizontal axis.
@@ -34,11 +36,8 @@ knob [-e -i -m -v] [[-o] | [v] | [m] | [e] | [k]] [[zap] | [zero] | [id [val]]]
* *aY* -- absolute translation in vertical direction.
* *aZ* -- absolute translation in direction normal to screen.
* *aS* -- absolute Scale or Zoom.
* *xadc* -- absolute translation of adc in horizontal direction (screen coordinates -2048 to +2048).
* *yadc* -- absolute translation of adc in vertical direction (screen coordinates -2048 to +2048).
* *ang1* -- absolute rotation of adc angle1 (degrees).
* *ang2* -- absolute rotation of adc angle2 (degrees).
* *distadc* -- distance setting of the adc (screen coordinates -2048 to +2048).
The command rejects unknown identifiers, missing values, nonnumeric values, and a mixture of view and model coordinate options before modifying the view.
[[examples]]
+7 -9
View File
@@ -44,17 +44,15 @@ Remove regions from the list in which their parent is a region and the region is
Specifies descending (z-a) sort order.
*-0*
*-1*
*-2*
*-3*
*-4*
*-5*
*-6*::
Specifies sort column 1, 2, 3, 4, 5, or 6 (referring to columns listed in the description of this command); 1 is default. If 0 is specified, the regions are listed in the order in which they are stored, but this will be overridden if *-d*, *-m*, or *-s* options are used, because of the sorting which needs to be done when either of those options is used.
*-0*, *-1*, *-2*, *-3*, *-4*, *-5*::
Selects the sort key. *-1* through *-5* sort by region ID, material ID, LOS,
air code, and region name respectively; *-1* is the default. *-0* keeps the
stored order. The duplicate-filtering options *-d*, *-m*, and *-s* may still
sort records as needed to detect matching codes. The displayed region-parent
column is not a sort-key option.
*-f FileName*::
*-f* _FileName_::
Identifies output should be to a file and specifies the file name. If the path is not included as part of the 'FileName' the path will be the 'current directory'.
[[examples]]
+2 -2
View File
@@ -42,8 +42,8 @@ Check for full paths that are cyclic - i.e. a situation where a high level objec
Check for references to objects or files that are missing (not present in the database or on the file system.) Primarily this is a check for comb objects referring to missing objects, but it will also check for and report invalid object and file references in extrude and dsp primitives.
*-I*, *--invalid-shape* [check [check ...]]::
Check for shapes in the database that do not satisfy one or more properties required for them to be valid definitions, where correcting the problem requires a change to the object's definition. (As of this writing the only implemented check is for BoT object solidity, but many more are possible and planned.) (Objects invalid due to missing objects are potentially valid without the necessity of changing the object's own definition - e.g. the missing object/file can be added. That category of error can be searched for with the *-M* check.)
*-I*, *--invalid-shape* [_primitive:technique_ [ ... ]]::
Check for shapes in the database that do not satisfy one or more properties required for them to be valid definitions, where correcting the problem requires a change to the object's definition. (As of this writing the only implemented check is for BoT object solidity, but many more are possible and planned.) (Objects invalid due to missing objects are potentially valid without the necessity of changing the object's own definition - e.g. the missing object/file can be added. That category of error can be searched for with the *-M* check.) The optional selector is consumed only when it contains a colon, so `lint -I object.g` checks `object.g`, while `lint -I bot:empty object.g` selects the `bot:empty` technique before checking `object.g`. Multiple selectors may be supplied as one quoted argument.
*-F*, *--filter*::
+2 -2
View File
@@ -10,8 +10,8 @@ list, l - list the attributes and parameters of database objects
[source]
----
list [-r] [-t] [-v] object(s)
l [-r] [-t] [-v] object(s)
list [-r] [-t] [-v ...] object [object ...]
l [-r] [-t] [-v ...] object [object ...]
----
+35 -21
View File
@@ -11,29 +11,42 @@ lod - configure Level of Detail (LOD) drawing
[source]
----
lod
lod (on|off|enabled)
lod scale (points|curves) [factor]
lod [--help]
lod [0|1]
lod csg|mesh [0|1]
lod cache [clear [all_files]|exists]
lod scale|point_scale|curve_scale [factor]
lod bot_threshold [face_count]
view lod [same arguments]
----
[[description]]
== DESCRIPTION
The *lod* command configures the Level of Detail (LoD) drawing behavior for the current view. When LoD drawing is enabled, BRL-CAD adapts the rendering complexity of wireframe geometry based on view conditions, improving performance for complex models.
The *lod* command configures the Level of Detail (LoD) drawing behavior for the current view. *view lod* is an equivalent spelling. When LoD drawing is enabled, BRL-CAD adapts the rendering complexity of wireframe geometry based on view conditions, improving performance for complex models.
When called with no arguments, *lod* prints the current LoD configuration, including:
* Whether adaptive LoD drawing is currently enabled or disabled.
* The current *point scale* factor.
* The current *curve scale* factor.
* The current *BoT face threshold* (the number of faces at which a BoT switches to simplified display).
* Whether mesh and CSG adaptive LoD drawing are enabled.
* The current overall, point, and curve scale factors.
* The current BoT face threshold (the number of faces at which a BoT switches to simplified display).
=== Subcommands
* *on* : Enable adaptive LoD drawing.
* *off* : Disable adaptive LoD drawing.
* *enabled* : Print `1` if LoD is currently enabled, `0` if disabled. Suitable for scripting.
* *scale points [factor]* : If `factor` is given, sets the point density scale. If omitted, prints the current point scale value.
* *scale curves [factor]* : If `factor` is given, sets the curve complexity scale. If omitted, prints the current curve scale value.
* *1* : Enable both mesh and CSG adaptive LoD drawing.
* *0* : Disable both mesh and CSG adaptive LoD drawing.
* *csg [0|1]* : Query or set CSG adaptive LoD drawing.
* *mesh [0|1]* : Query or set mesh adaptive LoD drawing.
* *scale [factor]* : Query or set the overall LoD scale.
* *point_scale [factor]* : Query or set the point-density scale.
* *curve_scale [factor]* : Query or set the curve-complexity scale.
* *bot_threshold [face_count]* : Query or set the nonnegative BoT face threshold.
* *cache* : Build the current database's mesh LoD cache.
* *cache clear* : Clear the in-memory cache.
* *cache clear all_files* : Clear cache data for all files.
* *cache exists* : Test whether all BoT and BRep entries have cached LoD data.
All scale values must be finite numbers. The command rejects an unknown action, an invalid binary setting, a negative threshold, or extra action arguments before changing view state.
[[examples]]
== EXAMPLES
@@ -44,10 +57,11 @@ When called with no arguments, *lod* prints the current LoD configuration, inclu
mged> **lod**
----
LoD drawing: enabled
Point scale: 1.000000
Curve scale: 1.000000
BoT face threshold: 32768
enabled(mesh/csg): 1/1
scale: 1
point_scale: 1
curve_scale: 1
bot_threshold: 32768
----
Prints the current LoD configuration.
@@ -56,18 +70,18 @@ Prints the current LoD configuration.
.Enable LoD and reduce curve complexity
[example]
====
mged> **lod on**
mged> **lod scale curves 0.5**
mged> **view lod 1**
mged> **view lod curve_scale 0.5**
Enables LoD drawing and halves the curve complexity scale, reducing the number of line segments used to approximate curves.
====
.Check LoD status for scripting
.Query a single LoD setting
[example]
====
mged> **lod enabled**
mged> **lod mesh**
Returns `1` if LoD is enabled, `0` if disabled. Useful in scripts or Tcl procedures.
Returns `1` if mesh LoD drawing is enabled and `0` otherwise. Useful in scripts or Tcl procedures.
====
[[author]]
+4 -3
View File
@@ -10,14 +10,15 @@ ls - The command with no _object_ argument lists the name of every object in the
[source]
----
ls [-A -o -a -c -r -s -p -l -q -H -S] [objects]
ls [-a -c -r -s -p -l -q -H -S] [objects]
ls --attributes [--or] [-a -c -r -s -p -l -q -H -S] attribute value [attribute value ...]
----
[[description]]
== DESCRIPTION
The command with no _object_ argument lists the name of every object in the database (in alphabetical order) except for those marked as hidden with the *hide* command. If the _object_ argument is supplied, only those _objects_ are listed. The _object_ argument may include regular expressions. If the _-A_ option is used, then the arguments are expected to be a list of attribute name/value pairs, and objects having attributes that match the provided list are listed. By default, an object must match all the specified attributes in order to be listed; however, the _-o_ flag indicates that an object matching at least one attribute name/value pair should be listed. See the *attr* command for information on how to set or get attributes. Regular expressions are not supported for attributes. The following options are also allowed:
The command with no _object_ argument lists the name of every object in the database (in alphabetical order) except for those marked as hidden with the *hide* command. If the _object_ argument is supplied, only those _objects_ are listed. The _object_ argument may include regular expressions. If the _-A_ option is used, the operands are attribute name/value pairs (one or more complete pairs are required), and objects having attributes that match the provided list are listed. By default, an object must match all the specified attributes in order to be listed; however, the _-o_ flag indicates that an object matching at least one attribute name/value pair should be listed. See the *attr* command for information on how to set or get attributes. Regular expressions are not supported for attributes. The following options are also allowed:
* `-h`, `--help` -- Print help and exit.
@@ -91,7 +92,7 @@ Lists all combinations with names beginning with "suspension."
.List all regions having particular attributes.
[example]
====
mged>**ls -A -o -r Comment{First comment} Comment{Second comment}**
mged>**ls -A -o -r Comment {First comment} Comment {Second comment}**
Lists all regions that have a "Comment" attribute that is set to either "First comment" or "Second comment."
+22 -5
View File
@@ -10,18 +10,35 @@ make - Creates a __new_shape__ of the indicated type.
[source]
----
make [-h] [-t] [-o "x y z"] [-s scale] new_shape type
make [-o x/y/z] [-s scale] new_shape type
make -t
make -h
----
[[description]]
== DESCRIPTION
Creates a __new_shape__ of the indicated type. The __new_shape__ is sized according to the current view size and is dependent on the _type_. The possible values for _type_ are:
Creates a __new_shape__ of the indicated type. The __new_shape__ is sized according to the current view size and is dependent on the _type_.
The *-h* option prints usage help. The *-o* option specifies the origin for the
new primitive and the *-s* option sets the initial size scale used when
building the primitive.
== OPTIONS
*-o* _x/y/z_::
Set the primitive origin. A finite three-component value may be written as
`x/y/z`, `x,y,z`, `x;y;z`, a quoted `"x y z"` argument, or three separate
numeric arguments. The default origin is `0 0 0`.
*-s* _scale_::
Set the initial size scale. The default is `1`.
*-t*::
List the primitive types supported by *make*. This mode does not accept a
new-shape name or primitive type.
*-h*, *-H*, *-?*::
Print usage help.
The possible values for _type_ are:
* arb8 -- ARB (eight vertices)
+1 -1
View File
@@ -29,7 +29,7 @@ The counter is shared across all calls within the same session and persists unti
[[options]]
== OPTIONS
*-s [num]*::
*-s* [_num_]::
Set the internal counter to `num`. If `num` is omitted, the counter is reset to 0.
[[examples]]
+6 -26
View File
@@ -10,10 +10,9 @@ man - Opens the graphical man page viewer.
[source]
----
man [cmdname]
man [-g | --gui] [cmdname]
man [--no-gui] [-L language] [-S section] [cmdname]
man [-k|-K] keyword
man [manual_page [section]]
man [-g | --gui] [manual_page [section]]
man [--no-gui] [-L language] [-S section] [manual_page [section]]
man [-h | --help]
----
@@ -25,11 +24,8 @@ Launches the BRL-CAD manual page viewer for the specified command name.
By default, *man* starts the GUI viewer when possible. It can also force GUI or
non-GUI mode and can select a manual language or manual section before
launching `brlman`.
The *-k* and *-K* options search manual pages instead of opening a named page.
The *-k* option searches names, synopses, and brief descriptions; *-K*
searches the full manual page text.
launching `brlman`. A trailing section argument is accepted for compatibility
with `man view 3`; the explicit *-S* option is preferred.
[[options]]
@@ -48,13 +44,7 @@ Force command-line viewer mode.
Select the manual language to request from `brlman`.
*-S*, *--section* _section_::
Select the manual section to request from `brlman`.
*-k* _keyword_::
Search manual page names, synopses, and brief descriptions.
*-K* _keyword_::
Search the full manual page text.
Select manual section `1`, `3`, `5`, or `n` to request from `brlman`.
[[examples]]
@@ -78,16 +68,6 @@ Launches `brlman` in non-GUI mode and requests section `1` for `rt`.
====
.Search command manual pages.
[example]
====
mged> **man -K "boolean operations"**
Opens the graphical manual page viewer with ranked full-text results.
====
[[author]]
== AUTHOR
+10 -1
View File
@@ -112,14 +112,23 @@ To simply test a density file for validity without attempting to import it, use
For manipulation of subsets of the data, the *get* and *set* subcommands are provided. *get* will return either one or a set of tuples matching the provided patterns. For density matching a tolerance may be specified to allow for approximate matches. The glob style of pattern matching is supported.
The *get* filters may be repeated. Numeric *--id* and *--density* filters
accept exact values and the `<`, `<=`, `>`, and `>=` range forms. Repeated
filters within one category are alternatives; active id, density, and name
categories are combined. A positional pattern matches either an id or a
material name.
[[matermappingdesc]]
== DENSITY DATABASE MANIPULATION - MAPPING MODE
The *map* mode of operation uses density information (either from a file or from the current database) to syncronize the *material_id* and *material_name* properties of objects. The *--ids-from-names* mode will use *material_name* properties, perform a lookup on the density database to find a corresponding id number, and update the *material_id*. If an optional mapping file is supplied, the name lookup will also find id assignments based on the name equivalencies specified by the map.
The *map* mode of operation uses density information (either from a file or from the current database) to synchronize the *material_id* and *material_name* properties of objects. The *--ids-from-names* mode will use *material_name* properties, perform a lookup on the density database to find a corresponding id number, and update the *material_id*. If an optional mapping file is supplied, the name lookup will also find id assignments based on the name equivalencies specified by the map.
For situations where a file has *material_id* attributes but no names, the *--names-from-ids* option will use density information to assign *material_name* attributes to those objects whose *material_id* values are present. It will also update existing *material_name* values.
Exactly one of *--ids-from-names* and *--names-from-ids* is required for a
mapping operation.
[[examples]]
== EXAMPLES
+33 -20
View File
@@ -10,44 +10,59 @@ material - Used to create, change, retrieve, assign, import, or view materials a
[source]
----
material assign {object_name_pattern} {material_name}
material assign {object_name} {material_name}
----
[source]
----
material create {object_name_pattern} {material_name}
material create {object_name} {material_name}
----
[source]
----
material import [--id | --name] {file_name}
material destroy {material_object}
----
[source]
----
material get {object_name_pattern} [property_group_name] {property_name}
material get {material_object} {name | parent | source}
----
[source]
----
material remove {object_name_pattern} [property_group_name] {property_name}
material get {material_object} {physical | mechanical | optical | thermal} {property_name}
----
[source]
----
material set {object_name_pattern} [property_group_name] {property_name} {property_value}
material set {material_object} {name | parent | source} {property_value}
----
[source]
----
material set {material_object} {physical | mechanical | optical | thermal} {property_name} {property_value}
----
[source]
----
material remove {material_object} {name | parent | source}
----
[source]
----
material remove {material_object} {physical | mechanical | optical | thermal} {property_name}
----
[source]
----
material import (--id | --name) {file_name}
----
[[description]]
== DESCRIPTION
Used to create, change, retrieve, assign, import, or view materials and their properties. Note that properties and property materials are cases sensitive and should not contain whitespace.
Used to create, change, retrieve, assign, import, or view materials and their properties. Property, property-group, and material-object names are case-sensitive and should not contain whitespace.
A newly formed material will have a minimum of the following data set on creation:
@@ -56,9 +71,7 @@ A newly formed material will have a minimum of the following data set on creatio
* name
Material objects are made up of a name (seperate from the object name), parent value, and source value. All of which are variable length strings.
Material objects have a name (separate from the database object name), parent value, and source value. All three are variable-length strings.
In addition to the three variable length string properties, material objects also contain four key-value lists used for storing additional material information:
@@ -80,7 +93,7 @@ Set the material_name property of the specified object to the specified material
*create*::
Initalize a new material and sets the name property to the value specified.
Initialize a new material and set its name property to the specified value.
*destroy*::
@@ -88,19 +101,19 @@ Destroy the material object.
*get*::
Retrieve a property of the material, optionally from one of the material's four material groups.
Retrieve a direct property (name, parent, or source), or a named property from one of the four material property groups.
*import*::
Import a density file's entries into material objects. --id denotes the material object names will be the id of the entry in the density table, --name the name of the entry in the density file.
Import a density file's entries into material objects. Exactly one naming mode is required: --id creates database object names from the density-table IDs (prefixed with `matl`), while --name uses the density-table material names.
*remove*::
Remove a material property from the object. (In the case of name, parent, and source this merely sets those values to NULL).
Remove a material property from the object. For name, parent, and source this clears the direct property.
*set*::
Set a material property on the object, optionally from one of the material's four material groups.
Set a direct property or a property in one of the material's four material groups.
+29 -5
View File
@@ -10,7 +10,7 @@ mirror - Mirrors a shape or combination across a given axis.
[source]
----
mirror [-p "point"] [-d "dir"] [-x|-y-|-z] [-o offset] {from_object to_object}
mirror [-p x/y/z] [-d x/y/z] [-x|-y|-z] [-o offset] from_object to_object [axis]
----
@@ -22,10 +22,34 @@ If __from_object__ is a shape, then it is copied to a new shape named
__to_object__ that is mirrored across the given axis. If __from_object__ is a
combination, then a new combination is created that contains exactly the same
members named __to_object__. Transformation matrices are added to mirror it
across the requested axis. The _-x, -y, & -z_ options tell the command which
axis to mirror the object. The _-p_ can be used to specify a point to mirror
about, and the _-d_ can be used to specify a direction vector to mirror about.
The *-h* option prints usage help.
across the requested axis.
== OPTIONS
*-x*, *-y*, *-z*::
Select the X, Y, or Z mirror-plane normal. Options are processed in command
order, so a later axis option or *-d* value replaces an earlier one.
*-p* _x/y/z_::
Set a point on the mirror plane.
*-d* _x/y/z_::
Set a nonzero mirror-plane normal.
For *-p* and *-d*, a finite three-component vector may be written as
`x/y/z`, `x,y,z`, `x;y;z`, a quoted `"x y z"` argument, or three separate
numeric arguments.
*-o* _offset_::
Offset the selected plane normal from the specified point in current units.
_axis_::
The optional trailing `x`, `y`, or `z` selector is accepted for compatibility
and overrides an earlier axis choice. Prefer *-x*, *-y*, or *-z* in new
commands.
*-h*, *-H*, *-?*::
Print usage help.
[[examples]]
+1 -1
View File
@@ -17,7 +17,7 @@ mv from to
[[description]]
== DESCRIPTION
The *move* command (also available as *mv*) renames an existing database object from `from` to `to`. It is a pure rename operation — the object's geometry is unchanged; only its name in the database directory is updated.
The *move* command (also available as *mv*) renames an existing database object from `from` to `to`. It is a pure rename operation — the object's geometry is unchanged; only its name in the database directory is updated. The destination is a database object name, not a path, and may not contain a slash.
The command performs the following steps:
+4 -4
View File
@@ -65,13 +65,13 @@ results suitable for programmatic processing.
== OPTIONS
*-scope path*::
*-scope* _path_::
Restrict the search to regions under the given path. The path may be a
single object path (for example "/world/room") or a Tcl list of paths.
If omitted the default scope is the model root "/". Paths that do not
begin with "/" are normalized by prepending "/".
*-ray_spacing distance|"auto"*::
*-ray_spacing* _distance_\|*auto*::
Spacing between sample rays (in the current local units, or with explicit
unit suffix). A smaller spacing produces a denser ray sampling and may
improve accuracy at increased cost. The special value *auto* lets the
@@ -79,12 +79,12 @@ command pick a spacing based on the geometry: it uses the diagonal of
the combined bounding box of the pair being sampled divided by 100. The
command reports the spacing values actually used when presenting results.
*-max_samples n*::
*-max_samples* _n_::
Maximum number of sample points along any sampled axis. The command
computes a sampling grid and clamps the number of samples to this value
to avoid excessive work. Must be a positive integer. Default is 100.
*-quiet 0|1*::
*-quiet* _0_\|_1_::
When 0 (default), the command prints a human-readable report. When 1 the
command returns a Tcl list of result records and prints nothing. Use
quiet mode for scripting and further post-processing.
+1 -2
View File
@@ -528,7 +528,7 @@ Halt push operations at the hierarchy level above regions. See <<npush_region_pu
Halt push operations at the hierarchy level above solids.
*-d max_depth*, *--max-depth max_depth*::
*-d*, *--max-depth* _max_depth_::
Halt push operations at the hierarchy level specified by __max_depth__. See <<npush_depth_properties,the depth limited push section>> for a description of the properties of depth-limited push that are worth understanding before using this option.
@@ -580,4 +580,3 @@ BRL-CAD Team
== BUG REPORTS
Reports of bugs or problems should be submitted via electronic mail to devs@brlcad.org
+7 -4
View File
@@ -10,14 +10,17 @@ pathlist - Lists all existing paths that start from the specified combinations a
[source]
----
pathlist {combinations}
pathlist [-n|--noleaf] combination
----
[[description]]
== DESCRIPTION
Lists all existing paths that start from the specified combinations and end at a primitive shape.
Lists all existing paths that start from the specified combination and end at a
primitive shape. The *-n* or *--noleaf* option omits the leaf object from
each reported path. The historical *-noleaf* spelling remains accepted for
compatibility.
[[examples]]
@@ -28,9 +31,9 @@ The example shows the use of the *pathlist* command to list all paths that start
.List all paths that start from given combinations and end at a primitive shape.
[example]
====
mged>**pathlist group1 region2**
mged>**pathlist group1**
Lists all existing paths that start from the _combinations group1_ and _region2_ and end at primitive shapes.
Lists all existing paths that start from _group1_ and end at primitive shapes.
====
+7 -7
View File
@@ -22,9 +22,9 @@ The *pix2fb* command reads a raw RGB pixel file (bottom-up row order) and sends
*Input size*
* *-w width* : Width of the input pixel file in pixels (default 512).
* *-n height* : Height of the input pixel file in pixels (default 512).
* *-s size* : Set both input width and height to `size` (square input).
* *-w width* : Positive width of the input pixel file in pixels (default 512).
* *-n height* : Positive height of the input pixel file in pixels (default 512).
* *-s size* : Set both input width and height to positive `size` (square input).
* *-a* : Autosize the input — attempt to determine dimensions from the file.
*Input region (crop)*
@@ -34,9 +34,9 @@ The *pix2fb* command reads a raw RGB pixel file (bottom-up row order) and sends
*Output (framebuffer) size*
* *-W scr_width* : Width of the framebuffer display area in pixels.
* *-N scr_height* : Height of the framebuffer display area in pixels.
* *-S scr_size* : Set both framebuffer width and height to `scr_size` (square output).
* *-W scr_width* : Positive width of the framebuffer display area in pixels.
* *-N scr_height* : Positive height of the framebuffer display area in pixels.
* *-S scr_size* : Set both framebuffer width and height to positive `scr_size` (square output).
*Output position*
@@ -50,7 +50,7 @@ The *pix2fb* command reads a raw RGB pixel file (bottom-up row order) and sends
* *-i* : Inverse (upside-down) — draw the image with inverted row order.
* *-1* : Force single-line writes (one row at a time).
* *-m lines* : Streamlined multi-line writes; write `lines` rows per call.
* *-p seconds* : Pause for `seconds` before closing the framebuffer and exiting.
* *-p seconds* : Pause for nonnegative `seconds` before closing the framebuffer and exiting.
[[examples]]
== EXAMPLES
+14 -3
View File
@@ -10,14 +10,25 @@ plot - Creates a UNIX plot of the current MGED display.
[source]
----
plot [-float] [-zclip] [-2d] [-grid] [output_file] [filter]
plot [-2|-3] [-f] [-g] [-z] output_file
plot [-2|-3] [-f] [-g] [-z] | filter [filter_argument ...]
----
[[description]]
== DESCRIPTION
Creates a UNIX plot of the current MGED display. If an __output_file__ is specified, the plot is stored in that file. If a _filter_ is specified, the output is sent to that _filter_. The *-float* option requests a plot file with real numbers rather than integers. The *-zclip* option requests that the plot be clipped to the viewing cube in the Z-direction. The *-2d* option requests a two-dimensional plot (the default is 3D). The *-grid* option is intended to include a grid in the plot, but is currently not implemented. This command does not use the _dm-plot_ display manager. The *pl* command performs the same function, but does use the _dm-plot_ display manager.
Creates a UNIX plot of the current MGED display. If an __output_file__ is
specified, the plot is stored in that file. If the first output word is `|`,
the remaining words form a filter command and the plot is written to its
standard input. The *-f* option requests a plot file with real numbers rather
than integers. The *-z* (or *-Z*) option requests that the plot be clipped to
the viewing cube in the Z-direction. The *-2* option requests a two-dimensional
plot; *-3* explicitly requests the default three-dimensional plot. The *-g*
option is accepted but grid output is not implemented. This command does not
use the _dm-plot_ display manager. The *pl* command performs the same function,
but does use the _dm-plot_ display manager. The dimension options *-2* and
*-3* are mutually exclusive.
[[examples]]
@@ -28,7 +39,7 @@ The example shows the use of the *plot* command to create a UNIX plot of the cur
.Create a UNIX plot of the current MGED display and send the results to a specified command.
[example]
====
mged>plot -float | pldebug
mged>plot -f | pldebug
Creates a UNIX plot of the current MGED display and pipe the results to the *pldebug* command.
+2 -1
View File
@@ -21,7 +21,8 @@ Writes the current GED display to the specified PNG _file_.
The implementation supports the following options:
* *-c r/g/b* - Set the background color using RGB values separated by non-numeric delimiters.
* *-c r/g/b* - Set the background color. Accepts packed `r/g/b`, `r,g,b`,
or `r;g;b` channels, or three separate 0--255 channel values.
* *-s size* - Set the output image size in pixels. The implementation requires a size of at least 50.
Without options, the command writes a 512x512 PNG image with a white background.

Some files were not shown because too many files have changed in this diff Show More