Compare commits
@@ -384,7 +384,7 @@ jobs:
|
||||
osx:
|
||||
name: macOS Clang
|
||||
needs: [linux]
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
@@ -403,7 +403,7 @@ jobs:
|
||||
- name: Prepare bext dependencies
|
||||
uses: ./brlcad/.github/actions/prepare-bext
|
||||
with:
|
||||
platform-channel: macos-14-${{ runner.arch }}-release
|
||||
platform-channel: macos-15-${{ runner.arch }}-release
|
||||
source-dir: ${{ github.workspace }}/brlcad
|
||||
output-dir: ${{ runner.temp }}/bext_output
|
||||
build-type: Release
|
||||
|
||||
@@ -177,7 +177,7 @@ jobs:
|
||||
osx_bext:
|
||||
name: macOS - BRL-CAD bext build
|
||||
needs: [linux_bext]
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
strategy:
|
||||
fail-fast: true
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
+32
-17
@@ -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(12115e6c5922e2db27a9b88e00dd714af5315f69)
|
||||
brlcad_bext_init(f8245e0bb31c5f96b17d8d32a988b9a7679fe4b9)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Define various utilities.
|
||||
@@ -678,8 +678,13 @@ endif(MSVC)
|
||||
# before use so platforms without GNU/LLVM-style linker options are skipped.
|
||||
brlcad_check_linker_flag(C "LINKER:--no-undefined" BRLCAD_LINKER_NO_UNDEFINED_C_FLAG_FOUND)
|
||||
brlcad_check_linker_flag(CXX "LINKER:--no-undefined" BRLCAD_LINKER_NO_UNDEFINED_CXX_FLAG_FOUND)
|
||||
if(BRLCAD_LINKER_NO_UNDEFINED_C_FLAG_FOUND AND BRLCAD_LINKER_NO_UNDEFINED_CXX_FLAG_FOUND)
|
||||
if(BRLCAD_LINKER_NO_UNDEFINED_C_FLAG_FOUND AND BRLCAD_LINKER_NO_UNDEFINED_CXX_FLAG_FOUND
|
||||
AND NOT BRLCAD_ENABLE_ADDRESS_SANITIZER)
|
||||
set(BRLCAD_LINKER_NO_UNDEFINED_FLAG "LINKER:--no-undefined" CACHE STRING "Linker flag requiring resolved shared library symbols" FORCE)
|
||||
else()
|
||||
# Clang links the AddressSanitizer runtime into executables, leaving its
|
||||
# shared-library instrumentation symbols unresolved until then.
|
||||
set(BRLCAD_LINKER_NO_UNDEFINED_FLAG "" CACHE STRING "Linker flag requiring resolved shared library symbols" FORCE)
|
||||
endif()
|
||||
brlcad_check_linker_flags(C BRLCAD_LINKER_WHOLE_ARCHIVE_GROUP_C_FLAG_FOUND "LINKER:--whole-archive" "LINKER:--no-whole-archive")
|
||||
brlcad_check_linker_flags(CXX BRLCAD_LINKER_WHOLE_ARCHIVE_GROUP_CXX_FLAG_FOUND "LINKER:--whole-archive" "LINKER:--no-whole-archive")
|
||||
@@ -1642,21 +1647,31 @@ if(NOT MSVC)
|
||||
endif(BRLCAD_WARNINGS OR BRLCAD_ENABLE_STRICT)
|
||||
|
||||
if(BRLCAD_ENABLE_COVERAGE)
|
||||
# TODO: These seem to GCC specific flags - should probably set up for clang
|
||||
# as well if that's our compiler...
|
||||
# https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
|
||||
# If we need different settings for different tools, should
|
||||
# encapsulate each tool's setup in a function
|
||||
check_c_flag(ftest-coverage)
|
||||
check_cxx_flag(ftest-coverage)
|
||||
if(FTEST_COVERAGE_C_FLAG_FOUND)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lgcov -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
else(FTEST_COVERAGE_C_FLAG_FOUND)
|
||||
message(SEND_ERROR "Building with coverage is not supported by BRL-CAD on this platform.")
|
||||
endif(FTEST_COVERAGE_C_FLAG_FOUND)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
check_c_flag(fprofile-instr-generate)
|
||||
check_cxx_flag(fprofile-instr-generate)
|
||||
check_c_flag(fcoverage-mapping)
|
||||
check_cxx_flag(fcoverage-mapping)
|
||||
if(NOT FPROFILE_INSTR_GENERATE_C_FLAG_FOUND OR
|
||||
NOT FPROFILE_INSTR_GENERATE_CXX_FLAG_FOUND OR
|
||||
NOT FCOVERAGE_MAPPING_C_FLAG_FOUND OR
|
||||
NOT FCOVERAGE_MAPPING_CXX_FLAG_FOUND)
|
||||
message(FATAL_ERROR "Clang source-based coverage is not supported by this toolchain.")
|
||||
endif()
|
||||
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
|
||||
add_link_options(-fprofile-instr-generate)
|
||||
else()
|
||||
check_c_flag(ftest-coverage)
|
||||
check_cxx_flag(ftest-coverage)
|
||||
if(FTEST_COVERAGE_C_FLAG_FOUND AND FTEST_COVERAGE_CXX_FLAG_FOUND)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lgcov -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov -ftest-coverage -fprofile-arcs -fprofile-update=atomic")
|
||||
else()
|
||||
message(FATAL_ERROR "GCC coverage is not supported by this toolchain.")
|
||||
endif()
|
||||
endif()
|
||||
endif(BRLCAD_ENABLE_COVERAGE)
|
||||
|
||||
if(BRLCAD_ENABLE_STRICT)
|
||||
|
||||
@@ -10,78 +10,106 @@ descriptive text that emphasizes or further describes significant
|
||||
changes made. See document footer for additional details.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
--- 20XX-XX-XX Release 7.46.0 ---
|
||||
--- 2026-10-0X Release 7.46.0 ---
|
||||
----------------------------------------------------------------------
|
||||
|
||||
* updated MGED and Archer for Tcl 8.6.18 and Itcl/Itk 4 - Cliff Yapp
|
||||
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
|
||||
* fixed writes to fileless geometry databases - Cliff Yapp
|
||||
* fixed nastran-g handling of large property IDs - Rupesh, 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 dxf-g invalid polyface idx crash - Meghna45-code, 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 messages - Cliff Yapp
|
||||
* fixed Tcl dialogs with multi-word titles and msgs - 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 Archer tree handling for object names with spaces - Cliff Yapp
|
||||
* fixed submodel transforms & relative database paths - Sean Morrison
|
||||
* fixed Archer tree handling for 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 an 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 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 database objects - Sean Morrison
|
||||
* new mkbuilding tool for parametric/OSM/CityJSON models - Sean Morrison
|
||||
* added arrange nest command for packing db objects - Sean Morrison
|
||||
* added mkbuilding 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 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
|
||||
* 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
|
||||
* 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 index - Sean Morrison
|
||||
* rt -b query option now supports a single value idx - 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
|
||||
* corrected rtarea sampling and exposed-area calculations - Cliff Yapp
|
||||
* fixed VOL data-file lookup and missing-data errors - Chris McGregor
|
||||
* corrected rtarea sampling/exposed-area calculations - Cliff Yapp
|
||||
* bot split now groups results and preserves mesh data - Cliff Yapp
|
||||
* bot decimate now preserves normals, UVs, and plate data - Cliff Yapp
|
||||
* bot decimate now preserves nrmls, UVs, and plate data - Cliff Yapp
|
||||
* added raytracing support for annotation objects - Cliff Yapp
|
||||
* fixed MGED X embedded framebuffer display manager crash - 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
|
||||
* 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
|
||||
@@ -103,26 +131,34 @@ changes made. See document footer for additional details.
|
||||
* 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 point scaling (via metaball_move_pnt) - Sean Morrison
|
||||
* added metaball pnt 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
|
||||
* 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 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
|
||||
* fixed fbcolor color ramp bug drawing the last color - Sean Morrison
|
||||
* corrected bwstat median and input error handling - 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 and pixembed edge fill - Sean Morrison
|
||||
* fixed bwcrop single-axis crops & 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
|
||||
@@ -131,7 +167,7 @@ changes made. See document footer for additional details.
|
||||
* 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
|
||||
@@ -142,14 +178,16 @@ changes made. See document footer for additional details.
|
||||
* 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 and MIME associations - Jordi Sayol
|
||||
* improved Debian application menus/MIME associations - Jordi Sayol
|
||||
* updated Tcl/Tk dependency to v8.6.18 using bundled Itcl - Cliff Yapp
|
||||
* 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
|
||||
@@ -161,7 +199,6 @@ changes made. See document footer for additional details.
|
||||
* 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
|
||||
@@ -270,7 +307,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 PNTS, DSP, and EBM - Sean Morrison
|
||||
* added g2asc/asc2g support for 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
|
||||
@@ -542,6 +579,7 @@ 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
|
||||
@@ -580,6 +618,7 @@ 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
BRL-CAD
|
||||
Release 7.44.2
|
||||
http://brlcad.org/
|
||||
BRL-CAD
|
||||
Release 7.46.0
|
||||
http://brlcad.org/
|
||||
|
||||
BRL-CAD is a powerful cross-platform open source combinatorial
|
||||
solid modeling system that includes an interactive 3D solid geometry
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
# 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. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,465 @@
|
||||
# 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. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
#!/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()
|
||||
@@ -0,0 +1,148 @@
|
||||
#!/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()
|
||||
+37182
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
||||
#!/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
+53
-22
@@ -94,13 +94,15 @@ record(const char *fmt, ...)
|
||||
bu_vls_vprintf(&str, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!BU_STR_EQUAL(LOGFILE, "")) {
|
||||
if (!BU_STR_EMPTY(LOGFILE)) {
|
||||
FILE *fp = fopen(LOGFILE, "a");
|
||||
fprintf(fp, "%s", bu_vls_addr(&str));
|
||||
fclose(fp);
|
||||
if (fp) {
|
||||
fprintf(fp, "%s", bu_vls_cstr(&str));
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
if (bu_str_false(QUIET)) {
|
||||
bu_log("%s", bu_vls_addr(&str));
|
||||
bu_log("%s", bu_vls_cstr(&str));
|
||||
}
|
||||
|
||||
bu_vls_free(&str);
|
||||
@@ -284,10 +286,15 @@ main(int ac, char *av[])
|
||||
void (*verbose_echo)(const char *, ...) = sink;
|
||||
void (*echo)(const char *, ...) = record;
|
||||
|
||||
bu_setprogname(av[0]);
|
||||
if (ac > 0 && av && av[0]) {
|
||||
bu_setprogname(av[0]);
|
||||
} else {
|
||||
bu_setprogname("benchmark");
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -305,7 +312,7 @@ main(int ac, char *av[])
|
||||
bu_setenv("HELP", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (bu_strncasecmp(av[arg], "instruct", 8)) {
|
||||
if (bu_strncasecmp(av[arg], "instruct", 8) == 0) {
|
||||
bu_setenv("INSTRUCTIONS", "1", 1);
|
||||
continue;
|
||||
}
|
||||
@@ -324,13 +331,12 @@ main(int ac, char *av[])
|
||||
bu_setenv("RUN", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (strchr(av[arg], '=')) {
|
||||
/* TODO: !!! make sure this still works */
|
||||
eq = strchr(av[arg], '=');
|
||||
if (eq) {
|
||||
char *var = bu_strdup(av[arg]);
|
||||
char *val = strtok(var, "=");
|
||||
if (var && val) {
|
||||
bu_setenv(var, val, 1);
|
||||
}
|
||||
char *eq_in_var = var + (eq - av[arg]);
|
||||
*eq_in_var = '\0';
|
||||
bu_setenv(var, eq_in_var + 1, 1);
|
||||
bu_free(var, "strdup av[arg]");
|
||||
continue;
|
||||
}
|
||||
@@ -343,7 +349,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", av[0]);
|
||||
bu_log("Usage: %s [command(s)] [OPTION=value] [RT_OPTIONS]\n", bu_getprogname());
|
||||
bu_log("\n");
|
||||
bu_log("Available commands:\n");
|
||||
bu_log(" clean\n");
|
||||
@@ -378,7 +384,10 @@ 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", av[0]);
|
||||
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_exit(1, NULL);
|
||||
}
|
||||
|
||||
@@ -443,6 +452,9 @@ 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);
|
||||
}
|
||||
|
||||
@@ -466,7 +478,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", av[0]);
|
||||
bu_log("Running '%s clobber' will remove run logs.\n", bu_getprogname());
|
||||
}
|
||||
bu_log("\n");
|
||||
|
||||
@@ -546,6 +558,9 @@ 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);
|
||||
}
|
||||
|
||||
@@ -555,15 +570,19 @@ main(int ac, char *av[])
|
||||
***/
|
||||
|
||||
if (bu_str_false(getenv("RUN"))) {
|
||||
bu_exit(1, "Type '%s help' for usage.\n", av[0]);
|
||||
bu_vls_free(&rtargs);
|
||||
bu_vls_free(&vp);
|
||||
bu_vls_free(&str);
|
||||
bu_exit(1, "Type '%s help' for usage.\n", bu_getprogname());
|
||||
}
|
||||
|
||||
/* 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_addr(&str);
|
||||
logfile = bu_vls_cstr(&str);
|
||||
bu_setenv("LOGFILE", logfile, 1);
|
||||
fd = open(logfile, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0 || !bu_file_writable(logfile)) {
|
||||
@@ -573,6 +592,9 @@ 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"))) {
|
||||
@@ -604,9 +626,10 @@ 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", av[0], rfc2822);
|
||||
echo("Running %s on %s\n", bu_getprogname(), rfc2822);
|
||||
echo("Logging output to %s\n", logfile ? logfile : "disabled");
|
||||
echo("%s\n\n", bu_vls_addr(&v));
|
||||
echo("%s\n\n", bu_vls_cstr(&v));
|
||||
bu_vls_free(&v);
|
||||
}
|
||||
|
||||
|
||||
@@ -813,6 +836,7 @@ main(int ac, char *av[])
|
||||
estimate = maxtime;
|
||||
|
||||
echo("Estimated time is %s\n", format_elapsed(estimate));
|
||||
bu_vls_free(&elapsed);
|
||||
}
|
||||
|
||||
/************************
|
||||
@@ -830,7 +854,7 @@ main(int ac, char *av[])
|
||||
ret += bench("sphflake");
|
||||
|
||||
echo("\n... Done.\n");
|
||||
echo("Total testing time elapsed: %.2lfs\n", format_elapsed(bu_gettime() - start));
|
||||
echo("Total testing time elapsed: %s\n", format_elapsed(bu_gettime() - start));
|
||||
|
||||
if (ret != 0) {
|
||||
echo("\n");
|
||||
@@ -843,8 +867,11 @@ 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", av[0]);
|
||||
echo("Run '%s clean' to remove generated pix files.\n", bu_getprogname());
|
||||
echo("Benchmark testing failed.\n");
|
||||
bu_vls_free(&rtargs);
|
||||
bu_vls_free(&vp);
|
||||
bu_vls_free(&str);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -867,7 +894,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", av[0]);
|
||||
echo("Run '%s clean' to remove generated pix files.\n", bu_getprogname());
|
||||
echo("\n");
|
||||
|
||||
echo("Summary:\n");
|
||||
@@ -900,6 +927,7 @@ main(int ac, char *av[])
|
||||
echo("\n");
|
||||
}
|
||||
}
|
||||
bu_vls_free(&performance);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -938,6 +966,9 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -70,18 +70,21 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
-6
@@ -50,14 +50,15 @@ double
|
||||
average(int ac, double av[])
|
||||
{
|
||||
double total = 0.0;
|
||||
int count = ac;
|
||||
|
||||
if (ac < 1)
|
||||
return -0.0;
|
||||
if (ac < 1 || !av)
|
||||
return 0.0;
|
||||
|
||||
while (ac-- > 0) {
|
||||
total += av[ac];
|
||||
}
|
||||
return total / ac;
|
||||
return total / (double)count;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,8 +69,8 @@ variance(int ac, double av[])
|
||||
double err = 0.0;
|
||||
double num = ac;
|
||||
|
||||
if (ac < 1)
|
||||
return -0.0;
|
||||
if (ac < 1 || !av)
|
||||
return 0.0;
|
||||
else if (ac == 1)
|
||||
return 0.0;
|
||||
|
||||
@@ -81,7 +82,7 @@ variance(int ac, double av[])
|
||||
}
|
||||
|
||||
/* return the sample variance */
|
||||
return err / (num - 1);
|
||||
return err / (num - 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+34
-22
@@ -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 = argv[0];
|
||||
const char *argv0 = (argc > 0 && argv && argv[0]) ? argv[0] : "pixcmp";
|
||||
|
||||
FILE *f1 = NULL;
|
||||
FILE *f2 = NULL;
|
||||
@@ -227,7 +227,9 @@ main(int argc, char *argv[])
|
||||
size_t f2_skip = 0;
|
||||
size_t stop_after = 0;
|
||||
|
||||
bu_setprogname(argv[0]);
|
||||
if (argc > 0 && argv && argv[0]) {
|
||||
bu_setprogname(argv[0]);
|
||||
}
|
||||
|
||||
/* process opts */
|
||||
while ((c = bu_getopt(argc, argv, "sdbi:n:q?")) != -1) {
|
||||
@@ -320,6 +322,8 @@ 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);
|
||||
}
|
||||
|
||||
@@ -328,6 +332,8 @@ 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");
|
||||
}
|
||||
|
||||
@@ -342,27 +348,33 @@ 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); */
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
{
|
||||
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] : "-");
|
||||
|
||||
/* 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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-5
@@ -64,21 +64,32 @@ int
|
||||
run(int ac, char *av[])
|
||||
{
|
||||
int retval;
|
||||
const char *run_geomname = av[0];
|
||||
const char *run_geometry = av[1];
|
||||
long int hypersample = strtod(av[2], NULL);
|
||||
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);
|
||||
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", av[0], hypersample, 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",
|
||||
run_target, hypersample, bu_vls_cstr(&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", av[0], retval);
|
||||
echo("DEBUG: Running %s returned %d\n", run_target, retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -4,38 +4,54 @@
|
||||
:manmanual: BRL-CAD
|
||||
|
||||
== NAME
|
||||
pixdiff - highlight samples which differ between two pix or bw files
|
||||
pixdiff - highlight differences between two pix or bw images
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source]
|
||||
----
|
||||
pixdiff _file1.pix_ _file2.pix_ > _out.pix_
|
||||
pixdiff _file1.bw_ _file2.bw_ > _out.bw_
|
||||
pixdiff -b _file1.bw_ _file2.bw_ > _out.bw_
|
||||
----
|
||||
|
||||
|
||||
[[description]]
|
||||
== DESCRIPTION
|
||||
|
||||
*pixdiff* compares two raw *pix*(5) or *bw*(5) images byte by byte and
|
||||
writes a difference image of the same size to standard output. Bytes that
|
||||
differ by +/-1 are written at intensity 192, while larger differences are
|
||||
written at full intensity 255. Matching bytes are written at half their
|
||||
original intensity, providing visual context for locating differences.
|
||||
By default, *pixdiff* compares raw *pix*(5) images as RGB pixels and writes
|
||||
a PIX difference image to standard output. When all three channels of a
|
||||
pixel match, it writes a dim grayscale version of that pixel to all three
|
||||
output channels. When any channel differs, each matching channel is written
|
||||
as zero, each channel differing by one is written as 192, and each channel
|
||||
differing by more than one is written as 255.
|
||||
|
||||
Because the comparison does not interpret pixel structure, no format option
|
||||
is needed and *pixdiff* is independent of image resolution. The two inputs
|
||||
must be the same size in bytes; otherwise the program reports the mismatch
|
||||
and exits. Either input file may be given as
|
||||
With *-b*, *pixdiff* compares raw *bw*(5) images one byte at a time and
|
||||
writes a BW difference image. Differing samples use the same 192 and 255
|
||||
intensities; matching samples are written at half their original intensity.
|
||||
|
||||
No image dimensions are needed. The two inputs must be the same size in
|
||||
bytes, and PIX input must contain complete three-byte pixels. Otherwise,
|
||||
*pixdiff* reports an error. Either input file may be given as
|
||||
*-* to read from standard input. Output must be redirected; *pixdiff*
|
||||
refuses to write a raw image stream to a terminal.
|
||||
|
||||
Upon completion, the count of bytes that matched, that were off by 1, and
|
||||
that were off by many is reported on standard error.
|
||||
Upon completion, *pixdiff* reports matching, off-by-one, and larger-difference
|
||||
channel or sample counts on standard error.
|
||||
|
||||
Also see *bwdiff*(1), which can also operate on *pix*(5) files and can
|
||||
produce other kinds of difference output.
|
||||
*bwdiff -n -b* produces a similar BW highlight image, but writes 255 rather
|
||||
than 192 for off-by-one differences. The default *bwdiff*(1) output instead
|
||||
shows signed differences around a neutral gray.
|
||||
|
||||
|
||||
[[options]]
|
||||
== OPTIONS
|
||||
|
||||
*-b*::
|
||||
Treat both inputs and the output as one-byte-per-pixel BW images. Without
|
||||
this option, use three-byte-per-pixel PIX images.
|
||||
|
||||
*-h*::
|
||||
Show usage information.
|
||||
|
||||
|
||||
[[examples]]
|
||||
@@ -59,10 +75,10 @@ on standard error give a quick quantitative sense of how much changed.
|
||||
====
|
||||
[source,bash]
|
||||
----
|
||||
pixdiff depth_a.bw depth_b.bw > depth_diff.bw
|
||||
pixdiff -b depth_a.bw depth_b.bw > depth_diff.bw
|
||||
----
|
||||
Writes a grayscale highlight image using the same byte comparison and
|
||||
statistics as the color example; no format option is needed.
|
||||
Writes a grayscale highlight image using byte-wise comparison. Matching
|
||||
samples retain half their input intensity as context.
|
||||
====
|
||||
|
||||
|
||||
|
||||
@@ -200,6 +200,56 @@ ____
|
||||
|
||||
The LIBRT_DEBUG environment variable may be set to the hexadecimal bit vector as described by the DEBUG_* flags listed in the raytrace.h header. Similarly, many LIBRT applications provide a "-x #" command-line option which will take precedence over the environment variable.
|
||||
|
||||
The RT_DEBUG_RTCMP flag (0x10000000) (set with LIBRT_DEBUG=10000000)
|
||||
sets up rtcmp capture, but recording starts disabled. Set
|
||||
LIBRT_RTCMP_FILE before enabling the flag, then call
|
||||
rt_rtcmp_capture_set_enabled(1) from the application or a debugger to
|
||||
record selected rays. Call rt_rtcmp_capture_set_enabled(0) to stop
|
||||
recording. Enabling returns -1 if the debug flag is unset or the output
|
||||
writer failed to initialize; disabling returns 0 even before setup. A
|
||||
ray must begin while recording is enabled, and leaving recording
|
||||
disabled when it finishes suppresses its record. The debug flag must be
|
||||
set before concurrent ray shooting; use the setter to change recording
|
||||
state while rays are running.
|
||||
|
||||
Captured hits append one high-precision rtcmp JSON record per ray with
|
||||
final partitions. Misses produce no record. librt never clears the
|
||||
output file; the caller must clear or rotate it before a new comparison
|
||||
as needed. Separate processes must not write to the same file
|
||||
concurrently. Pending records are flushed within two seconds under
|
||||
normal operation and during normal process shutdown; call
|
||||
rt_rtcmp_capture_flush() to wait for pending records when using a
|
||||
debugger. Disabling recording does not discard records already queued. A
|
||||
process terminated abnormally may lose pending records. rtcmp comparison
|
||||
files should use the same hit-only capture mode on both sides; its
|
||||
generation mode also includes misses. The output can be expanded to also
|
||||
include primitive segments if LIBRT_RTCMP_PRIMITIVES is set to 1 before
|
||||
capture is set up.
|
||||
|
||||
For example, run a single-threaded ray tracing application in a debugger
|
||||
and stop at `rt_shootray` for the suspect ray. Capture just that call,
|
||||
then compare it with a capture of the same ray from a reference build:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
$ LIBRT_DEBUG=10000000 LIBRT_RTCMP_FILE=trial.json \
|
||||
gdb --args ./ray_application model.g
|
||||
(gdb) break rt_shootray
|
||||
(gdb) run
|
||||
(gdb) call rt_rtcmp_capture_set_enabled(1)
|
||||
(gdb) finish
|
||||
(gdb) call rt_rtcmp_capture_set_enabled(0)
|
||||
(gdb) call rt_rtcmp_capture_flush()
|
||||
(gdb) quit
|
||||
$ rtcmp -c reference.json trial.json
|
||||
----
|
||||
|
||||
Continue to the suspect ray before enabling capture if the breakpoint
|
||||
first stops on another ray. Produce `reference.json` with the same ray
|
||||
and the same capture mode; set LIBRT_RTCMP_PRIMITIVES=1 for both runs
|
||||
when primitive segments are needed to locate a difference before Boolean
|
||||
evaluation.
|
||||
|
||||
The LIBRT_V4FLIP environment variable may be set to a true or false value to respectively force or disable endianness interpretation of v4 geometry database files. The default behavior is to automatically detect whether flipping the endian interpretation will help LIBRT read a binary-incompatible v4 geometry database file. Setting LIBRT_V4FLIP will override automatic detection.
|
||||
|
||||
|
||||
|
||||
@@ -61,5 +61,4 @@ Author: Paul Mackerras (paulus@cs.anu.edu.au),
|
||||
|
||||
file:/src/libtclcad/tkImgFmtPIX.c
|
||||
file:/src/tclscripts/cad_clrpick.tcl
|
||||
file:/src/tclscripts/html_library.tcl
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "bg/clip.h"
|
||||
#include "bg/lseg.h"
|
||||
#include "bg/obr.h"
|
||||
#include "bg/pca.h"
|
||||
#include "bg/plane.h"
|
||||
#include "bg/polygon.h"
|
||||
#include "bg/sat.h"
|
||||
|
||||
+4
-4
@@ -50,12 +50,12 @@ BG_EXPORT extern int bg_lseg_clip(fastf_t *xp1, fastf_t *yp1, fastf_t *xp2, fast
|
||||
* The RPP has faces parallel to the coordinate planes and is defined
|
||||
* by a minimum point and a maximum point.
|
||||
*
|
||||
* FIXME: the function name implies this takes a point,dir for a,b but
|
||||
* it actually takes a line segment going from points a to b!
|
||||
* Despite its historical name, this function clips the finite line segment
|
||||
* from a to b.
|
||||
*
|
||||
* Returns -
|
||||
* 0 if ray does not hit RPP,
|
||||
* !0 if ray hits RPP.
|
||||
* 0 if the segment does not hit the RPP,
|
||||
* !0 if the segment hits the RPP.
|
||||
*
|
||||
* Implicit Return -
|
||||
* if !0 was returned, "a" and "b" have been clipped to the RPP.
|
||||
|
||||
+6
-3
@@ -126,9 +126,12 @@ BG_EXPORT extern int bg_3d_coplanar_obr(point_t *center,
|
||||
* \endverbatim
|
||||
*
|
||||
*
|
||||
* @param[out] pnts eight points of oriented bounding box
|
||||
* @param points_3d array of 3D points
|
||||
* @param pnt_cnt number of points in pnts array
|
||||
* @param[out] pnts eight non-NULL, caller-provided point_t storage
|
||||
* locations for the oriented bounding box vertices
|
||||
* @param[in] points_3d flat array containing 3 * pnt_cnt coordinate values
|
||||
* @param[in] pnt_cnt number of points in points_3d
|
||||
*
|
||||
* @return 0 on success and -1 for invalid input or when no box can be fit
|
||||
*/
|
||||
BG_EXPORT extern int bg_3d_obb(point_t **pnts,
|
||||
const fastf_t *points_3d,
|
||||
|
||||
+4
-4
@@ -21,7 +21,7 @@
|
||||
/*----------------------------------------------------------------------*/
|
||||
/** @addtogroup bg_pca
|
||||
*
|
||||
* Principle Component Analysis
|
||||
* Principal Component Analysis
|
||||
*
|
||||
* Calculates an XYZ coordinate system such that it aligns with the largest
|
||||
* variations in the supplied data. Intuitively, it "aligns" with the
|
||||
@@ -50,7 +50,7 @@
|
||||
* point_t p;
|
||||
* for (size_t i = 0; i < pntcnt; i++) {
|
||||
* MAT4X3PNT(p, RT, pnts[i]);
|
||||
* VMOVE(pnts[i], v);
|
||||
* VMOVE(pnts[i], p);
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
@@ -69,7 +69,7 @@ __BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Perform a Principle Component Analysis on a set of points.
|
||||
* Perform a Principal Component Analysis on a set of points.
|
||||
*
|
||||
* Outputs are a center point and XYZ vectors for the coordinate system.
|
||||
*
|
||||
@@ -88,7 +88,7 @@ BG_EXPORT extern int bg_pca(point_t *c, vect_t *xaxis, vect_t *yaxis, vect_t *za
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* BG_PLANE_H */
|
||||
#endif /* BG_PCA_H */
|
||||
/** @} */
|
||||
/*
|
||||
* Local Variables:
|
||||
|
||||
+7
-4
@@ -1171,9 +1171,10 @@ BG_EXPORT extern int bg_isect_planes(point_t pt,
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Given an origin and a normal, create a plane_t.
|
||||
* Given an origin and a normal, create a plane_t with a unit normal.
|
||||
* The input point and normal are not modified. A zero-length normal fails.
|
||||
*/
|
||||
BG_EXPORT extern int bg_plane_pt_nrml(plane_t *p, point_t pt, vect_t nrml);
|
||||
BG_EXPORT extern int bg_plane_pt_nrml(plane_t *p, const point_t pt, const vect_t nrml);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
@@ -1188,13 +1189,15 @@ BG_EXPORT extern int bg_fit_plane(point_t *c, vect_t *n, size_t npnts, point_t *
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Find the closest U,V point on the plane p to 3d point pt.
|
||||
* Find the closest U,V point on the plane p to 3d point pt. The plane normal
|
||||
* need not be unit length.
|
||||
*/
|
||||
BG_EXPORT extern int bg_plane_closest_pt(fastf_t *u, fastf_t *v, plane_t *p, point_t *pt);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Return the 3D point on the plane at parametric coordinates u, v.
|
||||
* Return the 3D point on the plane at parametric coordinates u, v. The plane
|
||||
* normal need not be unit length.
|
||||
*/
|
||||
BG_EXPORT extern int bg_plane_pt_at(point_t *pt, plane_t *p, fastf_t u, fastf_t v);
|
||||
|
||||
|
||||
@@ -293,6 +293,7 @@ BG_EXPORT extern int bg_3d_polygon_area(fastf_t *area, size_t npts, const point_
|
||||
* @param[in] npts Number of point_ts, stored in pts
|
||||
* @param[in] pts all points of the polygon, sorted counter-clockwise.
|
||||
* The array mustn't contain duplicated points or non-coplanar points.
|
||||
* A zero-area polygon fails.
|
||||
*
|
||||
* @return 0 if calculation was successful
|
||||
* @return 1 if calculation failed, e.g. because one in-parameter is a NULL-pointer
|
||||
@@ -307,7 +308,7 @@ BG_EXPORT extern int bg_3d_polygon_centroid(point_t *cent, size_t npts, const po
|
||||
*@param[in] npts Number of points, pts contains
|
||||
*@param pts Array of point_ts, building a convex polygon. Duplicated points
|
||||
*aren't allowed. The points in the array will be sorted counter-clockwise.
|
||||
*@param[in] cmp Plane equation of the polygon
|
||||
*@param[in] cmp Plane equation of the polygon. Its normal must be nonzero.
|
||||
*
|
||||
*@return 0 if calculation was successful
|
||||
*@return 1 if calculation failed, e.g. because pts is a NULL-pointer
|
||||
|
||||
+20
-8
@@ -39,7 +39,9 @@
|
||||
__BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* Test for an intersection between a line and an Axis-Aligned Bounding Box (AABB).
|
||||
* Test for an intersection between an infinite line and an Axis-Aligned
|
||||
* Bounding Box (AABB). ldir need not be unit length, but must be nonzero.
|
||||
* aabb_extent supplies the positive half extents along the coordinate axes.
|
||||
*
|
||||
* Returns 1 if they intersect, 0 otherwise.
|
||||
*/
|
||||
@@ -50,7 +52,10 @@ bg_sat_line_aabb(
|
||||
);
|
||||
|
||||
/**
|
||||
* Test for an intersection between a line and an Oriented Bounding Box (OBB).
|
||||
* Test for an intersection between an infinite line and an Oriented Bounding
|
||||
* Box (OBB). ldir need not be unit length, but must be nonzero. Each OBB
|
||||
* extent vector points from the center to a face center; nonzero vectors must
|
||||
* be mutually perpendicular, and a zero vector represents a degenerate axis.
|
||||
*
|
||||
* Returns 1 if they intersect, 0 otherwise.
|
||||
*/
|
||||
@@ -61,7 +66,9 @@ bg_sat_line_obb(
|
||||
);
|
||||
|
||||
/**
|
||||
* Test for an intersection between a triangle and an Axis-Aligned Bounding Box (AABB).
|
||||
* Test for an intersection between a triangle and an Axis-Aligned Bounding
|
||||
* Box (AABB). extent supplies the positive half extents along the coordinate
|
||||
* axes.
|
||||
*
|
||||
* Returns 1 if they intersect, 0 otherwise.
|
||||
*/
|
||||
@@ -72,7 +79,10 @@ bg_sat_tri_aabb(
|
||||
);
|
||||
|
||||
/**
|
||||
* Test for an intersection between a triangle and an Oriented Bounding Box (OBB).
|
||||
* Test for an intersection between a triangle and an Oriented Bounding Box
|
||||
* (OBB). Each extent vector points from the center to a face center; nonzero
|
||||
* vectors must be mutually perpendicular, and a zero vector represents a
|
||||
* degenerate axis.
|
||||
*
|
||||
* Returns 1 if they intersect, 0 otherwise.
|
||||
*/
|
||||
@@ -85,8 +95,9 @@ bg_sat_tri_obb(
|
||||
/**
|
||||
* Test for an intersection between an Axis-Aligned Bounding Box (AABB) and an
|
||||
* Oriented Bounding Box (OBB). The latter is defined by a center point and
|
||||
* three perpendicular vectors from the center to the centers of the various
|
||||
* faces.
|
||||
* three extent vectors from the center to the centers of the various faces.
|
||||
* Nonzero extent vectors must be mutually perpendicular; a zero vector
|
||||
* represents a degenerate axis.
|
||||
*
|
||||
* Returns 1 if they intersect, 0 otherwise.
|
||||
*/
|
||||
@@ -98,8 +109,9 @@ bg_sat_aabb_obb(
|
||||
|
||||
/**
|
||||
* Test for an intersection between two Oriented Bounding Boxes (OBBs). The
|
||||
* boxes are defined by a center point and three perpendicular vectors from the
|
||||
* center to the centers of the various faces.
|
||||
* boxes are defined by a center point and three extent vectors from the center
|
||||
* to the centers of the various faces. Nonzero extent vectors must be
|
||||
* mutually perpendicular; a zero vector represents a degenerate axis.
|
||||
*
|
||||
* Returns 1 if they intersect, 0 otherwise.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ BG_EXPORT extern double bg_tri_closest_pt(
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* BG_TRI_TRI_H */
|
||||
#endif /* BG_TRI_PT_H */
|
||||
/** @} */
|
||||
/*
|
||||
* Local Variables:
|
||||
|
||||
@@ -54,7 +54,7 @@ BG_EXPORT extern int bg_isect_tri_line(point_t *isect,
|
||||
* If isect is non-NULL, it is written only when an intersection is found.
|
||||
*/
|
||||
BG_EXPORT extern int bg_isect_tri_ray(const point_t orig,
|
||||
const point_t dir,
|
||||
const vect_t dir,
|
||||
const point_t vert0,
|
||||
const point_t vert1,
|
||||
const point_t vert2,
|
||||
|
||||
@@ -87,7 +87,11 @@ BG_EXPORT extern int bg_trimesh_oriented(int vcnt, int fcnt, fastf_t *v, int *f)
|
||||
/**
|
||||
* Check if a mesh is topologically solid. Returns 1 if the mesh is NOT SOLID
|
||||
* and 0 if the mesh is SOLID. A SOLID (0) outcome indicates the mesh satisfies
|
||||
* all three criteria: Closed, Manifold, Oriented
|
||||
* all three criteria: Closed, Manifold, Oriented. If @p bedges is non-NULL,
|
||||
* it is set to NULL when no edge diagnostics are present, or to a bu_calloc()
|
||||
* allocated array of vertex-index pairs for unmatched, misoriented, and excess
|
||||
* edges. The caller must bu_free() a non-NULL result. Use
|
||||
* bg_trimesh_solid2() when structured diagnostics and their counts are needed.
|
||||
*/
|
||||
BG_EXPORT extern int bg_trimesh_solid(int vcnt, int fcnt, fastf_t *v, int *f, int **bedges);
|
||||
|
||||
|
||||
+15
-12
@@ -214,8 +214,8 @@ BN_EXPORT extern void bn_mat_ae(mat_t m,
|
||||
double elev);
|
||||
|
||||
/**
|
||||
* Find the azimuth and elevation angles that correspond to the
|
||||
* direction (not including twist) given by a direction vector.
|
||||
* Find the azimuth and elevation angles, in degrees, that correspond
|
||||
* to the direction (not including twist) given by a direction vector.
|
||||
*/
|
||||
BN_EXPORT extern void bn_ae_vec(fastf_t *azp,
|
||||
fastf_t *elp,
|
||||
@@ -236,14 +236,16 @@ BN_EXPORT extern void bn_aet_vec(fastf_t *az,
|
||||
fastf_t accuracy);
|
||||
|
||||
/**
|
||||
* Find a unit vector from the origin given azimuth and elevation.
|
||||
* Find a unit vector from the origin given azimuth and elevation in
|
||||
* radians.
|
||||
*/
|
||||
BN_EXPORT extern void bn_vec_ae(vect_t vec,
|
||||
fastf_t az,
|
||||
fastf_t el);
|
||||
|
||||
/**
|
||||
* Find a vector from the origin given azimuth, elevation, and distance.
|
||||
* Find a vector from the origin given azimuth and elevation in radians,
|
||||
* and distance.
|
||||
*/
|
||||
BN_EXPORT extern void bn_vec_aed(vect_t vec,
|
||||
fastf_t az,
|
||||
@@ -310,8 +312,10 @@ BN_EXPORT extern void bn_vec_perp(vect_t new_vec,
|
||||
* space by the angle between the two. There are many candidate
|
||||
* matrices.
|
||||
*
|
||||
* The input 'from' and 'to' vectors need not be unit length.
|
||||
* MAT4X3VEC(to, m, from) is the identity that is created.
|
||||
* The input 'from' and 'to' vectors need not be unit length. They are
|
||||
* normalized internally. Near-parallel inputs are handled using the
|
||||
* angular tolerance in 'tol'. If either input cannot be normalized,
|
||||
* the result is the identity matrix.
|
||||
*
|
||||
*/
|
||||
BN_EXPORT extern void bn_mat_fromto(mat_t m,
|
||||
@@ -344,12 +348,11 @@ BN_EXPORT extern void bn_mat_zrot(mat_t m,
|
||||
double cosz);
|
||||
|
||||
/**
|
||||
* Given a direction vector D of unit length, product a matrix which
|
||||
* rotates that vector D onto the -Z axis. This matrix will be
|
||||
* suitable for use as a "model2view" matrix.
|
||||
*
|
||||
* XXX This routine will fail if the vector is already more or less
|
||||
* aligned with the Z axis.
|
||||
* Given a nonzero direction vector D, produce a matrix which
|
||||
* rotates D onto the -Z axis. D is normalized internally. Z-axis
|
||||
* directions use a deterministic roll, and a zero direction produces
|
||||
* the identity matrix. This matrix will be suitable for use as a
|
||||
* model2view matrix.
|
||||
*
|
||||
* This is done in several steps.
|
||||
*
|
||||
|
||||
@@ -31,17 +31,62 @@
|
||||
#define BN_MULTIPOLY_H
|
||||
|
||||
#include "common.h"
|
||||
#include "bu/magic.h"
|
||||
#include "bn/defines.h"
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef struct bn_multipoly {
|
||||
uint32_t magic;
|
||||
/**< Number of coefficients in the first polynomial variable. */
|
||||
int dgrs;
|
||||
/**< Number of coefficients in the second polynomial variable. */
|
||||
int dgrt;
|
||||
/**< Coefficient of S^s * T^t is cf[s][t]. */
|
||||
double **cf;
|
||||
} bn_multipoly_t;
|
||||
|
||||
|
||||
#define BN_CK_MULTIPOLY(_p) BU_CKMAG(_p, BN_MULTIPOLY_MAGIC, "struct bn_multipoly")
|
||||
|
||||
/**
|
||||
* Allocate a zero-valued bivariate polynomial with the specified
|
||||
* coefficient counts. Both counts must be positive.
|
||||
*/
|
||||
BN_EXPORT extern struct bn_multipoly *bn_multipoly_new(int dgrs, int dgrt);
|
||||
|
||||
/** Release a bivariate polynomial allocated by bn_multipoly_new(). */
|
||||
BN_EXPORT extern void bn_multipoly_free(struct bn_multipoly *poly);
|
||||
|
||||
/**
|
||||
* Grow a polynomial to at least the specified coefficient counts.
|
||||
* Return NULL without modifying it if a coefficient storage size would overflow.
|
||||
*/
|
||||
BN_EXPORT extern struct bn_multipoly *bn_multipoly_grow(struct bn_multipoly *poly,
|
||||
int dgrs,
|
||||
int dgrt);
|
||||
|
||||
/**
|
||||
* Set the coefficient of S^s * T^t, growing the polynomial as needed.
|
||||
* Return NULL without modifying it for negative indices or unrepresentable counts
|
||||
* or storage sizes.
|
||||
*/
|
||||
BN_EXPORT extern struct bn_multipoly *bn_multipoly_set(struct bn_multipoly *poly,
|
||||
int s,
|
||||
int t,
|
||||
double value);
|
||||
|
||||
/** Return the sum of two bivariate polynomials. */
|
||||
BN_EXPORT extern struct bn_multipoly *bn_multipoly_add(const struct bn_multipoly *p1,
|
||||
const struct bn_multipoly *p2);
|
||||
|
||||
/**
|
||||
* Return the product of two bivariate polynomials, or NULL if an operand count is
|
||||
* nonpositive or a product coefficient count would exceed INT_MAX.
|
||||
*/
|
||||
BN_EXPORT extern struct bn_multipoly *bn_multipoly_mul(const struct bn_multipoly *p1,
|
||||
const struct bn_multipoly *p2);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* BN_MULTIPOLY_H */
|
||||
|
||||
+20
-4
@@ -45,7 +45,10 @@ __BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* Polynomial data type
|
||||
* bn_poly->cf[n] corresponds to X^n
|
||||
*
|
||||
* Coefficients are stored from the highest to the lowest degree:
|
||||
* `cf[0]` is the coefficient of `X^dgr` and `cf[dgr]` is the
|
||||
* constant coefficient.
|
||||
*/
|
||||
typedef struct bn_poly {
|
||||
uint32_t magic;
|
||||
@@ -63,6 +66,9 @@ typedef struct bn_poly {
|
||||
*
|
||||
* @brief
|
||||
* multiply two polynomials
|
||||
*
|
||||
* The output may alias either input. If the result exceeds
|
||||
* BN_MAX_POLY_DEGREE, returns BN_POLY_NULL without modifying product.
|
||||
*/
|
||||
BN_EXPORT extern struct bn_poly *bn_poly_mul(struct bn_poly *product,
|
||||
const struct bn_poly *m1,
|
||||
@@ -81,6 +87,8 @@ BN_EXPORT extern struct bn_poly *bn_poly_scale(struct bn_poly *eqn,
|
||||
* bn_poly_add
|
||||
* @brief
|
||||
* add two polynomials
|
||||
*
|
||||
* The output may alias either input.
|
||||
*/
|
||||
BN_EXPORT extern struct bn_poly *bn_poly_add(struct bn_poly *sum,
|
||||
const struct bn_poly *poly1,
|
||||
@@ -90,6 +98,8 @@ BN_EXPORT extern struct bn_poly *bn_poly_add(struct bn_poly *sum,
|
||||
* bn_poly_sub
|
||||
* @brief
|
||||
* subtract two polynomials
|
||||
*
|
||||
* The output may alias either input.
|
||||
*/
|
||||
BN_EXPORT extern struct bn_poly *bn_poly_sub(struct bn_poly *diff,
|
||||
const struct bn_poly *poly1,
|
||||
@@ -98,7 +108,10 @@ BN_EXPORT extern struct bn_poly *bn_poly_sub(struct bn_poly *diff,
|
||||
/**
|
||||
* @brief
|
||||
* Divides any polynomial into any other polynomial using synthetic
|
||||
* division. Both polynomials must have real coefficients.
|
||||
* division. Both polynomials must have real coefficients and the
|
||||
* divisor's leading coefficient must be nonzero. The quotient and
|
||||
* remainder outputs must be distinct; the quotient may alias the
|
||||
* dividend. All other output/input pairs must be distinct.
|
||||
*/
|
||||
BN_EXPORT extern void bn_poly_synthetic_division(struct bn_poly *quo,
|
||||
struct bn_poly *rem,
|
||||
@@ -108,7 +121,8 @@ BN_EXPORT extern void bn_poly_synthetic_division(struct bn_poly *quo,
|
||||
/**
|
||||
*@brief
|
||||
* Uses the quadratic formula to find the roots (in `complex' form) of
|
||||
* any quadratic equation with real coefficients.
|
||||
* any quadratic equation with real coefficients. A nonzero leading
|
||||
* coefficient need not be one.
|
||||
*
|
||||
* @return 1 for success
|
||||
* @return 0 for fail.
|
||||
@@ -144,6 +158,7 @@ BN_EXPORT extern int bn_poly_quadratic_roots(struct bn_complex roots[],
|
||||
* If D < 0, there will be three unequal real roots.
|
||||
*
|
||||
* Returns 1 for success, 0 for fail.
|
||||
* A nonzero leading coefficient need not be one.
|
||||
*/
|
||||
BN_EXPORT extern int bn_poly_cubic_roots(struct bn_complex roots[],
|
||||
const struct bn_poly *eqn);
|
||||
@@ -151,7 +166,8 @@ BN_EXPORT extern int bn_poly_cubic_roots(struct bn_complex roots[],
|
||||
/**
|
||||
*@brief
|
||||
* Uses the quartic formula to find the roots (in `complex' form)
|
||||
* of any quartic equation with real coefficients.
|
||||
* of any quartic equation with real coefficients. A nonzero leading
|
||||
* coefficient need not be one.
|
||||
*
|
||||
* @return 1 for success
|
||||
* @return 0 for fail.
|
||||
|
||||
+4
-3
@@ -100,8 +100,8 @@ BN_EXPORT extern void quat_double(quat_t qout,
|
||||
/**
|
||||
*@brief Gives the bisector of quaternions q1 and q2.
|
||||
*
|
||||
* (Could be done with quat_slerp and factor 0.5)
|
||||
* [I believe they must be unit quaternions this to work]
|
||||
* Inputs must be unit quaternions. Antipodal inputs use a valid
|
||||
* great-circle midpoint.
|
||||
*/
|
||||
BN_EXPORT extern void quat_bisect(quat_t qout,
|
||||
const quat_t q1,
|
||||
@@ -161,7 +161,8 @@ BN_EXPORT extern void quat_exp(quat_t out,
|
||||
|
||||
/**
|
||||
*@brief
|
||||
* Take the natural logarithm of a unit quaternion.
|
||||
* Take the natural logarithm of a unit quaternion. The identity
|
||||
* quaternion maps to the zero quaternion.
|
||||
* Code by Ken Shoemake.
|
||||
*/
|
||||
BN_EXPORT extern void quat_log(quat_t out,
|
||||
|
||||
+16
-9
@@ -205,23 +205,30 @@ BU_EXPORT extern int bu_sscanf(const char *src, const char *fmt, ...) _BU_ATTR_S
|
||||
/** Routines for scanning certain kinds of data. */
|
||||
|
||||
/**
|
||||
* Scans a sequence of fastf_t numbers from a string or stdin
|
||||
* Scans a sequence of fastf_t numbers from a string or stdin.
|
||||
*
|
||||
* Scanning fastf_t numbers with bu_sscanf() is difficult, because
|
||||
* doing so requires scanning to some intermediate type like double
|
||||
* and then assigning to the fastf_t variable to convert the value to
|
||||
* whatever type fastf_t really is. This function makes it possible
|
||||
* to scan a series of fastf_t numbers separated by some character(s)
|
||||
* easily, by doing the required conversion internally to the
|
||||
* functions. As series of delimiter characters will be skipped,
|
||||
* empty scan fields are not supported (e.g., "0.0,,0.0,1.0" will scan
|
||||
* as 3 fields, not 4 with the 2nd skipped).
|
||||
* to scan a series of fastf_t numbers easily, by doing the required
|
||||
* conversion internally. Delimiters form a non-empty character set:
|
||||
* one or more delimiter characters must separate values, and repeated
|
||||
* delimiters are skipped. Empty scan fields are therefore not
|
||||
* supported (e.g., "0.0,,0.0,1.0" scans as 3 fields, not 4 with the
|
||||
* second skipped). A trailing delimiter is not consumed after the
|
||||
* final requested value.
|
||||
*
|
||||
* @param[out] c Returns number of characters scanned by the function
|
||||
* @param[out] c Optional destination for the number of input characters
|
||||
* consumed. It is set to zero before scanning and remains zero for
|
||||
* invalid arguments or when no value is scanned.
|
||||
* @param[in] src A source string to scan from, or NULL to read from stdin
|
||||
* @param[in] delim Any delimiter character(s) to skip between scan values
|
||||
* @param[in] delim Non-empty set of delimiter characters to skip between
|
||||
* scan values
|
||||
* @param[in] n Number of fastf_t values to scan from the src input string
|
||||
* @param[out] ... Pointers to fastf_t for storing scanned values (optional)
|
||||
* @param[out] ... Exactly n fastf_t pointers for storing scanned values;
|
||||
* individual pointers may be NULL
|
||||
* @return Number of values scanned
|
||||
*
|
||||
*/
|
||||
BU_EXPORT extern int bu_scan_fastf_t(int *c, const char *src, const char *delim, size_t n, ...);
|
||||
|
||||
@@ -76,6 +76,7 @@ __BEGIN_DECLS
|
||||
/* libbn */
|
||||
|
||||
#define BN_GAUSS_MAGIC 0x1e886880 /**< ??h? => 512256128 */
|
||||
#define BN_MULTIPOLY_MAGIC 0x4d554c54 /**< MULT */
|
||||
#define BN_POLY_MAGIC 0x506f4c79 /**< PoLy */
|
||||
#define BN_SPM_MAGIC 0x41278678 /**< A'?x */
|
||||
#define BN_TABDATA_MAGIC 0x53736d70 /**< Ssmp */
|
||||
|
||||
+2
-2
@@ -102,7 +102,7 @@ typedef struct bu_ptbl bu_ptbl_t;
|
||||
/** DEPRECATED */
|
||||
#define BU_PTBL_BASEADDR(ptbl) (((uintptr_t)(ptbl) != (uintptr_t)NULL)?(ptbl)->buffer:NULL)
|
||||
/** DEPRECATED */
|
||||
#define BU_PTBL_LASTADDR(ptbl) (((uintptr_t)(ptbl) != (uintptr_t)NULL)?(ptbl)->buffer + (ptbl)->end - 1:NULL)
|
||||
#define BU_PTBL_LASTADDR(ptbl) (((uintptr_t)(ptbl) != (uintptr_t)NULL && (ptbl)->buffer && (ptbl)->end > 0)?(ptbl)->buffer + (ptbl)->end - 1:NULL)
|
||||
|
||||
/**
|
||||
* A handy way to visit all the elements of the table is:
|
||||
@@ -117,7 +117,7 @@ typedef struct bu_ptbl bu_ptbl_t;
|
||||
* }
|
||||
*/
|
||||
#define BU_PTBL_FOR(ip, cast, ptbl) \
|
||||
ip = cast BU_PTBL_LASTADDR(ptbl); ip >= cast BU_PTBL_BASEADDR(ptbl); ip--
|
||||
ip = cast BU_PTBL_LASTADDR(ptbl); (ip) != NULL && (ip) >= cast BU_PTBL_BASEADDR(ptbl); (ip)--
|
||||
|
||||
/**
|
||||
* This collection of routines implements a "pointer table" data
|
||||
|
||||
@@ -41,10 +41,10 @@ class QTCAD_EXPORT QgAccordionObject : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgAccordionObject(QWidget *pparent = 0, QWidget *object = 0, QString header_title = QString(""));
|
||||
explicit QgAccordionObject(QWidget *pparent = nullptr, QWidget *object = nullptr, const QString &header_title = QString());
|
||||
~QgAccordionObject();
|
||||
QPushButton *toggle;
|
||||
QScrollArea *objscrollarea;
|
||||
QPushButton *toggle = nullptr;
|
||||
QScrollArea *objscrollarea = nullptr;
|
||||
|
||||
signals:
|
||||
void select(QgAccordionObject *);
|
||||
@@ -53,7 +53,7 @@ class QTCAD_EXPORT QgAccordionObject : public QWidget
|
||||
void toggleVisibility();
|
||||
|
||||
private:
|
||||
QVBoxLayout *objlayout;
|
||||
QVBoxLayout *objlayout = nullptr;
|
||||
QString title;
|
||||
};
|
||||
|
||||
@@ -62,7 +62,7 @@ class QTCAD_EXPORT QgAccordion : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgAccordion(QWidget *pparent = 0);
|
||||
explicit QgAccordion(QWidget *pparent = nullptr);
|
||||
~QgAccordion();
|
||||
void addObject(QgAccordionObject *object);
|
||||
|
||||
@@ -71,8 +71,8 @@ class QTCAD_EXPORT QgAccordion : public QWidget
|
||||
|
||||
private:
|
||||
QSet<QgAccordionObject *> objs;
|
||||
QgAccordionObject *selected = NULL;
|
||||
QVBoxLayout *mlayout;
|
||||
QgAccordionObject *selected = nullptr;
|
||||
QVBoxLayout *mlayout = nullptr;
|
||||
};
|
||||
|
||||
#endif /* QGACCORDIANWIDGET_H */
|
||||
|
||||
@@ -44,8 +44,8 @@ class QTCAD_EXPORT QgAppExecDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgAppExecDialog(QWidget *pparent, QString executable, QStringList args, QString lfile = "");
|
||||
~QgAppExecDialog() {}
|
||||
explicit QgAppExecDialog(QWidget *pparent = nullptr, const QString &executable = QString(), const QStringList &args = QStringList(), const QString &lfile = QString());
|
||||
~QgAppExecDialog();
|
||||
|
||||
public slots:
|
||||
void read_stdout();
|
||||
@@ -54,10 +54,10 @@ class QTCAD_EXPORT QgAppExecDialog : public QDialog
|
||||
void process_done(int, QProcess::ExitStatus);
|
||||
|
||||
public:
|
||||
QFile *logfile;
|
||||
QgConsole *console;
|
||||
QProcess *proc;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QFile *logfile = nullptr;
|
||||
QgConsole *console = nullptr;
|
||||
QProcess *proc = nullptr;
|
||||
QDialogButtonBox *buttonBox = nullptr;
|
||||
};
|
||||
|
||||
#endif // QGAPPEXECDIALOG_H
|
||||
|
||||
@@ -41,7 +41,7 @@ class QTCAD_EXPORT QgAttributesModel : public QgKeyValModel
|
||||
Q_OBJECT
|
||||
|
||||
public: // "standard" custom tree model functions
|
||||
explicit QgAttributesModel(QObject *parent = 0, struct db_i *dbip = DBI_NULL, struct directory *dp = RT_DIR_NULL, int show_std = 0, int show_user = 0);
|
||||
explicit QgAttributesModel(QObject *parent = nullptr, struct db_i *dbip = DBI_NULL, struct directory *dp = RT_DIR_NULL, int show_std = 0, int show_user = 0);
|
||||
~QgAttributesModel();
|
||||
|
||||
bool hasChildren(const QModelIndex &parent) const;
|
||||
@@ -61,14 +61,14 @@ class QTCAD_EXPORT QgAttributesModel : public QgKeyValModel
|
||||
|
||||
private:
|
||||
void add_Children(const char *name, QgKeyValNode *curr_node);
|
||||
struct db_i *current_dbip;
|
||||
struct directory *current_dp;
|
||||
struct bu_attribute_value_set *avs;
|
||||
int std_visible;
|
||||
int user_visible;
|
||||
struct db_i *current_dbip = nullptr;
|
||||
struct directory *current_dp = nullptr;
|
||||
struct bu_attribute_value_set *avs = nullptr;
|
||||
int std_visible = 0;
|
||||
int user_visible = 0;
|
||||
};
|
||||
|
||||
#endif /* QGATTRIBUTESMODEL */
|
||||
#endif /* QGATTRIBUTESMODEL_H */
|
||||
|
||||
// Local Variables:
|
||||
// tab-width: 8
|
||||
|
||||
@@ -43,11 +43,11 @@ class QTCAD_EXPORT QgColorRGB: public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgColorRGB(QWidget *p = NULL, QString lstr = QString("Color:"), QColor dcolor = QColor(Qt::red));
|
||||
explicit QgColorRGB(QWidget *p = nullptr, const QString &lstr = QString("Color:"), const QColor &dcolor = QColor(Qt::red));
|
||||
~QgColorRGB();
|
||||
|
||||
QLineEdit *rgbtext;
|
||||
QPushButton *rgbcolor;
|
||||
QLineEdit *rgbtext = nullptr;
|
||||
QPushButton *rgbcolor = nullptr;
|
||||
struct bu_color bc;
|
||||
|
||||
signals:
|
||||
@@ -60,12 +60,11 @@ class QTCAD_EXPORT QgColorRGB: public QWidget
|
||||
void set_color_from_button();
|
||||
|
||||
private:
|
||||
QColorDialog *d;
|
||||
QHBoxLayout *mlayout;
|
||||
QHBoxLayout *mlayout = nullptr;
|
||||
QColor qc;
|
||||
};
|
||||
|
||||
#endif /* QACCORDIANWIDGET_H */
|
||||
#endif /* QGCOLORRGB_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
|
||||
@@ -72,7 +72,7 @@ class QTCAD_EXPORT GEDShellCompleter : public QgConsoleWidgetCompleter
|
||||
public:
|
||||
GEDShellCompleter(QWidget *p, struct ged *ged_ptr);
|
||||
void updateCompletionModel(const QString& console_txt) override;
|
||||
struct ged *gedp = NULL;
|
||||
struct ged *gedp = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
* Originally from https://github.com/juangburgos/QConsoleListener
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef QGCONSOLELISTENER_H
|
||||
#define QGCONSOLELISTENER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -48,25 +49,25 @@ class QTCAD_EXPORT QConsoleListener : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QConsoleListener(int fd = -1,
|
||||
struct ged_subprocess *p = NULL,
|
||||
explicit QConsoleListener(int fd = -1,
|
||||
struct ged_subprocess *p = nullptr,
|
||||
bu_process_io_t t = BU_PROCESS_STDIN,
|
||||
ged_io_func_t c = NULL,
|
||||
void *d = NULL);
|
||||
~QConsoleListener();
|
||||
ged_io_func_t c = nullptr,
|
||||
void *d = nullptr);
|
||||
~QConsoleListener() override;
|
||||
|
||||
// Called by client code when it is done with the process
|
||||
void on_finished();
|
||||
|
||||
struct ged_subprocess *process = NULL;
|
||||
ged_io_func_t callback;
|
||||
bu_process_io_t type;
|
||||
void *data;
|
||||
struct ged_subprocess *process = nullptr;
|
||||
ged_io_func_t callback = nullptr;
|
||||
bu_process_io_t type = BU_PROCESS_STDIN;
|
||||
void *data = nullptr;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QWinEventNotifier *m_notifier;
|
||||
QWinEventNotifier *m_notifier = nullptr;
|
||||
#else
|
||||
QSocketNotifier *m_notifier;
|
||||
QSocketNotifier *m_notifier = nullptr;
|
||||
#endif
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -83,6 +84,8 @@ Q_SIGNALS:
|
||||
void on_finishedGetLine(const QString &strNewLine);
|
||||
};
|
||||
|
||||
#endif /* QGCONSOLELISTENER_H */
|
||||
|
||||
// Local Variables:
|
||||
// tab-width: 8
|
||||
// mode: C++
|
||||
|
||||
@@ -35,10 +35,10 @@ class QTCAD_EXPORT QgDockWidget : public QDockWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgDockWidget(const QString &title, QWidget *parent);
|
||||
explicit QgDockWidget(const QString &title, QWidget *parent = nullptr);
|
||||
bool event(QEvent *e);
|
||||
|
||||
QgModel *m = NULL;
|
||||
QgModel *m = nullptr;
|
||||
|
||||
signals:
|
||||
void banner_click();
|
||||
|
||||
+9
-12
@@ -48,33 +48,33 @@ class QTCAD_EXPORT QgNameEdit: public QLineEdit
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgNameEdit(QWidget *p = NULL, struct db_i *e_dbip = NULL, int e_type = DB5_MINORTYPE_RESERVED);
|
||||
explicit QgNameEdit(QWidget *p = nullptr, struct db_i *e_dbip = nullptr, int e_type = DB5_MINORTYPE_RESERVED);
|
||||
~QgNameEdit();
|
||||
|
||||
int n_state = 1;
|
||||
|
||||
private:
|
||||
struct db_i *dbip = NULL;
|
||||
struct db_i *dbip = nullptr;
|
||||
// Minor type from rt/db5.h
|
||||
int expected_type = DB5_MINORTYPE_RESERVED;
|
||||
}
|
||||
};
|
||||
|
||||
/* 3D point/vector input */
|
||||
class QTCAD_EXPORT QVectEdit: public QWidget
|
||||
class QTCAD_EXPORT QgVectEdit: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgVectEdit(QWidget *p = NULL);
|
||||
explicit QgVectEdit(QWidget *p = nullptr);
|
||||
~QgVectEdit();
|
||||
|
||||
// QDoubleValidator inputs for each value
|
||||
QLineEdit *vx;
|
||||
QLineEdit *vy;
|
||||
QLineEdit *vz;
|
||||
QLineEdit *vx = nullptr;
|
||||
QLineEdit *vy = nullptr;
|
||||
QLineEdit *vz = nullptr;
|
||||
|
||||
vect_t v = VINIT_ZERO;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* Need a "pre-packaged" one line palette of controls for standard operations
|
||||
@@ -106,9 +106,6 @@ class QTCAD_EXPORT QVectEdit: public QWidget
|
||||
* be able to convey the extra information, but on the larger scale it would
|
||||
* collapse the current View/Instance/Edit paradigm in qged to just View/Edit. */
|
||||
|
||||
|
||||
/* Need to consider whether
|
||||
|
||||
#endif //QGEDIT_H
|
||||
|
||||
// Local Variables:
|
||||
|
||||
@@ -75,8 +75,8 @@ class QTCAD_EXPORT QgFlowLayout : public QLayout
|
||||
int smartSpacing(QStyle::PixelMetric pm) const;
|
||||
|
||||
QList<QLayoutItem *> itemList;
|
||||
int m_hSpace;
|
||||
int m_vSpace;
|
||||
int m_hSpace = -1;
|
||||
int m_vSpace = -1;
|
||||
};
|
||||
|
||||
#endif // QgFLOWLAYOUTH
|
||||
|
||||
@@ -51,7 +51,7 @@ class QTCAD_EXPORT QgGeomImport : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgGeomImport(QWidget *pparent = NULL);
|
||||
explicit QgGeomImport(QWidget *pparent = NULL);
|
||||
~QgGeomImport();
|
||||
|
||||
QString gfile(const char *tfile = NULL);
|
||||
@@ -72,18 +72,18 @@ class ASCImportDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ASCImportDialog(QString filename, QString g_path, QString l_path);
|
||||
explicit ASCImportDialog(QString filename, QString g_path, QString l_path, QWidget *parent = NULL);
|
||||
|
||||
QString command();
|
||||
QStringList options();
|
||||
QLineEdit *db_path;
|
||||
QLineEdit *log_path;
|
||||
QLineEdit *db_path = NULL;
|
||||
QLineEdit *log_path = NULL;
|
||||
|
||||
private:
|
||||
|
||||
QString input_file;
|
||||
QGroupBox *formGroupBox;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QGroupBox *formGroupBox = NULL;
|
||||
QDialogButtonBox *buttonBox = NULL;
|
||||
};
|
||||
|
||||
class RhinoImportDialog : public QDialog
|
||||
@@ -91,27 +91,26 @@ class RhinoImportDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RhinoImportDialog(QString filename, QString g_path, QString l_path);
|
||||
explicit RhinoImportDialog(QString filename, QString g_path, QString l_path, QWidget *parent = NULL);
|
||||
|
||||
QString command();
|
||||
QStringList options();
|
||||
QLineEdit *db_path;
|
||||
QLineEdit *log_path;
|
||||
QLineEdit *db_path = NULL;
|
||||
QLineEdit *log_path = NULL;
|
||||
|
||||
private:
|
||||
|
||||
QString input_file;
|
||||
|
||||
QLineEdit *scaling_factor;
|
||||
QLineEdit *tolerance;
|
||||
QLineEdit *verbosity;
|
||||
QCheckBox *debug_printing;
|
||||
QCheckBox *random_colors;
|
||||
QCheckBox *uuid;
|
||||
QLineEdit *scaling_factor = NULL;
|
||||
QLineEdit *tolerance = NULL;
|
||||
QLineEdit *verbosity = NULL;
|
||||
QCheckBox *debug_printing = NULL;
|
||||
QCheckBox *random_colors = NULL;
|
||||
QCheckBox *uuid = NULL;
|
||||
|
||||
|
||||
QGroupBox *formGroupBox;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QGroupBox *formGroupBox = NULL;
|
||||
QDialogButtonBox *buttonBox = NULL;
|
||||
};
|
||||
|
||||
class STEPImportDialog : public QDialog
|
||||
@@ -119,21 +118,21 @@ class STEPImportDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
STEPImportDialog(QString filename, QString g_path, QString l_path);
|
||||
explicit STEPImportDialog(QString filename, QString g_path, QString l_path, QWidget *parent = NULL);
|
||||
|
||||
QString command();
|
||||
QStringList options();
|
||||
QLineEdit *db_path;
|
||||
QLineEdit *log_path;
|
||||
QLineEdit *db_path = NULL;
|
||||
QLineEdit *log_path = NULL;
|
||||
|
||||
private:
|
||||
|
||||
QString input_file;
|
||||
|
||||
QCheckBox *verbosity;
|
||||
QCheckBox *verbosity = NULL;
|
||||
|
||||
QGroupBox *formGroupBox;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QGroupBox *formGroupBox = NULL;
|
||||
QDialogButtonBox *buttonBox = NULL;
|
||||
};
|
||||
|
||||
#endif // QGGEOMIMPORT_H
|
||||
|
||||
+24
-24
@@ -37,17 +37,17 @@
|
||||
#include "qtcad/defines.h"
|
||||
|
||||
class QTCAD_EXPORT QgKeyValNode
|
||||
{
|
||||
public:
|
||||
QgKeyValNode(QgKeyValNode *aParent=0);
|
||||
~QgKeyValNode();
|
||||
{
|
||||
public:
|
||||
explicit QgKeyValNode(QgKeyValNode *aParent = nullptr);
|
||||
~QgKeyValNode();
|
||||
|
||||
QString name;
|
||||
QString value;
|
||||
int attr_type;
|
||||
QString name;
|
||||
QString value;
|
||||
int attr_type = 0;
|
||||
|
||||
QgKeyValNode *parent;
|
||||
QList<QgKeyValNode*> children;
|
||||
QgKeyValNode *parent = nullptr;
|
||||
QList<QgKeyValNode*> children;
|
||||
};
|
||||
|
||||
class QTCAD_EXPORT QgKeyValModel : public QAbstractItemModel
|
||||
@@ -55,23 +55,23 @@ class QTCAD_EXPORT QgKeyValModel : public QAbstractItemModel
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgKeyValModel(QObject *p = NULL);
|
||||
~QgKeyValModel();
|
||||
explicit QgKeyValModel(QObject *p = nullptr);
|
||||
~QgKeyValModel() override;
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
||||
QModelIndex parent(const QModelIndex &child) const;
|
||||
int rowCount(const QModelIndex &child) const;
|
||||
int columnCount(const QModelIndex &child) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
int rowCount(const QModelIndex &child) const override;
|
||||
int columnCount(const QModelIndex &child) const override;
|
||||
|
||||
void setRootNode(QgKeyValNode *root);
|
||||
QgKeyValNode* rootNode();
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
|
||||
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;
|
||||
|
||||
QgKeyValNode *m_root;
|
||||
QgKeyValNode *m_root = nullptr;
|
||||
QModelIndex NodeIndex(QgKeyValNode *node) const;
|
||||
QgKeyValNode *IndexNode(const QModelIndex &index) const;
|
||||
|
||||
@@ -85,10 +85,10 @@ class QTCAD_EXPORT QgKeyValDelegate : public QStyledItemDelegate
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgKeyValDelegate(QWidget *pparent = 0) : QStyledItemDelegate(pparent) {}
|
||||
explicit QgKeyValDelegate(QWidget *pparent = nullptr) : QStyledItemDelegate(pparent) {}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
};
|
||||
|
||||
class QTCAD_EXPORT QgKeyValView : public QTreeView
|
||||
@@ -96,8 +96,8 @@ class QTCAD_EXPORT QgKeyValView : public QTreeView
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgKeyValView(QWidget *pparent, int decorate_tree = 0);
|
||||
~QgKeyValView() {};
|
||||
explicit QgKeyValView(QWidget *pparent = nullptr, int decorate_tree = 0);
|
||||
~QgKeyValView() override {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ class QTCAD_EXPORT QgMeasureFilter : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~QgMeasureFilter();
|
||||
|
||||
// Primary mouse interaction. As it happens the 2D and 3D mouse event
|
||||
// filtering is the same, so this is not a virtual function. See
|
||||
// get_point for the 2D/3D specific logic.
|
||||
|
||||
@@ -343,7 +343,7 @@ class QTCAD_EXPORT QgModel : public QAbstractItemModel
|
||||
|
||||
void item_rebuild(QgItem *item);
|
||||
|
||||
QgItem *rootItem;
|
||||
QgItem *rootItem = NULL;
|
||||
struct bview *empty_gvp = NULL;
|
||||
struct db_i *model_dbip = NULL;
|
||||
};
|
||||
|
||||
@@ -46,6 +46,8 @@ class QTCAD_EXPORT QgPolyFilter : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~QgPolyFilter();
|
||||
|
||||
// Initialization common to the various polygon filter types
|
||||
QMouseEvent *view_sync(QEvent *e);
|
||||
|
||||
@@ -81,6 +83,7 @@ class QTCAD_EXPORT QPolyCreateFilter : public QgPolyFilter
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~QPolyCreateFilter();
|
||||
bool eventFilter(QObject *, QEvent *e);
|
||||
void finalize(bool);
|
||||
|
||||
@@ -92,6 +95,7 @@ class QTCAD_EXPORT QPolyUpdateFilter : public QgPolyFilter
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~QPolyUpdateFilter();
|
||||
bool eventFilter(QObject *, QEvent *e);
|
||||
|
||||
struct bu_ptbl bool_objs = BU_PTBL_INIT_ZERO;
|
||||
@@ -118,6 +122,7 @@ class QTCAD_EXPORT QPolyMoveFilter : public QgPolyFilter
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~QPolyMoveFilter();
|
||||
bool eventFilter(QObject *, QEvent *e);
|
||||
struct bu_ptbl move_objs = BU_PTBL_INIT_ZERO;
|
||||
};
|
||||
|
||||
@@ -103,9 +103,9 @@ class QTCAD_EXPORT QgQuadView : public QWidget
|
||||
// Holds up to 4 views in single view only the first view is constructed
|
||||
// The other views are constructed if quad view mode is selected by the user
|
||||
QgView *views[4] = {nullptr, nullptr, nullptr, nullptr};
|
||||
QgView *currentView;
|
||||
QgView *currentView = nullptr;
|
||||
// We need to hang on to this because we don't create the other quad views until the user switches mode
|
||||
struct ged *gedp;
|
||||
struct ged *gedp = nullptr;
|
||||
|
||||
// Hang on to these pointers so when we need to clean up memory we have them
|
||||
QGridLayout *currentLayout = nullptr;
|
||||
|
||||
@@ -48,6 +48,8 @@ class QTCAD_EXPORT QgSelectFilter : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~QgSelectFilter();
|
||||
|
||||
// Primary mouse interaction. This differs a bit for the
|
||||
// various selection types, hence the virtual definition
|
||||
// in the base class.
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
#include "common.h"
|
||||
|
||||
#ifndef QGSIGNALFLAGS_H
|
||||
#define QGSIGNALFLAGS_H
|
||||
|
||||
#define QG_VIEW_REFRESH 0x00000001 // Potential camera updates, no structural changes
|
||||
#define QG_VIEW_DRAWN 0x00000002 // Used when what is drawn in the scene changes
|
||||
|
||||
@@ -73,6 +73,8 @@ class QTCAD_EXPORT QgSketchFilter : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~QgSketchFilter() = default;
|
||||
|
||||
/**
|
||||
* Synchronise Qt mouse event with the bview coordinate state.
|
||||
*
|
||||
|
||||
@@ -69,7 +69,7 @@ class QTCAD_EXPORT QgToolPaletteButton: public QPushButton
|
||||
void element_selected(QgToolPaletteElement *);
|
||||
|
||||
private:
|
||||
QgToolPaletteElement *element;
|
||||
QgToolPaletteElement *element = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -126,8 +126,8 @@ class QTCAD_EXPORT QgToolPaletteElement: public QWidget
|
||||
void element_view_changed(unsigned long long);
|
||||
|
||||
public:
|
||||
QgToolPaletteButton *button;
|
||||
QWidget *controls;
|
||||
QgToolPaletteButton *button = nullptr;
|
||||
QWidget *controls = nullptr;
|
||||
int scroll_pos = 0;
|
||||
|
||||
bool use_event_filter = false;
|
||||
@@ -139,7 +139,7 @@ class QTCAD_EXPORT QgToolPalette: public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgToolPalette(QWidget *pparent = 0);
|
||||
QgToolPalette(QWidget *pparent = nullptr);
|
||||
~QgToolPalette();
|
||||
void addElement(QgToolPaletteElement *element);
|
||||
void deleteElement(QgToolPaletteElement *element);
|
||||
@@ -149,10 +149,10 @@ class QTCAD_EXPORT QgToolPalette: public QWidget
|
||||
|
||||
void resizeEvent(QResizeEvent *pevent);
|
||||
|
||||
QgToolPaletteElement *selected;
|
||||
QgToolPaletteElement *selected = nullptr;
|
||||
QString selected_style = QString("");
|
||||
|
||||
QVBoxLayout *mlayout;
|
||||
QVBoxLayout *mlayout = nullptr;
|
||||
|
||||
signals:
|
||||
|
||||
@@ -195,13 +195,13 @@ class QTCAD_EXPORT QgToolPalette: public QWidget
|
||||
void palette_do_view_changed(unsigned long long);
|
||||
|
||||
private:
|
||||
int always_selected;
|
||||
int icon_width;
|
||||
int icon_height;
|
||||
QSplitter *splitter;
|
||||
QWidget *button_container;
|
||||
QgFlowLayout *button_layout;
|
||||
QScrollArea *control_container;
|
||||
int always_selected = 1;
|
||||
int icon_width = 30;
|
||||
int icon_height = 30;
|
||||
QSplitter *splitter = nullptr;
|
||||
QWidget *button_container = nullptr;
|
||||
QgFlowLayout *button_layout = nullptr;
|
||||
QScrollArea *control_container = nullptr;
|
||||
QSet<QgToolPaletteElement *> elements;
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class QTCAD_EXPORT QgTreeSelectionModel : public QItemSelectionModel
|
||||
void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags flags) override;
|
||||
|
||||
public:
|
||||
QgTreeView *treeview;
|
||||
QgTreeView *treeview = nullptr;
|
||||
};
|
||||
|
||||
#endif //QGTREESELECTIONMODEL_H
|
||||
|
||||
@@ -50,7 +50,7 @@ class QTCAD_EXPORT QgTreeView : public QTreeView
|
||||
QModelIndex selected();
|
||||
|
||||
void drawBranches(QPainter* painter, const QRect& rrect, const QModelIndex& index) const override;
|
||||
QgModel *m = NULL;
|
||||
QgModel *m = nullptr;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *pevent) override;
|
||||
@@ -81,12 +81,12 @@ class QTCAD_EXPORT gObjDelegate : public QStyledItemDelegate
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
gObjDelegate(QgTreeView *tv = NULL, QWidget *pparent = 0) : QStyledItemDelegate(pparent) {cadtreeview = tv ;}
|
||||
gObjDelegate(QgTreeView *tv = nullptr, QWidget *pparent = nullptr) : QStyledItemDelegate(pparent), cadtreeview(tv) {}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
QgTreeView *cadtreeview = NULL;
|
||||
QgTreeView *cadtreeview = nullptr;
|
||||
};
|
||||
|
||||
#endif //QGTREEVIEW_H
|
||||
|
||||
@@ -56,7 +56,7 @@ extern QTCAD_EXPORT QImage
|
||||
QgIcon(struct directory *dp, struct db_i *dbip);
|
||||
|
||||
|
||||
#endif //QGUTIL_H
|
||||
#endif /* QGUTIL_H */
|
||||
|
||||
// Local Variables:
|
||||
// tab-width: 8
|
||||
|
||||
@@ -81,15 +81,15 @@ class QTCAD_EXPORT QgViewCtrl : public QToolBar
|
||||
|
||||
public:
|
||||
// Left mouse behavior controls (when not using a tool or editing)
|
||||
QAction *sca;
|
||||
QAction *rot;
|
||||
QAction *tra;
|
||||
QAction *center;
|
||||
QAction *sca = nullptr;
|
||||
QAction *rot = nullptr;
|
||||
QAction *tra = nullptr;
|
||||
QAction *center = nullptr;
|
||||
|
||||
// Raytrace/framebuffer controls
|
||||
QAction *raytrace;
|
||||
QAction *fb_mode;
|
||||
QAction *fb_clear;
|
||||
QAction *raytrace = nullptr;
|
||||
QAction *fb_mode = nullptr;
|
||||
QAction *fb_clear = nullptr;
|
||||
|
||||
private:
|
||||
bool raytrace_running = false;
|
||||
|
||||
+10
-10
@@ -56,34 +56,34 @@
|
||||
#include "bu/str.h"
|
||||
#define QTCAD_SUPPORT_ENV_SLOT_REPORTING 1
|
||||
#ifdef QTCAD_SUPPORT_ENV_SLOT_REPORTING
|
||||
# define QTCAD_SLOT(slot_name, level) {\
|
||||
# define QTCAD_SLOT(slot_name, level) do {\
|
||||
const char *qrsig = getenv("QTCAD_REPORT_SLOTS");\
|
||||
if (qrsig) {\
|
||||
int qlev = atoi(qrsig);\
|
||||
if (qlev == level) {\
|
||||
bu_log("%s\n", slot_name); \
|
||||
if (qlev == level && (slot_name)) {\
|
||||
bu_log("%s\n", (slot_name)); \
|
||||
} \
|
||||
}\
|
||||
}
|
||||
} while (0)
|
||||
#else
|
||||
# define QTCAD_SLOT(slot_name, level)
|
||||
# define QTCAD_SLOT(slot_name, level) do {} while (0)
|
||||
#endif
|
||||
|
||||
// Uncomment to allow the env command to enable printouts
|
||||
// reporting on when libqtcad events are being called
|
||||
#define QTCAD_SUPPORT_ENV_EVENT_REPORTING 1
|
||||
#ifdef QTCAD_SUPPORT_ENV_EVENT_REPORTING
|
||||
# define QTCAD_EVENT(event_name, level) {\
|
||||
# define QTCAD_EVENT(event_name, level) do {\
|
||||
const char *qrsig = getenv("QTCAD_REPORT_EVENTS");\
|
||||
if (qrsig) {\
|
||||
int qlev = atoi(qrsig);\
|
||||
if (qlev == level) {\
|
||||
bu_log("%s\n", event_name); \
|
||||
if (qlev == level && (event_name)) {\
|
||||
bu_log("%s\n", (event_name)); \
|
||||
} \
|
||||
}\
|
||||
}
|
||||
} while (0)
|
||||
#else
|
||||
# define QTCAD_EVENT(event_name, level)
|
||||
# define QTCAD_EVENT(event_name, level) do {} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* QTCAD_DEFINES_H */
|
||||
|
||||
+2
-2
@@ -84,7 +84,7 @@ __BEGIN_DECLS
|
||||
#define RT_DEBUG_HF 0x04000000 /**< @brief 27 Height Field solids */
|
||||
|
||||
#define RT_DEBUG_MESHING 0x08000000 /**< @brief 28 Print meshing/triangulation details */
|
||||
#define RT_DEBUG_UNUSED_3 0x10000000 /**< @brief 29 Unassigned */
|
||||
#define RT_DEBUG_RTCMP 0x10000000 /**< @brief 29 Set up rtcmp capture; recording uses a runtime toggle. If LIBRT_RTCMP_PRIMITIVES=1 includes primitive segments. */
|
||||
#define RT_DEBUG_UNUSED_4 0x20000000 /**< @brief 30 Unassigned */
|
||||
|
||||
/* Options which will cause the library to write binary debugging output */
|
||||
@@ -96,7 +96,7 @@ __BEGIN_DECLS
|
||||
"\040PL_BOX" \
|
||||
"\037PL_SOLIDS" \
|
||||
"\036UNUSED_4" \
|
||||
"\035UNUSED_3" \
|
||||
"\035RTCMP" \
|
||||
"\034UNUSED_2" \
|
||||
"\033HF" \
|
||||
"\032EBM" \
|
||||
|
||||
+23
-6
@@ -465,6 +465,17 @@ rt_get_solid_keypoint(struct rt_edit *s, point_t *pt, const char **strp, fastf_t
|
||||
RT_EXPORT extern void
|
||||
rt_edit_set_edflag(struct rt_edit *s, int edflag);
|
||||
|
||||
/**
|
||||
* Set a parameter-edit translation target expressed in model base units.
|
||||
*
|
||||
* rt_edit's parameter-edit handlers consume e_para in database local units,
|
||||
* while keypoints and edit axes are maintained in model base units. This
|
||||
* helper performs the boundary conversion for callers that have computed a
|
||||
* target from a keypoint, axis, or view transform.
|
||||
*/
|
||||
RT_EXPORT extern void
|
||||
rt_edit_set_translation_target(struct rt_edit *s, const point_t target);
|
||||
|
||||
RT_EXPORT extern int
|
||||
rt_edit_knob_cmd_process(
|
||||
struct rt_edit *s,
|
||||
@@ -499,8 +510,10 @@ rt_knob_edit_sca(
|
||||
int matrix_edit);
|
||||
|
||||
/* Equivalent to sedit - run editing logic after input data is set in
|
||||
* rt_edit container */
|
||||
RT_EXPORT extern void
|
||||
* rt_edit container. Transient input flags are consumed whether the edit
|
||||
* succeeds or fails; parameter values remain available to the caller.
|
||||
* Returns BRLCAD_ERROR if the primitive edit fails. */
|
||||
RT_EXPORT extern int
|
||||
rt_edit_process(struct rt_edit *s);
|
||||
|
||||
/**
|
||||
@@ -521,7 +534,7 @@ rt_edit_snap_point(point2d_t pt, const struct rt_edit *s);
|
||||
* restored later with rt_edit_revert().
|
||||
*
|
||||
* The snapshot is stored inside the rt_edit struct. Calling this
|
||||
* function again overwrites any previous snapshot (single-level undo).
|
||||
* function again replaces the previous snapshot only on success.
|
||||
*
|
||||
* @return BRLCAD_OK on success, BRLCAD_ERROR if the export failed.
|
||||
*/
|
||||
@@ -532,8 +545,8 @@ rt_edit_checkpoint(struct rt_edit *s);
|
||||
* Restore primitive parameters from the snapshot saved by
|
||||
* rt_edit_checkpoint().
|
||||
*
|
||||
* If no snapshot has been saved (or the last snapshot was already
|
||||
* consumed) this function logs a message and returns BRLCAD_ERROR.
|
||||
* The snapshot remains available for repeated restores. If none has
|
||||
* been saved, this function logs a message and returns BRLCAD_ERROR.
|
||||
*
|
||||
* @return BRLCAD_OK on success, BRLCAD_ERROR otherwise.
|
||||
*/
|
||||
@@ -697,7 +710,11 @@ enum rt_constraint_edit_op_kind {
|
||||
RT_CONSTRAINT_EDIT_OP_SET_BEND,
|
||||
RT_CONSTRAINT_EDIT_OP_SCALE_OD,
|
||||
RT_CONSTRAINT_EDIT_OP_SCALE_ID,
|
||||
RT_CONSTRAINT_EDIT_OP_SCALE_BEND
|
||||
RT_CONSTRAINT_EDIT_OP_SCALE_BEND,
|
||||
/* Set every point when an all-zero dimension has no scale reference. */
|
||||
RT_CONSTRAINT_EDIT_OP_SET_ALL_OD,
|
||||
RT_CONSTRAINT_EDIT_OP_SET_ALL_ID,
|
||||
RT_CONSTRAINT_EDIT_OP_SET_ALL_BEND
|
||||
};
|
||||
|
||||
struct rt_constraint_edit_param_ref {
|
||||
|
||||
@@ -55,14 +55,11 @@ struct clt_tri_specific {
|
||||
};
|
||||
#endif
|
||||
|
||||
#define RT_BOT_SURFNO_INTERIOR (-1)
|
||||
|
||||
/* Shared between bot and ars at the moment */
|
||||
struct bot_specific {
|
||||
unsigned char bot_mode;
|
||||
unsigned char bot_orientation;
|
||||
unsigned char bot_flags;
|
||||
unsigned char bot_parity_shot;
|
||||
size_t bot_ntri;
|
||||
fastf_t *bot_thickness;
|
||||
struct bu_bitv *bot_facemode;
|
||||
|
||||
@@ -41,6 +41,7 @@ struct rt_nmg_edit {
|
||||
struct loopuse *lu_copy; /* copy of loop to be extruded */
|
||||
plane_t lu_pl; /* plane equation for loop to be extruded */
|
||||
struct shell *es_s; /* Shell where extrusion is to end up */
|
||||
int es_s_from_extrusion; /* Replace this edit's prior preview */
|
||||
point_t lu_keypoint; /* keypoint of lu_copy for extrusion */
|
||||
struct vertex *es_v; /* Currently selected NMG vertex (ECMD_NMG_VPICK) */
|
||||
struct faceuse *es_fu; /* Currently selected NMG faceuse (ECMD_NMG_FPICK) */
|
||||
|
||||
@@ -55,6 +55,18 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define RT_RTCMP_CAPTURE_RUNTIME_TOGGLE 1
|
||||
|
||||
/** Set RT_DEBUG_RTCMP recording: nonzero enables, zero disables.
|
||||
* Enabling requires the debug flag and a usable output writer.
|
||||
* Return 0 on success and -1 on failure. Disabling succeeds even
|
||||
* before setup.
|
||||
*/
|
||||
RT_EXPORT extern int rt_rtcmp_capture_set_enabled(int enabled);
|
||||
|
||||
/** Wait until pending RT_DEBUG_RTCMP records have reached the output file. */
|
||||
RT_EXPORT extern int rt_rtcmp_capture_flush(void);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Shoot a ray
|
||||
|
||||
@@ -175,7 +175,7 @@ TCLCAD_EXPORT extern void fb_tcl_setup(void);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* TCLCAD_MISC_H */
|
||||
#endif /* TCLCAD_DRAW_H */
|
||||
|
||||
/** @} */
|
||||
/*
|
||||
|
||||
@@ -2200,7 +2200,11 @@ macro(find_package_opencv)
|
||||
set(OpenCV_DIR_TMP "${OpenCV_DIR}")
|
||||
set(OpenCV_DIR "${CMAKE_BINARY_DIR}/${LIB_DIR}/cmake/opencv4")
|
||||
set(OpenCV_ROOT ${CMAKE_BINARY_DIR})
|
||||
find_package(OpenCV COMPONENTS core features2d imgproc highgui)
|
||||
find_package(OpenCV CONFIG COMPONENTS core imgproc imgcodecs highgui)
|
||||
if(OpenCV_FOUND AND OpenCV_VERSION_MAJOR GREATER_EQUAL 5)
|
||||
# OpenCV 5 moved boundingRect from imgproc to geometry.
|
||||
find_package(OpenCV CONFIG COMPONENTS geometry)
|
||||
endif()
|
||||
unset(OpenCV_ROOT)
|
||||
|
||||
# If no bundled copy, see what the system has
|
||||
|
||||
@@ -117,6 +117,20 @@ if(TARGET libged)
|
||||
|
||||
endif(TARGET libged)
|
||||
|
||||
if(TARGET librt AND FUZZER_SUPPORTED)
|
||||
set(RT_EDIT_FUZZ_DIR "${CMAKE_SOURCE_DIR}/src/librt/tests/edit")
|
||||
brlcad_addexec(
|
||||
fuzz_rt_edit_test
|
||||
"${RT_EDIT_FUZZ_DIR}/fuzz.cpp;${RT_EDIT_FUZZ_DIR}/ars.cpp;${RT_EDIT_FUZZ_DIR}/bot.cpp"
|
||||
"libbu;librt;libnmg;libwdb;libbrep"
|
||||
TEST
|
||||
)
|
||||
set_target_properties(fuzz_rt_edit_test PROPERTIES UNITY_BUILD OFF)
|
||||
target_compile_options(fuzz_rt_edit_test PRIVATE ${FUZZER_EXE_COMPILE_OPTIONS})
|
||||
target_link_options(fuzz_rt_edit_test PRIVATE ${FUZZER_LINK_OPTIONS})
|
||||
BRLCAD_ADD_TEST(NAME fuzz_rt_edit_smoke COMMAND fuzz_rt_edit_test -runs=1 -max_total_time=5)
|
||||
endif()
|
||||
|
||||
cmakefiles(
|
||||
CMakeLists.txt
|
||||
fuzz_ged.cpp
|
||||
|
||||
@@ -23,6 +23,7 @@ set(
|
||||
gqa.mass_mix.am.out
|
||||
gqa.mass_mix.aw.out
|
||||
gqa.mass_mix.u0.out
|
||||
gqa.missing_density.out
|
||||
gqa.mged
|
||||
gqa.overlaps.plot3
|
||||
gqa.sphere_adaptive.out
|
||||
|
||||
@@ -67,6 +67,11 @@ run_capture ( ) {
|
||||
return $ret
|
||||
}
|
||||
|
||||
expect_failure ( ) {
|
||||
"$@"
|
||||
test $? -ne 0
|
||||
}
|
||||
|
||||
extract_last_number ( ) {
|
||||
label="$1"
|
||||
file="$2"
|
||||
@@ -101,6 +106,19 @@ assert_close ( ) {
|
||||
fi
|
||||
}
|
||||
|
||||
assert_contains ( ) {
|
||||
expected="$1"
|
||||
file="$2"
|
||||
desc="$3"
|
||||
|
||||
if grep -F -q "$expected" "$file" ; then
|
||||
log "PASS: $desc"
|
||||
else
|
||||
log "FAIL: $desc"
|
||||
STATUS="`expr $STATUS + 1`"
|
||||
fi
|
||||
}
|
||||
|
||||
MGED="`ensearch mged`"
|
||||
if test ! -f "$MGED" ; then
|
||||
log "Unable to find mged, aborting"
|
||||
@@ -177,6 +195,10 @@ adjust mass_air.r GIFTmater 2
|
||||
g mass_air_only.g mass_air.r
|
||||
g mass_air_mix.g mass_solid.r mass_air.r
|
||||
|
||||
in missing_density.s rpp 2 3 0 1 0 1
|
||||
r missing_density.r u missing_density.s
|
||||
adjust missing_density.r GIFTmater 123
|
||||
|
||||
in sphere.s sph 0 0 0 1
|
||||
r sphere.r u sphere.s
|
||||
adjust sphere.r GIFTmater 5
|
||||
@@ -243,6 +265,7 @@ run_capture gqa.mass_mix.aw.out $GQABIN -u m,m^3,kg -g 250mm-50mm -Aw gqa.g mass
|
||||
run_capture gqa.mass_mix.am.out $GQABIN -u m,m^3,kg -g 250mm-50mm -Am gqa.g mass_air_mix.g
|
||||
run_capture gqa.mass_mix.u0.out $GQABIN -u m,m^3,kg -g 250mm-50mm -U 0 -Aw gqa.g mass_air_mix.g
|
||||
run_capture gqa.sphere_adaptive.out $GQABIN -u m,m^3,kg -q -Av -g 0.05m gqa.g sphere.r
|
||||
run_capture gqa.missing_density.out expect_failure $GQABIN -u m,m^3,kg -g 250mm-50mm -f density_table.txt -Aw gqa.g missing_density.r
|
||||
|
||||
MASS_AIR_AW="`extract_last_number 'Average total weight:' gqa.mass_air.aw.out`"
|
||||
MASS_AIR_AM="`extract_last_number 'Average total weight:' gqa.mass_air.am.out`"
|
||||
@@ -257,6 +280,7 @@ assert_close 1001 "$MASS_MIX_AW" 0.001 "mixed solid+air modeled weight with -Aw"
|
||||
assert_close "$MASS_MIX_AW" "$MASS_MIX_AM" 0.001 "-Aw and -Am agree on mixed modeled air"
|
||||
assert_close 1000 "$MASS_MIX_U0" 0.001 "-U 0 excludes modeled air from weight"
|
||||
assert_close 4.18879 "$SPHERE_VOLUME" 0.01 "adaptive sphere volume refines beyond symmetric first pass"
|
||||
assert_contains "Density 123 on region /missing_density.r is not defined in the density table." gqa.missing_density.out "undefined density produces an error"
|
||||
|
||||
|
||||
if [ $STATUS = 0 ] ; then
|
||||
|
||||
@@ -68,6 +68,7 @@ set(
|
||||
sca_view.mged
|
||||
search_exec.mged
|
||||
sed.mged
|
||||
sed_reset.mged
|
||||
set_perspective.mged
|
||||
setview.mged
|
||||
size.mged
|
||||
@@ -100,6 +101,7 @@ if(TARGET mged)
|
||||
continue()
|
||||
endif(TNAME STREQUAL "")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${testfile}")
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${testfile}" TEST_CONTENTS)
|
||||
if(TNAME STREQUAL "search_exec")
|
||||
string(CONFIGURE "${TEST_CONTENTS}" TEST_CONTENTS @ONLY)
|
||||
@@ -126,6 +128,12 @@ if(TARGET mged)
|
||||
elseif(TNAME STREQUAL "arb")
|
||||
set(TEST_EXPECT "'arb' testing completed")
|
||||
set(TEST_SOURCE "${CMAKE_CURRENT_BINARY_DIR}/regress_${testfile}")
|
||||
elseif(TNAME MATCHES "^(extrude|facedef|mirface|permute)$")
|
||||
set(TEST_EXPECT "'${TNAME}' testing completed")
|
||||
set(TEST_SOURCE "${CMAKE_CURRENT_BINARY_DIR}/regress_${testfile}")
|
||||
elseif(TNAME STREQUAL "edgedir")
|
||||
set(TEST_EXPECT "'edarb edgedir' testing completed")
|
||||
set(TEST_SOURCE "${CMAKE_CURRENT_BINARY_DIR}/regress_${testfile}")
|
||||
elseif(TNAME STREQUAL "killtree")
|
||||
set(TEST_EXPECT "KILL Solid: killtree_dup.s")
|
||||
set(TEST_REJECT "db_lookup(killtree_dup.s) failed")
|
||||
@@ -138,6 +146,10 @@ if(TARGET mged)
|
||||
elseif(TNAME STREQUAL "prim_edit")
|
||||
set(TEST_EXPECT "Primitive parameter editing testing completed")
|
||||
set(TEST_REJECT "FAIL:")
|
||||
elseif(TNAME STREQUAL "sed_reset")
|
||||
set(TEST_EXPECT "PASS: 'sed_reset' testing completed")
|
||||
set(TEST_REJECT "FAIL:")
|
||||
set(TEST_SOURCE "${CMAKE_CURRENT_BINARY_DIR}/regress_${testfile}")
|
||||
elseif(TNAME STREQUAL "overlap_plotting")
|
||||
set(TEST_DB "${CMAKE_SOURCE_DIR}/src/libged/tests/ged_tests.g")
|
||||
set(TEST_EXPECT "PASS overlap plotting")
|
||||
@@ -187,6 +199,7 @@ distclean(${mged_outfiles})
|
||||
|
||||
cmakefiles(
|
||||
CMakeLists.txt
|
||||
csg_edit.mged
|
||||
mged.tcl
|
||||
regression_resources.tcl
|
||||
search_exec_procs.tcl
|
||||
|
||||
@@ -119,4 +119,35 @@ if {![catch {get $invalid_inner}]} {
|
||||
}
|
||||
|
||||
|
||||
# ARBN uses one independent thickness per plane. Exercise unequal offsets so
|
||||
# the test also verifies the plane ordering and inward normal convention.
|
||||
set arbn_outer inside_arbn_outer.s
|
||||
set arbn_inner inside_arbn_inner.s
|
||||
set arbn_thicknesses {1 2 3 4 1.5 0.5}
|
||||
in $arbn_outer arbn 6 \
|
||||
1 0 0 10 -1 0 0 0 \
|
||||
0 1 0 10 0 -1 0 0 \
|
||||
0 0 1 10 0 0 -1 0
|
||||
if {[catch {inside $arbn_outer $arbn_inner {*}$arbn_thicknesses} result]} {
|
||||
error "inside failed for ARBN: $result"
|
||||
}
|
||||
set arbn_definition [get $arbn_inner]
|
||||
set expected_offsets {9 -2 7 -4 8.5 -0.5}
|
||||
for {set plane 0} {$plane < 6} {incr plane} {
|
||||
set equation [lindex $arbn_definition [expr {4 + 2 * $plane}]]
|
||||
set actual_offset [lindex $equation 3]
|
||||
if {abs($actual_offset - [lindex $expected_offsets $plane]) > $plane_tolerance} {
|
||||
error "ARBN inside plane $plane has offset $actual_offset: $arbn_definition"
|
||||
}
|
||||
}
|
||||
facetize -n inside_arbn_inner_nmg.s $arbn_inner
|
||||
|
||||
set invalid_arbn_inner inside_arbn_invalid.s
|
||||
if {![catch {inside $arbn_outer $invalid_arbn_inner {*}[lrepeat 6 6]}]} {
|
||||
error "ARBN inside accepted thicknesses that collapse the solid"
|
||||
}
|
||||
if {![catch {get $invalid_arbn_inner}]} {
|
||||
error "ARBN inside wrote an invalid collapsed solid"
|
||||
}
|
||||
|
||||
puts "*** 'arb' testing completed ***"
|
||||
|
||||
@@ -962,8 +962,140 @@ foreach test [list \
|
||||
csg_matrix_mouse_check {*}$test
|
||||
}
|
||||
|
||||
puts "--- Repeated graphical object transforms ---"
|
||||
proc csg_matrix_repeated_mouse_check {} {
|
||||
global orig_gui transform csg_mouse_dm_pixels csg_mouse_view_size
|
||||
global csg_drag_scale
|
||||
set prim csg_matrix_repeat.s
|
||||
set inner csg_matrix_repeat_inner.c
|
||||
set outer csg_matrix_repeat_outer.c
|
||||
set saved_orig_gui $orig_gui
|
||||
set expected [csg_edit_identity_matrix]
|
||||
set failed [catch {
|
||||
in $prim sph 0 0 0 10
|
||||
comb $inner u $prim
|
||||
comb $outer u $inner
|
||||
set orig_gui 0
|
||||
for {set step 0} {$step < 16} {incr step} {
|
||||
e $outer
|
||||
center 0 0 0
|
||||
size $csg_mouse_view_size
|
||||
setview 0 0 0
|
||||
dm size $csg_mouse_dm_pixels $csg_mouse_dm_pixels
|
||||
_mged_press oill
|
||||
_mged_ill -e -i 1 /$outer/$inner/$prim
|
||||
_mged_matpick 2
|
||||
if {[status state] ne "OBJ EDIT" || $transform ne "e"} {
|
||||
error "step $step did not enter object editing"
|
||||
}
|
||||
set view_before [csg_edit_view_state]
|
||||
if {$step % 2 == 0} {
|
||||
press Rotate
|
||||
dm con r z 100 100
|
||||
set operation [csg_matrix_axis_rotation z 10]
|
||||
set motion {dm motion 140 100}
|
||||
} else {
|
||||
press Scale
|
||||
dm am s 100 100
|
||||
set operation [csg_matrix_scale all $csg_drag_scale]
|
||||
set motion {dm motion 164 100}
|
||||
}
|
||||
set motion_code [catch {uplevel #0 $motion} motion_result]
|
||||
if {$motion_code != 0 && $motion_code != 2} {
|
||||
error "step $step mouse motion failed: $motion_result"
|
||||
}
|
||||
dm idle
|
||||
press accept
|
||||
set expected [csg_matrix_multiply $operation $expected]
|
||||
csg_edit_comb_leaf_matrix_at $inner $prim $expected
|
||||
csg_edit_view_state_at $view_before
|
||||
d $outer
|
||||
}
|
||||
} failure]
|
||||
set orig_gui $saved_orig_gui
|
||||
catch {press reject}
|
||||
catch {Z}
|
||||
foreach object [list $outer $inner $prim] {
|
||||
catch {kill $object}
|
||||
}
|
||||
if {$failed} {
|
||||
puts " FAIL: repeated object mouse rotations/scales ($failure)"
|
||||
} else {
|
||||
puts " PASS: repeated object mouse rotations/scales"
|
||||
}
|
||||
}
|
||||
csg_matrix_repeated_mouse_check
|
||||
|
||||
puts "--- All ARB point, edge, and face states ---"
|
||||
|
||||
proc csg_edit_sed_point {attribute} {
|
||||
set serialized [get_sed]
|
||||
set index [lsearch -exact $serialized $attribute]
|
||||
if {$index < 0 || $index + 1 >= [llength $serialized]} {
|
||||
error "get_sed has no $attribute: $serialized"
|
||||
}
|
||||
return [lindex $serialized [expr {$index + 1}]]
|
||||
}
|
||||
|
||||
proc csg_arb_repeated_mouse_check {} {
|
||||
global orig_gui csg_bv_coord_half_range csg_mouse_dm_pixels
|
||||
global csg_mouse_view_size
|
||||
set source csg_lifecycle_arb5.s
|
||||
set prim csg_arb_repeat.s
|
||||
set saved_orig_gui $orig_gui
|
||||
set expected {}
|
||||
set failed [catch {
|
||||
cp $source $prim
|
||||
e $prim
|
||||
center 0 0 0
|
||||
size $csg_mouse_view_size
|
||||
setview 0 0 0
|
||||
dm size $csg_mouse_dm_pixels $csg_mouse_dm_pixels
|
||||
set orig_gui 0
|
||||
sed $prim
|
||||
press {Move Edges}
|
||||
press {Move Point 5}
|
||||
set original_z [lindex [db get $source V5] 2]
|
||||
for {set step 0} {$step < 64} {incr step} {
|
||||
if {$step > 0 && $step % 8 == 0} {
|
||||
press sedit
|
||||
press {Move Edges}
|
||||
press {Move Point 5}
|
||||
}
|
||||
set mouse_x [expr {150 + 2 * ($step % 5)}]
|
||||
set mouse_y [expr {150 + 2 * (($step * 3) % 5)}]
|
||||
M 1 $mouse_x $mouse_y
|
||||
set expected [list \
|
||||
[expr {$mouse_x / $csg_bv_coord_half_range * $csg_mouse_view_size / 2.0}] \
|
||||
[expr {$mouse_y / $csg_bv_coord_half_range * $csg_mouse_view_size / 2.0}] \
|
||||
$original_z]
|
||||
set actual [csg_edit_sed_point V5]
|
||||
if {[csg_edit_point_distance $actual $expected] > 0.000001} {
|
||||
error "step $step expected V5 $expected, got $actual"
|
||||
}
|
||||
}
|
||||
press accept
|
||||
d $prim
|
||||
if {[csg_edit_point_distance [db get $prim V5] $expected] > 0.000001} {
|
||||
error "accepted V5 differs from the final mouse target"
|
||||
}
|
||||
foreach vertex {V1 V2 V3 V4} {
|
||||
csg_edit_point_matches_source $source $vertex $prim
|
||||
}
|
||||
arb_standard_storage_check arb5 $prim
|
||||
} failure]
|
||||
set orig_gui $saved_orig_gui
|
||||
catch {press reject}
|
||||
catch {d $prim}
|
||||
catch {kill $prim}
|
||||
if {$failed} {
|
||||
puts " FAIL: repeated ARB5 mouse movement ($failure)"
|
||||
} else {
|
||||
puts " PASS: repeated ARB5 mouse movement"
|
||||
}
|
||||
}
|
||||
csg_arb_repeated_mouse_check
|
||||
|
||||
# Every ARB menu entry is checked independently. The variants do not share
|
||||
# menu indices, so sampling one edge or face would miss precisely the class of
|
||||
# integration failure this test is intended to catch. Move each selection a
|
||||
@@ -1322,6 +1454,280 @@ csg_edit_sequence_check csg_lifecycle_dsp.s "Toggle Smooth" {
|
||||
{press {Toggle Smooth}}
|
||||
} [list csg_edit_scalar_at sm 1]
|
||||
|
||||
puts "--- Specialized mouse editing and menu inventory ---"
|
||||
proc csg_edit_prepare_mouse_view {} {
|
||||
global csg_dispatch_view_size
|
||||
center 0 0 0
|
||||
size $csg_dispatch_view_size
|
||||
setview 0 0 0
|
||||
}
|
||||
array set csg_mouse_covered {}
|
||||
proc csg_mouse_case {source menu_items label commands validator} {
|
||||
global csg_mouse_covered
|
||||
csg_edit_sequence_check $source $label $commands $validator
|
||||
set type [lindex [db get $source] 0]
|
||||
if {![info exists csg_mouse_covered($type)]} {
|
||||
set csg_mouse_covered($type) {}
|
||||
}
|
||||
foreach item $menu_items {
|
||||
if {[lsearch -exact $csg_mouse_covered($type) $item] < 0} {
|
||||
lappend csg_mouse_covered($type) $item
|
||||
}
|
||||
}
|
||||
}
|
||||
proc csg_edit_menu_inventory_check {source ignored} {
|
||||
global csg_mouse_covered
|
||||
if {[catch {
|
||||
Z
|
||||
e $source
|
||||
sed $source
|
||||
set actual [mmenu_get 0]
|
||||
set type [lindex [db get $source] 0]
|
||||
set covered {}
|
||||
if {[info exists csg_mouse_covered($type)]} {
|
||||
set covered $csg_mouse_covered($type)
|
||||
}
|
||||
foreach item $actual {
|
||||
set tested [expr {[lsearch -exact $covered $item] >= 0}]
|
||||
set exempt [expr {[lsearch -exact $ignored $item] >= 0}]
|
||||
if {$tested == $exempt} {
|
||||
error "menu entry '$item' needs exactly one mouse-test or exclusion"
|
||||
}
|
||||
}
|
||||
foreach item [concat $covered $ignored] {
|
||||
if {[lsearch -exact $actual $item] < 0} {
|
||||
error "recorded menu entry '$item' is absent from $actual"
|
||||
}
|
||||
}
|
||||
press reject
|
||||
d $source
|
||||
} failure]} {
|
||||
puts " FAIL: menu inventory $source ($failure)"
|
||||
catch {press reject}
|
||||
catch {Z}
|
||||
} else {
|
||||
puts " PASS: menu inventory $source"
|
||||
}
|
||||
}
|
||||
|
||||
csg_edit_prepare_mouse_view
|
||||
set csg_special_mouse_target [list \
|
||||
[expr {512.0 / $csg_bv_coord_half_range * $csg_dispatch_view_size / 2.0}] \
|
||||
[expr {512.0 / $csg_bv_coord_half_range * $csg_dispatch_view_size / 2.0}] 0]
|
||||
set csg_special_mouse_scale [expr {1.0 + 2047.0 / ($csg_bv_coord_half_range * 4.0)}]
|
||||
set csg_special_mouse_shrink [expr {
|
||||
1.0 / (1.0 + 1024.0 / ($csg_bv_coord_half_range * 4.0))}]
|
||||
csg_mouse_case csg_lifecycle_pipe.s {{Move Point}} "mouse select and move point" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Select Point}}
|
||||
{p 0 0 0}
|
||||
{press {Move Point}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_point_at V0 $csg_special_mouse_target]
|
||||
in csg_mouse_pipe_topology.s pipe 4 \
|
||||
0 0 0 1 2 3 \
|
||||
0 0 30 1 2 3 \
|
||||
30 40 80 1 2 3 \
|
||||
80 80 100 1 2 3
|
||||
csg_mouse_case csg_mouse_pipe_topology.s {{Select Point} {Move Point}} "mouse select point" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Select Point}}
|
||||
{M 1 0 0}
|
||||
{press {Move Point}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_point_at V0 $csg_special_mouse_target]
|
||||
csg_mouse_case csg_mouse_pipe_topology.s {{Append Point}} "mouse append point" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Append Point}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_point_at V4 {5 5 0}]
|
||||
csg_mouse_case csg_mouse_pipe_topology.s {{Prepend Point}} "mouse prepend point" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Prepend Point}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_point_at V0 {5 5 0}]
|
||||
csg_mouse_case csg_mouse_pipe_topology.s {{Split Segment}} "mouse split segment" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Select Point}}
|
||||
{p 0 0 0}
|
||||
{press {Split Segment}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_point_at V1 {5 5 0}]
|
||||
foreach {item attribute initial} {
|
||||
{Set Point OD} O0 5
|
||||
{Set Point ID} I0 3
|
||||
{Set Point Bend} R0 6
|
||||
} {
|
||||
csg_mouse_case csg_lifecycle_pipe.s [list $item] "mouse $item" [list \
|
||||
{csg_edit_prepare_mouse_view} \
|
||||
{press {Select Point}} {p 0 0 0} [list press $item] \
|
||||
{M 1 0 -1024}] \
|
||||
[list csg_edit_scalar_at $attribute [expr {$initial * $csg_special_mouse_shrink}]]
|
||||
}
|
||||
foreach {item attributes initial} {
|
||||
{Set Pipe OD} {O0 O1 O2 O3} {5 5 6 6}
|
||||
{Set Pipe ID} {I0 I1 I2 I3} {3 3 2 0}
|
||||
{Set Pipe Bend} {R0 R1 R2 R3} {6 7 10 8}
|
||||
} {
|
||||
set expected {}
|
||||
foreach value $initial {
|
||||
lappend expected [expr {$value * $csg_special_mouse_shrink}]
|
||||
}
|
||||
csg_mouse_case csg_lifecycle_pipe.s [list $item] "mouse $item" [list \
|
||||
{csg_edit_prepare_mouse_view} \
|
||||
[list press $item] {M 1 0 -1024}] \
|
||||
[list csg_edit_scalar_values_at $attributes $expected]
|
||||
}
|
||||
proc csg_edit_bot_vertices_moved {source moved delta prim} {
|
||||
set vertices [db get $source V]
|
||||
for {set index 0} {$index < [llength $vertices]} {incr index} {
|
||||
set expected [lindex $vertices $index]
|
||||
if {[lsearch -exact $moved $index] >= 0} {
|
||||
set translated {}
|
||||
foreach value $expected shift $delta {
|
||||
lappend translated [expr {$value + $shift}]
|
||||
}
|
||||
set expected $translated
|
||||
}
|
||||
csg_edit_list_value_at V $index $expected $prim
|
||||
}
|
||||
}
|
||||
csg_mouse_case csg_lifecycle_bot.s {{Move Vertex}} "mouse move vertex" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Pick Vertex}}
|
||||
{p 0}
|
||||
{press {Move Vertex}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_bot_vertices_moved csg_lifecycle_bot.s {0} \
|
||||
$csg_special_mouse_target]
|
||||
csg_mouse_case csg_lifecycle_bot.s {{Pick Vertex} {Move Vertex}} "mouse pick and move vertex" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Pick Vertex}}
|
||||
{M 1 0 0}
|
||||
{press {Move Vertex}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_bot_vertices_moved csg_lifecycle_bot.s {0} \
|
||||
$csg_special_mouse_target]
|
||||
csg_mouse_case csg_lifecycle_bot.s {{Move Edge}} "mouse move edge" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Pick Edge}}
|
||||
{p 0 1}
|
||||
{press {Move Edge}}
|
||||
{M 1 1024 512}
|
||||
} [list csg_edit_bot_vertices_moved csg_lifecycle_bot.s {0 1} {10 5 0}]
|
||||
csg_mouse_case csg_lifecycle_bot.s {{Pick Edge} {Move Edge}} "mouse pick and move edge" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Pick Edge}}
|
||||
{M 1 512 512}
|
||||
{press {Move Edge}}
|
||||
{M 1 1024 512}
|
||||
} [list csg_edit_bot_vertices_moved csg_lifecycle_bot.s {0 1} {10 5 0}]
|
||||
csg_mouse_case csg_lifecycle_bot.s {{Move Triangle}} "mouse move triangle" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Pick Triangle}}
|
||||
{p 0 1 2}
|
||||
{press {Move Triangle}}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_bot_vertices_moved csg_lifecycle_bot.s {0 1 2} \
|
||||
$csg_special_mouse_target]
|
||||
csg_mouse_case csg_lifecycle_ebm.s {{Extrude Depth}} "mouse extrusion depth" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Extrude Depth}}
|
||||
{M 1 0 2047}
|
||||
} [list csg_edit_scalar_at H [expr {4.0 * $csg_special_mouse_scale}]]
|
||||
csg_mouse_case csg_lifecycle_vol.s {{Threshold (low)}} "mouse low threshold" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Threshold (low)}}
|
||||
{p 10}
|
||||
{M 1 0 2047}
|
||||
} [list csg_edit_scalar_at lo [expr {int(10.0 * $csg_special_mouse_scale)}]]
|
||||
csg_mouse_case csg_lifecycle_vol.s {{Voxel Size (X Y Z)}} "mouse voxel size" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Voxel Size (X Y Z)}}
|
||||
{M 1 0 2047}
|
||||
} [list csg_edit_point_at size [list \
|
||||
$csg_special_mouse_scale $csg_special_mouse_scale $csg_special_mouse_scale]]
|
||||
csg_mouse_case csg_lifecycle_vol.s {{Threshold (hi)}} "mouse high threshold" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Threshold (hi)}}
|
||||
{M 1 0 -1024}
|
||||
} [list csg_edit_scalar_at hi [expr {int(255.0 * $csg_special_mouse_shrink)}]]
|
||||
csg_mouse_case csg_lifecycle_dsp.s {{Set X}} "mouse X scale" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{press {Set X}}
|
||||
{M 1 0 2047}
|
||||
} [list csg_edit_matrix_component_at stom 0 $csg_special_mouse_scale]
|
||||
foreach {item index} {{Set Y} 5 {Set ALT} 10} {
|
||||
csg_mouse_case csg_lifecycle_dsp.s [list $item] "mouse $item" [list \
|
||||
{csg_edit_prepare_mouse_view} \
|
||||
[list press $item] {M 1 0 2047}] \
|
||||
[list csg_edit_matrix_component_at stom $index $csg_special_mouse_scale]
|
||||
}
|
||||
foreach type {arbn brep} {
|
||||
set source csg_lifecycle_${type}.s
|
||||
csg_edit_sequence_check $source "generic mouse translation" {
|
||||
{csg_edit_prepare_mouse_view}
|
||||
{keypoint 0 0 0}
|
||||
{press sxy}
|
||||
{M 1 512 512}
|
||||
} [list csg_edit_bbox_translated $source $csg_special_mouse_target]
|
||||
}
|
||||
|
||||
# Every specialized menu entry must be accounted for. Exclusions are menu
|
||||
# headings, non-positional actions/settings, or the BOT triangle picker (tested
|
||||
# under Xmin because it needs Tk). A new entry without a mouse case or
|
||||
# explicit exclusion fails here.
|
||||
foreach {source ignored} {
|
||||
csg_lifecycle_pipe.s {
|
||||
{PIPE MENU} {Next Point} {Previous Point} {Delete Point}
|
||||
}
|
||||
csg_lifecycle_bot.s {
|
||||
{BOT MENU} {Pick Triangle} {Move Vertex List}
|
||||
{Split Edge} {Split Face} {Fuse Vertices} {Fuse Faces}
|
||||
{Delete Triangle} {Select Mode} {Select Orientation}
|
||||
{Set flags} {Set Face Thickness} {Set Face Mode}
|
||||
}
|
||||
csg_lifecycle_dsp.s {
|
||||
{DSP MENU} Name {Toggle Smooth} {Set Data Source}
|
||||
}
|
||||
csg_lifecycle_ebm.s {
|
||||
{EBM MENU} {File Name} {File Size (W N)}
|
||||
}
|
||||
csg_lifecycle_vol.s {
|
||||
{VOL MENU} {File Name} {File Size (X Y Z)}
|
||||
}
|
||||
csg_lifecycle_arbn.s {}
|
||||
csg_lifecycle_brep.s {}
|
||||
} {
|
||||
csg_edit_menu_inventory_check $source $ignored
|
||||
}
|
||||
|
||||
# A view-space request must remain view-space even when the editor's current
|
||||
# coordinate system is object-relative. This is the fast path underlying the
|
||||
# corresponding real mouse drag in the Xmin GUI test.
|
||||
set csg_saved_coords [rset var coords]
|
||||
set csg_saved_transform [rset var transform]
|
||||
if {[catch {
|
||||
Z
|
||||
e csg_lifecycle_bot.s
|
||||
sed csg_lifecycle_bot.s
|
||||
center 0 0 0
|
||||
rset var coords o
|
||||
rset var transform v
|
||||
knob -i -v aX 1
|
||||
if {[csg_edit_point_distance [center] {-1 0 0}] > 0.000001} {
|
||||
error "explicit view knob left center at [center]"
|
||||
}
|
||||
} csg_view_override_error]} {
|
||||
puts " FAIL: view-space translation with object coordinates ($csg_view_override_error)"
|
||||
} else {
|
||||
puts " PASS: view-space translation with object coordinates"
|
||||
}
|
||||
catch {press reject}
|
||||
catch {Z}
|
||||
rset var coords $csg_saved_coords
|
||||
rset var transform $csg_saved_transform
|
||||
|
||||
file delete -force $csg_data_file
|
||||
file delete -force $csg_dsp_file
|
||||
|
||||
|
||||
@@ -43,4 +43,37 @@ foreach {arb_type face expected_type} $arb_extrude_cases {
|
||||
arb_standard_storage_check $expected_type $prim
|
||||
}
|
||||
|
||||
# A one-inch extrusion must extend a face by 25.4 base millimeters through
|
||||
# both the direct libged command and MGED's interactive solid editor.
|
||||
set inch_in_mm 25.4
|
||||
set tolerance 0.001
|
||||
foreach mode {direct interactive} {
|
||||
set suffix "_inch_$mode"
|
||||
in_arb8 extrude $suffix
|
||||
set prim "extrude_arb8${suffix}.s"
|
||||
set base_x [lindex [db get $prim V1] 0]
|
||||
|
||||
units in
|
||||
if {$mode eq "direct"} {
|
||||
if {[catch {edarb extrude $prim 1234 1} result]} {
|
||||
error "inch edarb extrusion failed: $result"
|
||||
}
|
||||
} else {
|
||||
Z
|
||||
e $prim
|
||||
sed $prim
|
||||
if {[catch {extrude 1234 1} result]} {
|
||||
error "inch MGED extrusion failed: $result"
|
||||
}
|
||||
accept
|
||||
Z
|
||||
}
|
||||
units mm
|
||||
|
||||
set new_x [lindex [db get $prim V5] 0]
|
||||
if {abs($new_x - $base_x - $inch_in_mm) > $tolerance} {
|
||||
error "inch $mode extrusion moved V5 by [expr {$new_x - $base_x}] mm"
|
||||
}
|
||||
}
|
||||
|
||||
puts "*** 'extrude' testing completed ***"
|
||||
|
||||
@@ -31,6 +31,7 @@ in tor_pe.s tor 0 0 0 0 0 1 20 2
|
||||
prim_edit_check tor_pe.s "Set Radius 1" 30 r_a 30 -1
|
||||
prim_edit_check tor_pe.s "Set Radius 2" 5 r_h 5 -1
|
||||
prim_edit_mouse_check tor_pe.s "Set Radius 1" r_a 30 -1
|
||||
prim_edit_mouse_check tor_pe.s "Set Radius 2" r_h 5 -1
|
||||
kill tor_pe.s
|
||||
|
||||
puts "--- ELL (ellipsoid: A, B, C) ---"
|
||||
@@ -39,6 +40,8 @@ prim_edit_check ell_pe.s "Set A" 8 A 8 0
|
||||
prim_edit_check ell_pe.s "Set B" 6 B 6 1
|
||||
prim_edit_check ell_pe.s "Set C" 4 C 4 2
|
||||
prim_edit_mouse_check ell_pe.s "Set A" A 8 0
|
||||
prim_edit_mouse_check ell_pe.s "Set B" B 6 1
|
||||
prim_edit_mouse_check ell_pe.s "Set C" C 4 2
|
||||
kill ell_pe.s
|
||||
|
||||
puts "--- RPC (right parabolic cylinder: H, r) ---"
|
||||
@@ -46,6 +49,7 @@ in rpc_pe.s rpc 0 0 0 0 0 10 0 5 0 3
|
||||
prim_edit_check rpc_pe.s "Set H" 20 H 20 2
|
||||
prim_edit_check rpc_pe.s "Set r" 6 r 6 -1
|
||||
prim_edit_mouse_check rpc_pe.s "Set H" H 20 2
|
||||
prim_edit_mouse_check rpc_pe.s "Set r" r 6 -1
|
||||
kill rpc_pe.s
|
||||
|
||||
puts "--- RHC (right hyperbolic cylinder: H, r, c) ---"
|
||||
@@ -54,6 +58,8 @@ prim_edit_check rhc_pe.s "Set H" 20 H 20 2
|
||||
prim_edit_check rhc_pe.s "Set r" 6 r 6 -1
|
||||
prim_edit_check rhc_pe.s "Set c" 3 c 3 -1
|
||||
prim_edit_mouse_check rhc_pe.s "Set r" r 6 -1
|
||||
prim_edit_mouse_check rhc_pe.s "Set H" H 20 2
|
||||
prim_edit_mouse_check rhc_pe.s "Set c" c 3 -1
|
||||
kill rhc_pe.s
|
||||
|
||||
puts "--- EPA (elliptical paraboloid: H, r_1, r_2) ---"
|
||||
@@ -62,6 +68,8 @@ prim_edit_check epa_pe.s "Set H" 20 H 20 2
|
||||
prim_edit_check epa_pe.s "Set A" 8 r_1 8 -1
|
||||
prim_edit_check epa_pe.s "Set B" 4 r_2 4 -1
|
||||
prim_edit_mouse_check epa_pe.s "Set H" H 20 2
|
||||
prim_edit_mouse_check epa_pe.s "Set A" r_1 8 -1
|
||||
prim_edit_mouse_check epa_pe.s "Set B" r_2 4 -1
|
||||
kill epa_pe.s
|
||||
|
||||
puts "--- EHY (elliptical hyperboloid: H, r_1, c) ---"
|
||||
@@ -70,6 +78,8 @@ prim_edit_check ehy_pe.s "Set H" 20 H 20 2
|
||||
prim_edit_check ehy_pe.s "Set A" 8 r_1 8 -1
|
||||
prim_edit_check ehy_pe.s "Set c" 3 c 3 -1
|
||||
prim_edit_mouse_check ehy_pe.s "Set A" r_1 8 -1
|
||||
prim_edit_mouse_check ehy_pe.s "Set H" H 20 2
|
||||
prim_edit_mouse_check ehy_pe.s "Set c" c 3 -1
|
||||
kill ehy_pe.s
|
||||
|
||||
puts "--- PART (particle: H, r_v, r_h) ---"
|
||||
@@ -78,6 +88,8 @@ prim_edit_check part_pe.s "Set H" 20 H 20 2
|
||||
prim_edit_check part_pe.s "Set v" 4 r_v 4 -1
|
||||
prim_edit_check part_pe.s "Set h" 3 r_h 3 -1
|
||||
prim_edit_mouse_check part_pe.s "Set v" r_v 4 -1
|
||||
prim_edit_mouse_check part_pe.s "Set H" H 20 2
|
||||
prim_edit_mouse_check part_pe.s "Set h" r_h 3 -1
|
||||
kill part_pe.s
|
||||
|
||||
puts "--- TGC (truncated general cone: H, A, B, C, D) ---"
|
||||
@@ -91,6 +103,10 @@ prim_edit_check tgc_pe.s "Set B" 3 B 3 1
|
||||
prim_edit_check tgc_pe.s "Set C" 3 C 3 0
|
||||
prim_edit_check tgc_pe.s "Set D" 4 D 4 1
|
||||
prim_edit_mouse_check tgc_pe.s "Set H" H 8 2
|
||||
prim_edit_mouse_check tgc_pe.s "Set A" A 4 0
|
||||
prim_edit_mouse_check tgc_pe.s "Set B" B 3 1
|
||||
prim_edit_mouse_check tgc_pe.s "Set C" C 3 0
|
||||
prim_edit_mouse_check tgc_pe.s "Set D" D 4 1
|
||||
kill tgc_pe.s
|
||||
|
||||
puts "--- ETO (elliptical torus: r, C, D) ---"
|
||||
@@ -100,6 +116,7 @@ prim_edit_check eto_pe.s "Set r" 8 r 8 -1
|
||||
prim_edit_check eto_pe.s "Set D" 1.5 r_d 1.5 -1
|
||||
prim_edit_mouse_check eto_pe.s "Set r" r 8 -1
|
||||
prim_edit_mouse_check eto_pe.s "Set C" C 5 0
|
||||
prim_edit_mouse_check eto_pe.s "Set D" r_d 1.5 -1
|
||||
kill eto_pe.s
|
||||
|
||||
puts "--- HYP (one-sheet hyperboloid: H, A, B, c) ---"
|
||||
@@ -111,6 +128,9 @@ prim_edit_check hyp_pe.s "Set A" 2 A 10 1
|
||||
prim_edit_check hyp_pe.s "Set B" 2 b 4 -1
|
||||
prim_edit_check hyp_pe.s "Set c" 0.5 bnr 0.25 -1
|
||||
prim_edit_mouse_check hyp_pe.s "Set H" H 20 2
|
||||
prim_edit_mouse_check hyp_pe.s "Set A" A 10 1
|
||||
prim_edit_mouse_check hyp_pe.s "Set B" b 4 -1
|
||||
prim_edit_mouse_check hyp_pe.s "Set c" bnr 0.25 -1
|
||||
kill hyp_pe.s
|
||||
|
||||
puts "--- SUPERELL (superellipsoid: A, B, C) ---"
|
||||
@@ -119,6 +139,8 @@ prim_edit_check superell_pe.s "Set A" 5 A 5 0
|
||||
prim_edit_check superell_pe.s "Set B" 4 B 4 1
|
||||
prim_edit_check superell_pe.s "Set C" 3 C 3 2
|
||||
prim_edit_mouse_check superell_pe.s "Set A" A 5 0
|
||||
prim_edit_mouse_check superell_pe.s "Set B" B 4 1
|
||||
prim_edit_mouse_check superell_pe.s "Set C" C 3 2
|
||||
kill superell_pe.s
|
||||
|
||||
puts "--- CLINE (cylinder line: H, R, plate thickness) ---"
|
||||
@@ -129,6 +151,7 @@ prim_edit_check cline_pe.s "Set R" 4 R 4 -1
|
||||
prim_edit_check cline_pe.s "Set plate thickness" 0.4 T 0.4 -1
|
||||
prim_edit_mouse_check cline_pe.s "Set H" H 8 2
|
||||
prim_edit_mouse_check cline_pe.s "Set R" R 4 -1
|
||||
prim_edit_mouse_check cline_pe.s "Set plate thickness" T 0.4 -1
|
||||
kill cline_pe.s
|
||||
|
||||
puts "--- NMG (non-manifold geometry: Pick Edge, Move Edge, Next EU) ---"
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
puts "*** Testing 'sed_reset' command ***"
|
||||
|
||||
proc sed_reset_check {primitive edit_commands} {
|
||||
e $primitive
|
||||
sed $primitive
|
||||
if {[status state] ne "SOL EDIT"} {
|
||||
error "$primitive entered [status state], not SOL EDIT"
|
||||
}
|
||||
|
||||
set original [get_sed]
|
||||
foreach command $edit_commands {
|
||||
uplevel #0 $command
|
||||
}
|
||||
if {[get_sed] eq $original} {
|
||||
error "$primitive edit did not change the working geometry"
|
||||
}
|
||||
|
||||
sed_reset
|
||||
if {[status state] ne "SOL EDIT"} {
|
||||
error "$primitive reset entered [status state], not SOL EDIT"
|
||||
}
|
||||
if {[get_sed] ne $original} {
|
||||
error "$primitive reset did not restore the original geometry"
|
||||
}
|
||||
|
||||
press reject
|
||||
if {[status state] ne "VIEWING"} {
|
||||
error "$primitive reject entered [status state], not VIEWING"
|
||||
}
|
||||
d $primitive
|
||||
}
|
||||
|
||||
if {[catch {
|
||||
in sed_reset_arb8.s arb8 \
|
||||
0 0 0 10 0 0 10 10 0 0 10 0 \
|
||||
0 0 10 10 0 10 10 10 10 0 10 10
|
||||
sed_reset_check sed_reset_arb8.s {
|
||||
{press {Move Faces}}
|
||||
{press {Move Face 1234}}
|
||||
{p 0 0 -1}
|
||||
}
|
||||
} failure]} {
|
||||
puts "FAIL: ARB8 face move reset ($failure)"
|
||||
catch {press reject}
|
||||
catch {Z}
|
||||
} else {
|
||||
puts "PASS: ARB8 face move reset"
|
||||
}
|
||||
|
||||
if {[catch {
|
||||
make sed_reset_cline.s cline
|
||||
sed_reset_check sed_reset_cline.s {
|
||||
{press {Move End H}}
|
||||
{p 3 4 12}
|
||||
}
|
||||
} failure]} {
|
||||
puts "FAIL: CLINE edit reset ($failure)"
|
||||
catch {press reject}
|
||||
catch {Z}
|
||||
} else {
|
||||
puts "PASS: CLINE edit reset"
|
||||
}
|
||||
|
||||
puts "PASS: 'sed_reset' testing completed"
|
||||
@@ -93,6 +93,7 @@ if(BRLCAD_X11_PROVIDER_RESOLVED STREQUAL "XMIN" AND
|
||||
"PLOT3_ASC_BIN=$<TARGET_FILE:plot3-asc>"
|
||||
)
|
||||
mged_add_xmin_gui_fixture(help "mged;dm-tkswrast;m35.g")
|
||||
mged_add_xmin_gui_fixture(edit-interaction "mged;dm-tkswrast;m35.g")
|
||||
mged_add_xmin_gui_fixture(bot "mged;dm-tkswrast;m35.g")
|
||||
mged_add_xmin_gui_fixture(editors "mged;dm-tkswrast;m35.g")
|
||||
mged_add_xmin_gui_fixture(query-pattern "mged;dm-tkswrast;m35.g")
|
||||
@@ -212,18 +213,19 @@ cmakefiles(
|
||||
mged/mged_xmin_gui.sh
|
||||
mged/xmin_gui_bot.tcl
|
||||
mged/xmin_gui_controls.tcl
|
||||
mged/xmin_gui_edit.tcl
|
||||
mged/xmin_gui_edit_interaction.tcl
|
||||
mged/xmin_gui_editors.tcl
|
||||
mged/xmin_gui_help.tcl
|
||||
mged/xmin_gui_lod.tcl
|
||||
mged/xmin_gui_overlaps.tcl
|
||||
mged/xmin_gui_pipe_oracle.tcl
|
||||
mged/xmin_gui_query_pattern.tcl
|
||||
mged/xmin_gui_render_outputs.tcl
|
||||
mged/xmin_gui_search_exec.tcl
|
||||
mged/xmin_gui_shotvis.tcl
|
||||
mged/xmin_gui_test.tcl
|
||||
mged/xmin_gui_workflows.tcl
|
||||
mged/xmin_gui_edit.tcl
|
||||
mged/xmin_gui_pipe_oracle.tcl
|
||||
)
|
||||
|
||||
# Local Variables:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -50,6 +50,18 @@ proc ::mged::xmin::help::exercise_command_manual {top} {
|
||||
::gui::test::require {
|
||||
[llength $selection] == 1 && [$toc get $selection] eq "rt"
|
||||
} "man rt did not select and load the rt manual page"
|
||||
|
||||
event generate $toc <<ListboxSelect>>
|
||||
::mged::gui::test::settle
|
||||
|
||||
man search
|
||||
set html_view [$browser component browser].htmlview
|
||||
set html_widget [$html_view html]
|
||||
$html_view goto {#hierarchy_performance}
|
||||
::mged::gui::test::settle
|
||||
::gui::test::require {[lindex [$html_widget yview] 0] > 0.0} \
|
||||
"manual browser did not follow an in-page hyperlink"
|
||||
|
||||
::gui::test::require {
|
||||
[catch {man xmin_page_that_does_not_exist} message] &&
|
||||
[string first "couldn't find manual page" $message] >= 0
|
||||
@@ -151,10 +163,38 @@ proc ::mged::xmin::help::exercise_html_manual {top} {
|
||||
set mged_browser [file join $::env(GUI_TEST_DIR) missing-browser]
|
||||
::mged::gui::test::invoke $top {Help Manual}
|
||||
set fallback $top.man
|
||||
set viewer $fallback.html
|
||||
::gui::test::require {
|
||||
[winfo exists $fallback] && [winfo ismapped $fallback] &&
|
||||
[string length [string trim [$fallback.text get 1.0 end]]] > 100
|
||||
[winfo exists $viewer] && [$viewer title] eq "Table of Contents"
|
||||
} "Manual did not load MGED's internal HTML viewer"
|
||||
|
||||
set special_path [file join [pwd] {manual path} {contents#1.html}]
|
||||
::gui::test::require {
|
||||
[::mged::manual::local_path \
|
||||
[::mged::manual::file_uri $special_path]] eq \
|
||||
[file normalize $special_path]
|
||||
} "internal Manual viewer did not preserve special path characters"
|
||||
|
||||
set html [$viewer html]
|
||||
set contents [$html text text]
|
||||
::gui::test::require {
|
||||
[string first "Preface" $contents] >= 0 &&
|
||||
[string first "background-color" $contents] < 0
|
||||
} "internal Manual viewer did not render its table of contents"
|
||||
|
||||
$viewer goto mged.html#csg
|
||||
::mged::gui::test::settle
|
||||
set contents [$html text text]
|
||||
::gui::test::require {
|
||||
[$viewer title] eq "Mged User's Manual" &&
|
||||
[string first "Modeling With CSG" $contents] >= 0
|
||||
} "internal Manual viewer did not follow its document links"
|
||||
|
||||
$fallback.f.back invoke
|
||||
::mged::gui::test::settle
|
||||
::gui::test::require {[$viewer title] eq "Table of Contents"} \
|
||||
"internal Manual viewer Back button did not restore the prior page"
|
||||
destroy $fallback
|
||||
}
|
||||
|
||||
|
||||
@@ -53,12 +53,23 @@ endif(BRLCAD_ENABLE_TCL)
|
||||
# Archer plugins
|
||||
set(
|
||||
archer_utility_FILES
|
||||
plugins/Utility/attrGroupsDisplayUtilityP.tcl
|
||||
plugins/Utility/botUtilityP.tcl
|
||||
plugins/Utility/lodUtilityP.tcl
|
||||
plugins/Utility/README
|
||||
plugins/Utility/attrGroupsDisplayUtilityP.tcl
|
||||
plugins/Utility/attrGroupsDisplayUtilityP/AttrGroupsDisplayUtilityP.tcl
|
||||
plugins/Utility/botUtilityP.tcl
|
||||
plugins/Utility/botUtilityP/BotUtilityP.tcl
|
||||
plugins/Utility/lodUtilityP.tcl
|
||||
plugins/Utility/lodUtilityP/LODUtilityP.tcl
|
||||
)
|
||||
set(archer_wizard_FILES
|
||||
plugins/Wizards/humanwizard.tcl
|
||||
plugins/Wizards/humanwizard/HumanWizard.tcl
|
||||
plugins/Wizards/tankwizard.tcl
|
||||
plugins/Wizards/tankwizard/TankWizard.tcl
|
||||
plugins/Wizards/tankwizard/images/tank.png
|
||||
plugins/Wizards/tirewizard.tcl
|
||||
plugins/Wizards/tirewizard/TireWizard.tcl
|
||||
)
|
||||
set(archer_wizard_FILES plugins/Wizards/humanwizard.tcl plugins/Wizards/tankwizard.tcl plugins/Wizards/tirewizard.tcl)
|
||||
|
||||
if(BRLCAD_ENABLE_TCL)
|
||||
brlcad_adddata(archer_utility_FILES plugins/archer/Utility)
|
||||
@@ -77,6 +88,8 @@ endif(BRLCAD_ENABLE_TCL)
|
||||
set(
|
||||
archer_ignore_files
|
||||
CMakeLists.txt
|
||||
plugins/Commands/README
|
||||
plugins/Core/README
|
||||
${archer_utility_FILES}
|
||||
${archer_wizard_FILES}
|
||||
${archer_txt}
|
||||
|
||||
+58
-26
@@ -272,11 +272,11 @@ color_hook(const struct bu_structparse *sp, const char *name, void *UNUSED(base)
|
||||
{
|
||||
struct bu_color color = BU_COLOR_INIT_ZERO;
|
||||
|
||||
BU_CK_STRUCTPARSE(sp);
|
||||
|
||||
if (!sp || !name || !value || sp->sp_count != 3 || bu_strcmp("%f", sp->sp_fmt))
|
||||
bu_bomb("color_hook(): invalid arguments");
|
||||
|
||||
BU_CK_STRUCTPARSE(sp);
|
||||
|
||||
if (!bu_color_from_str(&color, value)) {
|
||||
bu_log("ERROR: invalid color string: '%s'\n", value);
|
||||
VSETALL(color.buc_rgb, 0.0);
|
||||
@@ -400,7 +400,7 @@ art_validate_options(void)
|
||||
"path-tracer quality with -c \"set samples=<N>\" instead "
|
||||
"(current default is 25)");
|
||||
|
||||
if (use_air != 0 || airdensity != 0.0 || densityfile != NULL)
|
||||
if (use_air != 0 || !ZERO(airdensity) || densityfile != NULL)
|
||||
ART_WARN("-U air-region handling, -m atmospheric haze, and -d density "
|
||||
"file are ignored; art has no participating-media model");
|
||||
|
||||
@@ -480,8 +480,12 @@ namespace asr = renderer;
|
||||
static void
|
||||
art_parse_light_intensity(const struct bu_vls* shader, double* bright, double* fract)
|
||||
{
|
||||
*bright = 1.0;
|
||||
*fract = -1.0;
|
||||
if (bright)
|
||||
*bright = 1.0;
|
||||
if (fract)
|
||||
*fract = -1.0;
|
||||
if (!shader || !bright || !fract)
|
||||
return;
|
||||
|
||||
const char* s = bu_vls_cstr(shader);
|
||||
if (bu_strncmp(s, "light", 5) == 0)
|
||||
@@ -549,8 +553,11 @@ register_region(struct db_tree_state* tsp,
|
||||
bu_log("name: %s\n", conversion_temp.c_str());
|
||||
|
||||
// get objects bounding box
|
||||
struct ged* gedp;
|
||||
gedp = ged_open("db", tsp->ts_dbip->dbi_filename, 1);
|
||||
if (!tsp || !tsp->ts_dbip || !tsp->ts_dbip->dbi_filename)
|
||||
return 1;
|
||||
struct ged* gedp = ged_open("db", tsp->ts_dbip->dbi_filename, 1);
|
||||
if (gedp == GED_NULL)
|
||||
return 1;
|
||||
point_t min;
|
||||
point_t max;
|
||||
int ret = rt_obj_bounds(gedp->ged_result_str, gedp->dbip, 1, (const char**)&name_full, 1, min, max);
|
||||
@@ -738,6 +745,7 @@ register_region(struct db_tree_state* tsp,
|
||||
asf::Transformd::identity());
|
||||
scene->assembly_instances().insert(assembly_instance);
|
||||
|
||||
ged_close(gedp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -872,23 +880,32 @@ build_project(const char* file, const char* UNUSED(objects))
|
||||
// walk the db to register all regions
|
||||
struct db_tree_state state;
|
||||
RT_DBTS_INIT(&state);
|
||||
struct db_i* dbip = db_open(file, DB_OPEN_READONLY);
|
||||
state.ts_dbip = dbip;
|
||||
struct db_i* walk_dbip = (APP.a_rt_i && APP.a_rt_i->rti_dbip) ? APP.a_rt_i->rti_dbip : DBI_NULL;
|
||||
struct db_i* dbip = DBI_NULL;
|
||||
if (walk_dbip == DBI_NULL && file) {
|
||||
dbip = db_open(file, DB_OPEN_READONLY);
|
||||
walk_dbip = dbip;
|
||||
}
|
||||
state.ts_dbip = walk_dbip;
|
||||
|
||||
/* discovered lights are collected by register_region() during the walk */
|
||||
art_lights.clear();
|
||||
art_seen_regions.clear();
|
||||
|
||||
if (objc) {
|
||||
db_walk_tree(APP.a_rt_i->rti_dbip, objc, (const char**)objv, 1, &state, register_region, NULL, NULL, reinterpret_cast<void*>(scene.get()));
|
||||
}
|
||||
if (cmd_objs) {
|
||||
|
||||
size_t cmdobjc = BU_PTBL_LEN(cmd_objs);
|
||||
const char** cmdobjv = (const char**)cmd_objs->buffer;
|
||||
if (cmdobjc) {
|
||||
db_walk_tree(APP.a_rt_i->rti_dbip, (int)cmdobjc, cmdobjv, 1, &state, register_region, NULL, NULL, reinterpret_cast<void*>(scene.get()));
|
||||
if (walk_dbip) {
|
||||
if (objc) {
|
||||
db_walk_tree(walk_dbip, objc, (const char**)objv, 1, &state, register_region, NULL, NULL, reinterpret_cast<void*>(scene.get()));
|
||||
}
|
||||
if (cmd_objs) {
|
||||
size_t cmdobjc = BU_PTBL_LEN(cmd_objs);
|
||||
const char** cmdobjv = (const char**)cmd_objs->buffer;
|
||||
if (cmdobjc) {
|
||||
db_walk_tree(walk_dbip, (int)cmdobjc, cmdobjv, 1, &state, register_region, NULL, NULL, reinterpret_cast<void*>(scene.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dbip) {
|
||||
db_close(dbip);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@@ -1051,6 +1068,7 @@ build_project(const char* file, const char* UNUSED(objects))
|
||||
.insert("film_dimensions", bu_vls_cstr(&dimensions))
|
||||
.insert("horizontal_fov", bu_vls_cstr(&fov))
|
||||
));
|
||||
bu_vls_free(&fov);
|
||||
camera = pinhole;
|
||||
} else {
|
||||
// Create an orthographic camera with film dimensions
|
||||
@@ -1121,6 +1139,7 @@ build_project(const char* file, const char* UNUSED(objects))
|
||||
// Bind the scene to the project.
|
||||
project->set_scene(scene);
|
||||
|
||||
bu_vls_free(&dimensions);
|
||||
return project;
|
||||
}
|
||||
|
||||
@@ -1263,6 +1282,9 @@ def_tree(struct rt_i* rtip)
|
||||
static void
|
||||
art_save_image(asr::Project& project, const char* filename)
|
||||
{
|
||||
if (!filename || !project.get_frame())
|
||||
return;
|
||||
|
||||
const char* dot = strrchr(filename, '.');
|
||||
|
||||
/* Formats Appleseed writes directly: skip the round-trip. */
|
||||
@@ -1358,7 +1380,7 @@ art_cm_end(const int UNUSED(argc), const char** UNUSED(argv))
|
||||
renderer.reset();
|
||||
|
||||
// clean up resources
|
||||
|
||||
bu_vls_free(&str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1394,7 +1416,11 @@ main(int argc, char **argv)
|
||||
struct bu_vls str = BU_VLS_INIT_ZERO;
|
||||
//int objs_free_argv = 0;
|
||||
|
||||
bu_setprogname(argv[0]);
|
||||
if (argc > 0 && argv && argv[0]) {
|
||||
bu_setprogname(argv[0]);
|
||||
} else {
|
||||
bu_setprogname("art");
|
||||
}
|
||||
|
||||
// initialize options and overload menu before parsing
|
||||
init_defaults();
|
||||
@@ -1402,12 +1428,12 @@ main(int argc, char **argv)
|
||||
/* Process command line options */
|
||||
int i = get_args(argc, (const char**)argv);
|
||||
if (i < 0) {
|
||||
usage(argv[0], 0);
|
||||
usage(bu_getprogname(), 0);
|
||||
return 1;
|
||||
}
|
||||
// explicitly asking for help
|
||||
else if (i == 0) {
|
||||
usage(argv[0], 99);
|
||||
usage(bu_getprogname(), 99);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1416,8 +1442,8 @@ main(int argc, char **argv)
|
||||
art_validate_options();
|
||||
|
||||
if (bu_optind >= argc) {
|
||||
RENDERER_LOG_INFO("%s: BRL-CAD geometry database not specified\n", argv[0]);
|
||||
usage(argv[0], 0);
|
||||
RENDERER_LOG_INFO("%s: BRL-CAD geometry database not specified\n", bu_getprogname());
|
||||
usage(bu_getprogname(), 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1450,6 +1476,7 @@ main(int argc, char **argv)
|
||||
rtip = rt_dirbuild(title_file, title, sizeof(title));
|
||||
if (rtip == RTI_NULL) {
|
||||
RENDERER_LOG_INFO("building the database directory for [%s] FAILED\n", title_file);
|
||||
bu_free(resources, "appleseed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1476,7 +1503,8 @@ main(int argc, char **argv)
|
||||
|
||||
/* include objects from database */
|
||||
if (rt_gettrees(rtip, objc, (const char**)objv, (int)npsw) < 0) {
|
||||
RENDERER_LOG_INFO("loading the geometry for [%s...] FAILED\n", objv[0]);
|
||||
RENDERER_LOG_INFO("loading the geometry for [%s...] FAILED\n", (objv && objc > 0 && objv[0]) ? objv[0] : "objects");
|
||||
bu_free(resources, "appleseed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1499,6 +1527,7 @@ main(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
bu_free(resources, "appleseed");
|
||||
bu_vls_free(&str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1513,7 +1542,9 @@ main(int argc, char **argv)
|
||||
|
||||
if (framebuffer && !fbp) {
|
||||
RENDERER_LOG_INFO("FRAMEBUFFER IS ON\n");
|
||||
fb_setup();
|
||||
if (fb_setup() != 0 || fbp == FB_NULL) {
|
||||
framebuffer = NULL;
|
||||
}
|
||||
}
|
||||
ArtTileCallback artcallback;
|
||||
// Create the master renderer.
|
||||
@@ -1578,6 +1609,7 @@ main(int argc, char **argv)
|
||||
renderer.reset();
|
||||
}
|
||||
// clean up resources
|
||||
bu_vls_free(&str);
|
||||
bu_free(resources, "appleseed");
|
||||
|
||||
return 0;
|
||||
|
||||
+41
-15
@@ -120,7 +120,7 @@ thread_local struct BRLCAD_to_ASR brlcad_ray_info;
|
||||
|
||||
/* brlcad raytrace hit callback */
|
||||
int
|
||||
brlcad_hit(struct application* UNUSED(ap), struct partition* PartHeadp, struct seg* UNUSED(segs))
|
||||
brlcad_hit(struct application* ap, struct partition* PartHeadp, struct seg* UNUSED(segs))
|
||||
{
|
||||
struct partition* pp;
|
||||
struct hit* hitp = NULL;
|
||||
@@ -132,6 +132,9 @@ brlcad_hit(struct application* UNUSED(ap), struct partition* PartHeadp, struct s
|
||||
//point_t pt;
|
||||
vect_t inormal;
|
||||
|
||||
if (!ap || !PartHeadp)
|
||||
return 0;
|
||||
|
||||
// vect_t onormal;
|
||||
|
||||
/* Secondary path-tracing rays may originate inside a region. In that
|
||||
@@ -141,13 +144,13 @@ brlcad_hit(struct application* UNUSED(ap), struct partition* PartHeadp, struct s
|
||||
for (pp = PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) {
|
||||
if (pp->pt_inhit && pp->pt_inhit->hit_dist >= 0.0) {
|
||||
hitp = pp->pt_inhit;
|
||||
stp = pp->pt_inseg->seg_stp;
|
||||
stp = pp->pt_inseg ? pp->pt_inseg->seg_stp : NULL;
|
||||
flip = pp->pt_inflip;
|
||||
break;
|
||||
}
|
||||
if (pp->pt_outhit && pp->pt_outhit->hit_dist >= 0.0) {
|
||||
hitp = pp->pt_outhit;
|
||||
stp = pp->pt_outseg->seg_stp;
|
||||
stp = pp->pt_outseg ? pp->pt_outseg->seg_stp : NULL;
|
||||
flip = pp->pt_outflip;
|
||||
break;
|
||||
}
|
||||
@@ -213,15 +216,17 @@ BrlcadObject:: BrlcadObject(
|
||||
VSET(max, m_params.get_required<double>("maxX"), m_params.get_required<double>("maxY"), m_params.get_required<double>("maxZ"));
|
||||
|
||||
std::string db_file = m_params.get_required<std::string>("database_path");
|
||||
this->rtip = rt_i_create(p_ap->a_rt_i->rti_dbip);
|
||||
this->rtip = (p_ap && p_ap->a_rt_i && p_ap->a_rt_i->rti_dbip) ? rt_i_create(p_ap->a_rt_i->rti_dbip) : RTI_NULL;
|
||||
if (this->rtip == RTI_NULL) {
|
||||
RENDERER_LOG_INFO("building the database directory for [%s] FAILED\n", db_file.c_str());
|
||||
bu_exit(BRLCAD_ERROR, "building the database directory for [%s] FAILED\n", db_file.c_str());
|
||||
}
|
||||
|
||||
for (int ic = 0; ic < MAX_PSW; ic++) {
|
||||
rt_init_resource(&p_resources[ic], ic, this->rtip);
|
||||
RT_CK_RESOURCE(&p_resources[ic]);
|
||||
if (p_resources) {
|
||||
for (int ic = 0; ic < MAX_PSW; ic++) {
|
||||
rt_init_resource(&p_resources[ic], ic, this->rtip);
|
||||
RT_CK_RESOURCE(&p_resources[ic]);
|
||||
}
|
||||
}
|
||||
|
||||
rt_gettree(this->rtip, this->name->c_str());
|
||||
@@ -244,6 +249,10 @@ BrlcadObject::release()
|
||||
{
|
||||
// bu_free(resources, "appleseed");
|
||||
// bu_free(ap, "appleseed");
|
||||
if (this->rtip != RTI_NULL) {
|
||||
rt_i_destroy(this->rtip);
|
||||
this->rtip = RTI_NULL;
|
||||
}
|
||||
delete this->name;
|
||||
delete this;
|
||||
}
|
||||
@@ -316,10 +325,17 @@ BrlcadObject::intersect(
|
||||
const asr::ShadingRay& ray,
|
||||
IntersectionResult& result) const
|
||||
{
|
||||
if (!resources || !this->name) {
|
||||
result.m_hit = false;
|
||||
return;
|
||||
}
|
||||
|
||||
struct application app;
|
||||
app = ap; /*struct copy*/
|
||||
/* brlcad raytracing */
|
||||
int cpu = get_id();
|
||||
if (cpu < 0 || cpu >= MAX_PSW)
|
||||
cpu = 0;
|
||||
app.a_resource = &resources[cpu];
|
||||
|
||||
/* Honor the shading ray's valid interval [m_tmin, m_tmax). m_dir is NOT
|
||||
@@ -370,10 +386,15 @@ BrlcadObject::intersect(
|
||||
bool
|
||||
BrlcadObject::intersect(const asr::ShadingRay& ray) const
|
||||
{
|
||||
if (!resources || !this->name)
|
||||
return false;
|
||||
|
||||
struct application app;
|
||||
app = ap; /* struct copy */
|
||||
/* brlcad raytracing */
|
||||
int cpu = get_id();
|
||||
if (cpu < 0 || cpu >= MAX_PSW)
|
||||
cpu = 0;
|
||||
app.a_resource = &resources[cpu];
|
||||
|
||||
/* Occlusion test over the ray's [m_tmin, m_tmax) interval (see the detailed
|
||||
@@ -431,7 +452,9 @@ static std::atomic<int> counter;
|
||||
int
|
||||
BrlcadObject::get_id()
|
||||
{
|
||||
thread_local int id = counter++;
|
||||
thread_local int id = (counter++) % MAX_PSW;
|
||||
if (id < 0)
|
||||
id = 0;
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -502,14 +525,17 @@ BrlcadObject::configure_raytrace_application(const char* path, int objc, std::ve
|
||||
}
|
||||
|
||||
/* parse object arguments */
|
||||
const char** objv = (const char**)bu_calloc((size_t)objc + 1, sizeof(char*), "obj array");
|
||||
for (int i = 0; i < objc; i++) {
|
||||
objv[i] = objects.at(i).c_str();
|
||||
}
|
||||
if (objc > 0 && !objects.empty()) {
|
||||
const char** objv = (const char**)bu_calloc((size_t)objc + 1, sizeof(char*), "obj array");
|
||||
for (int i = 0; i < objc && i < (int)objects.size(); i++) {
|
||||
objv[i] = objects.at(i).c_str();
|
||||
}
|
||||
|
||||
/* include objects from database */
|
||||
if (rt_gettrees(rtip, objc, objv, (int)npsw) < 0) {
|
||||
bu_log("Loading the geometry for [%s] FAILED\n", objects[0].c_str());
|
||||
/* include objects from database */
|
||||
if (rt_gettrees(rtip, objc, objv, (int)npsw) < 0) {
|
||||
bu_log("Loading the geometry for [%s] FAILED\n", objects[0].c_str());
|
||||
}
|
||||
bu_free(objv, "obj array");
|
||||
}
|
||||
|
||||
/* Prepare database for raytracing */
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
#include "art.h"
|
||||
|
||||
/* A BRLCAD object from geometry database */
|
||||
const char* Model = "brlcad geometry";
|
||||
static const char* const Model = "brlcad geometry";
|
||||
|
||||
struct BRLCAD_to_ASR
|
||||
{
|
||||
|
||||
+33
-11
@@ -62,18 +62,40 @@ extern struct fb *fbp; /* Framebuffer handle */
|
||||
void
|
||||
ArtTileCallback::on_tile_end(const renderer::Frame* frame, const size_t tile_x, const size_t tile_y)
|
||||
{
|
||||
foundation::Tile& t = frame->image().tile(tile_x, tile_y);
|
||||
if (!frame || !fbp)
|
||||
return;
|
||||
|
||||
const foundation::Image& img = frame->image();
|
||||
const auto& props = img.properties();
|
||||
if (tile_x >= props.m_tile_count_x || tile_y >= props.m_tile_count_y)
|
||||
return;
|
||||
|
||||
const foundation::Tile& t = img.tile(tile_x, tile_y);
|
||||
const foundation::Tile rgb(t, PixelFormatUInt8);
|
||||
// fb_write(fbp, tile_x, tile_y, rgb.get_storage(), rgb.get_size());
|
||||
// printf("yay!\n");
|
||||
// printf("%lu %lu \n", tile_x, tile_y);
|
||||
// printf("%lu %lu \n", rgb.get_width(), rgb.get_height());
|
||||
for (size_t y = 0; y < rgb.get_height(); y++) {
|
||||
for (size_t x = 0; x < rgb.get_width(); x++) {
|
||||
size_t x_coord = tile_x * rgb.get_width() + x;
|
||||
size_t y_coord = tile_y * rgb.get_height() + y;
|
||||
size_t img_h = frame->image().properties().m_canvas_height;
|
||||
fb_write(fbp, (int)x_coord, (int)(img_h - y_coord), rgb.get_storage()+((y * rgb.get_width() * 4) + (x * 4)), 1);
|
||||
|
||||
size_t img_w = props.m_canvas_width;
|
||||
size_t img_h = props.m_canvas_height;
|
||||
size_t tile_w = rgb.get_width();
|
||||
size_t tile_h = rgb.get_height();
|
||||
const uint8_t *storage = reinterpret_cast<const uint8_t *>(rgb.get_storage());
|
||||
size_t storage_size = rgb.get_size();
|
||||
|
||||
if (!storage || img_h == 0)
|
||||
return;
|
||||
|
||||
for (size_t y = 0; y < tile_h; y++) {
|
||||
size_t y_coord = tile_y * tile_h + y;
|
||||
if (y_coord >= img_h)
|
||||
continue;
|
||||
int fb_y = (int)(img_h - 1 - y_coord);
|
||||
for (size_t x = 0; x < tile_w; x++) {
|
||||
size_t x_coord = tile_x * tile_w + x;
|
||||
if (x_coord >= img_w)
|
||||
continue;
|
||||
size_t pixel_offset = (y * tile_w + x) * 4;
|
||||
if (pixel_offset + 4 <= storage_size) {
|
||||
fb_write(fbp, (int)x_coord, fb_y, storage + pixel_offset, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-21
@@ -84,7 +84,7 @@ cmd_quit(void *UNUSED(clientData),
|
||||
{
|
||||
int status;
|
||||
|
||||
if (argc == 2)
|
||||
if (argc >= 2 && argv && argv[1])
|
||||
status = atoi(argv[1]);
|
||||
else
|
||||
status = 0;
|
||||
@@ -98,20 +98,21 @@ cmd_quit(void *UNUSED(clientData),
|
||||
|
||||
/***************************** BWISH/BTCLSH COMMAND HISTORY *****************************/
|
||||
|
||||
static int historyInitialized=0;
|
||||
static void
|
||||
historyInit(void)
|
||||
{
|
||||
if (currHist.capacity == 0) {
|
||||
currHist.capacity = BU_CMDHIST_LIST_INIT_CAPACITY;
|
||||
currHist.size = 0;
|
||||
currHist.current = 0;
|
||||
currHist.cmdhist = (struct bu_cmdhist *)bu_malloc(
|
||||
sizeof (struct bu_cmdhist) * currHist.capacity,
|
||||
"init chop");
|
||||
} else if (currHist.size == currHist.capacity) {
|
||||
} else if (currHist.size >= currHist.capacity) {
|
||||
currHist.capacity *= 2;
|
||||
currHist.cmdhist = (struct bu_cmdhist *)bu_realloc(
|
||||
currHist.cmdhist,
|
||||
sizeof (struct bu_cmdhist_obj) * currHist.capacity,
|
||||
sizeof (struct bu_cmdhist) * currHist.capacity,
|
||||
"init chop");
|
||||
}
|
||||
}
|
||||
@@ -128,10 +129,13 @@ history_record_priv(struct bu_vls *cmdp, struct timeval *start, struct timeval *
|
||||
{
|
||||
struct bu_cmdhist *new_hist;
|
||||
|
||||
if (!cmdp || !start || !finish)
|
||||
return;
|
||||
|
||||
if (BU_STR_EQUAL(bu_vls_addr(cmdp), "\n"))
|
||||
return;
|
||||
|
||||
if (!historyInitialized) {
|
||||
if (currHist.capacity == 0 || currHist.size >= currHist.capacity) {
|
||||
historyInit();
|
||||
}
|
||||
|
||||
@@ -143,11 +147,6 @@ history_record_priv(struct bu_vls *cmdp, struct timeval *start, struct timeval *
|
||||
new_hist->h_finish = *finish;
|
||||
new_hist->h_status = status;
|
||||
|
||||
/* As long as this isn't our first command to record after setting
|
||||
* up the journal (which would be "journal", which we don't want
|
||||
* recorded!)...
|
||||
*/
|
||||
|
||||
currHist.current = currHist.size;
|
||||
currHist.size++;
|
||||
}
|
||||
@@ -214,7 +213,10 @@ cmd_history(void *clientData, int argc, const char **argv)
|
||||
++argv;
|
||||
}
|
||||
} else {
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
Tcl_AppendResult(interp, "Invalid option ", argv[1], "\n", (char *)NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
--argc;
|
||||
@@ -222,8 +224,8 @@ cmd_history(void *clientData, int argc, const char **argv)
|
||||
}
|
||||
|
||||
for (i = 1; i < currHist.size; i++) {
|
||||
hp = &currHist.cmdhist[i];
|
||||
hp_prev = &currHist.cmdhist[i - 1];
|
||||
hp = &currHist.cmdhist[i];
|
||||
hp_prev = &currHist.cmdhist[i - 1];
|
||||
bu_vls_trunc(&str, 0);
|
||||
if (with_delays) {
|
||||
if (timediff(&tvdiff, &(hp_prev->h_finish), &(hp->h_start)) >= 0)
|
||||
@@ -240,6 +242,7 @@ cmd_history(void *clientData, int argc, const char **argv)
|
||||
else
|
||||
Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
|
||||
}
|
||||
bu_vls_free(&str);
|
||||
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
@@ -251,7 +254,7 @@ cmd_history(void *clientData, int argc, const char **argv)
|
||||
struct bu_vls *
|
||||
history_prev(void)
|
||||
{
|
||||
if (currHist.current == 0) {
|
||||
if (currHist.current == 0 || currHist.size == 0 || currHist.cmdhist == NULL) {
|
||||
return NULL;
|
||||
} else {
|
||||
currHist.current--;
|
||||
@@ -263,18 +266,18 @@ history_prev(void)
|
||||
struct bu_vls *
|
||||
history_cur(void)
|
||||
{
|
||||
if (currHist.capacity == 0) {
|
||||
if (currHist.size == 0 || currHist.cmdhist == NULL || currHist.current >= currHist.size) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &(currHist.cmdhist[currHist.current].h_command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct bu_vls *
|
||||
history_next(void)
|
||||
{
|
||||
if (currHist.capacity == 0 || currHist.current == currHist.size - 1) {
|
||||
if (currHist.size == 0 || currHist.cmdhist == NULL || currHist.current >= currHist.size - 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -288,17 +291,17 @@ cmd_hist(void *clientData, int argc, const char **argv)
|
||||
{
|
||||
Tcl_Interp *interp = (Tcl_Interp *)clientData;
|
||||
struct bu_vls *vp;
|
||||
struct bu_vls vls = BU_VLS_INIT_ZERO;
|
||||
|
||||
if (argc < 2) {
|
||||
if (argc < 2 || !argv || !argv[1]) {
|
||||
Tcl_AppendResult(interp, "hist command\n\troutine for maintaining command history", (char *)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (BU_STR_EQUAL(argv[1], "add")) {
|
||||
struct timeval zero;
|
||||
struct bu_vls vls = BU_VLS_INIT_ZERO;
|
||||
|
||||
if (argc != 3) {
|
||||
if (argc != 3 || !argv[2]) {
|
||||
Tcl_AppendResult(interp, "hist add command\n\tadd command to history", (char *)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -328,7 +331,6 @@ cmd_hist(void *clientData, int argc, const char **argv)
|
||||
return TCL_ERROR;
|
||||
|
||||
Tcl_AppendResult(interp, bu_vls_addr(vp), (char *)NULL);
|
||||
bu_vls_free(&vls);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -343,7 +345,6 @@ cmd_hist(void *clientData, int argc, const char **argv)
|
||||
return TCL_ERROR;
|
||||
|
||||
Tcl_AppendResult(interp, bu_vls_addr(vp), (char *)NULL);
|
||||
bu_vls_free(&vls);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
+101
-67
@@ -135,18 +135,24 @@ inputHandler(ClientData clientData, int UNUSED(mask))
|
||||
|
||||
count = read((int)fd, (void *)buf, BU_PAGE_SIZE);
|
||||
|
||||
if (count < 0) {
|
||||
perror("READ ERROR");
|
||||
}
|
||||
if (count <= 0 && feof(stdin)) {
|
||||
Cad_Exit(TCL_OK);
|
||||
if (count <= 0) {
|
||||
if (count < 0) {
|
||||
perror("READ ERROR");
|
||||
}
|
||||
if (feof(stdin) || count == 0) {
|
||||
Cad_Exit(TCL_OK);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Process everything in buf */
|
||||
for (i = 0, ch = buf[i]; i < count && ch != '\0'; ch = buf[++i]) {
|
||||
if (ch < 0 || ch > CHAR_MAX)
|
||||
/* Process everything in buf safely */
|
||||
for (i = 0; i < count; i++) {
|
||||
ch = (unsigned char)buf[i];
|
||||
if (ch == '\0')
|
||||
break;
|
||||
if (ch > CHAR_MAX)
|
||||
continue;
|
||||
processChar(ch);
|
||||
processChar((char)ch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +162,6 @@ static void
|
||||
processChar(char ch)
|
||||
{
|
||||
struct bu_vls *vp = NULL;
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
static int escaped = 0;
|
||||
static int bracketed = 0;
|
||||
static int freshline = 1;
|
||||
@@ -229,6 +234,7 @@ processChar(char ch)
|
||||
bu_log("\b \b");
|
||||
bu_vls_trunc(&input_str, bu_vls_strlen(&input_str)-1);
|
||||
} else {
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
bu_vls_strcpy(&temp, bu_vls_addr(&input_str)+input_str_index);
|
||||
bu_vls_trunc(&input_str, input_str_index-1);
|
||||
bu_log("\b%s ", bu_vls_addr(&temp));
|
||||
@@ -253,37 +259,46 @@ processChar(char ch)
|
||||
escaped = bracketed = 0;
|
||||
break;
|
||||
case CTRL_D: /* Delete character at cursor */
|
||||
if (input_str_index == bu_vls_strlen(&input_str)) {
|
||||
if (input_str_index >= bu_vls_strlen(&input_str)) {
|
||||
insert_beep(); /* Beep if at end of input string */
|
||||
break;
|
||||
}
|
||||
bu_vls_strcpy(&temp, bu_vls_addr(&input_str)+input_str_index+1);
|
||||
bu_vls_trunc(&input_str, input_str_index);
|
||||
bu_log("%s ", bu_vls_addr(&temp));
|
||||
insert_prompt();
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
bu_vls_vlscat(&input_str, &temp);
|
||||
bu_vls_free(&temp);
|
||||
{
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
bu_vls_strcpy(&temp, bu_vls_addr(&input_str)+input_str_index+1);
|
||||
bu_vls_trunc(&input_str, input_str_index);
|
||||
bu_log("%s ", bu_vls_addr(&temp));
|
||||
insert_prompt();
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
bu_vls_vlscat(&input_str, &temp);
|
||||
bu_vls_free(&temp);
|
||||
}
|
||||
escaped = bracketed = 0;
|
||||
break;
|
||||
case CTRL_U: /* Delete whole line */
|
||||
insert_prompt();
|
||||
bu_vls_strncpy(&temp, SPACES, bu_vls_strlen(&input_str));
|
||||
bu_log("%s", bu_vls_addr(&temp));
|
||||
bu_vls_free(&temp);
|
||||
insert_prompt();
|
||||
bu_vls_trunc(&input_str, 0);
|
||||
input_str_index = 0;
|
||||
escaped = bracketed = 0;
|
||||
{
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
insert_prompt();
|
||||
bu_vls_strncpy(&temp, SPACES, bu_vls_strlen(&input_str));
|
||||
bu_log("%s", bu_vls_addr(&temp));
|
||||
bu_vls_free(&temp);
|
||||
insert_prompt();
|
||||
bu_vls_trunc(&input_str, 0);
|
||||
input_str_index = 0;
|
||||
escaped = bracketed = 0;
|
||||
}
|
||||
break;
|
||||
case CTRL_K: /* Delete to end of line */
|
||||
bu_vls_strncpy(&temp, SPACES, bu_vls_strlen(&input_str)-input_str_index);
|
||||
bu_log("%s", bu_vls_addr(&temp));
|
||||
bu_vls_free(&temp);
|
||||
bu_vls_trunc(&input_str, input_str_index);
|
||||
insert_prompt();
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
escaped = bracketed = 0;
|
||||
{
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
bu_vls_strncpy(&temp, SPACES, bu_vls_strlen(&input_str)-input_str_index);
|
||||
bu_log("%s", bu_vls_addr(&temp));
|
||||
bu_vls_free(&temp);
|
||||
bu_vls_trunc(&input_str, input_str_index);
|
||||
insert_prompt();
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
escaped = bracketed = 0;
|
||||
}
|
||||
break;
|
||||
case CTRL_L: /* Redraw line */
|
||||
bu_log("\n");
|
||||
@@ -315,7 +330,7 @@ processChar(char ch)
|
||||
escaped = bracketed = 0;
|
||||
break;
|
||||
case CTRL_T: /* Transpose characters */
|
||||
if (input_str_index == 0) {
|
||||
if (input_str_index == 0 || bu_vls_strlen(&input_str) < 2) {
|
||||
insert_beep();
|
||||
break;
|
||||
}
|
||||
@@ -364,24 +379,33 @@ processChar(char ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
insert_prompt();
|
||||
bu_vls_strncpy(&temp, SPACES, bu_vls_strlen(&input_str));
|
||||
bu_log("%s", bu_vls_addr(&temp));
|
||||
bu_vls_free(&temp);
|
||||
insert_prompt();
|
||||
bu_vls_trunc(&input_str, 0);
|
||||
bu_vls_vlscat(&input_str, vp);
|
||||
if (bu_vls_addr(&input_str)[bu_vls_strlen(&input_str)-1] == '\n')
|
||||
bu_vls_trunc(&input_str, bu_vls_strlen(&input_str)-1); /* del \n */
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
input_str_index = bu_vls_strlen(&input_str);
|
||||
escaped = bracketed = 0;
|
||||
{
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
insert_prompt();
|
||||
bu_vls_strncpy(&temp, SPACES, bu_vls_strlen(&input_str));
|
||||
bu_log("%s", bu_vls_addr(&temp));
|
||||
bu_vls_free(&temp);
|
||||
insert_prompt();
|
||||
bu_vls_trunc(&input_str, 0);
|
||||
bu_vls_vlscat(&input_str, vp);
|
||||
if (bu_vls_strlen(&input_str) > 0 && bu_vls_addr(&input_str)[bu_vls_strlen(&input_str)-1] == '\n')
|
||||
bu_vls_trunc(&input_str, bu_vls_strlen(&input_str)-1); /* del \n */
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
input_str_index = bu_vls_strlen(&input_str);
|
||||
escaped = bracketed = 0;
|
||||
}
|
||||
break;
|
||||
case CTRL_W: /* backward-delete-word */
|
||||
if (input_str_index == 0) {
|
||||
insert_beep();
|
||||
escaped = bracketed = 0;
|
||||
break;
|
||||
}
|
||||
{
|
||||
char *start;
|
||||
char *curr;
|
||||
int len;
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
struct bu_vls temp2 = BU_VLS_INIT_ZERO;
|
||||
|
||||
start = bu_vls_addr(&input_str);
|
||||
@@ -395,7 +419,7 @@ processChar(char ch)
|
||||
while (curr > start && *curr != ' ')
|
||||
--curr;
|
||||
|
||||
bu_vls_strcat(&temp, start+input_str_index);
|
||||
bu_vls_strcpy(&temp, start+input_str_index);
|
||||
|
||||
if (curr == start)
|
||||
input_str_index = 0;
|
||||
@@ -425,6 +449,7 @@ processChar(char ch)
|
||||
char *start;
|
||||
char *curr;
|
||||
int i;
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
struct bu_vls temp2 = BU_VLS_INIT_ZERO;
|
||||
|
||||
start = bu_vls_addr(&input_str);
|
||||
@@ -462,6 +487,7 @@ processChar(char ch)
|
||||
/* forward-word */
|
||||
char *start;
|
||||
char *curr;
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
|
||||
start = bu_vls_addr(&input_str);
|
||||
curr = start + input_str_index;
|
||||
@@ -489,31 +515,39 @@ processChar(char ch)
|
||||
case 'b':
|
||||
if (escaped) {
|
||||
/* backward-word */
|
||||
char *start;
|
||||
char *curr;
|
||||
if (input_str_index == 0) {
|
||||
insert_beep();
|
||||
escaped = bracketed = 0;
|
||||
break;
|
||||
}
|
||||
{
|
||||
char *start;
|
||||
char *curr;
|
||||
struct bu_vls temp = BU_VLS_INIT_ZERO;
|
||||
|
||||
start = bu_vls_addr(&input_str);
|
||||
curr = start + input_str_index - 1;
|
||||
start = bu_vls_addr(&input_str);
|
||||
curr = start + input_str_index - 1;
|
||||
|
||||
/* skip spaces */
|
||||
while (curr > start && *curr == ' ')
|
||||
--curr;
|
||||
/* skip spaces */
|
||||
while (curr > start && *curr == ' ')
|
||||
--curr;
|
||||
|
||||
/* find next space */
|
||||
while (curr > start && *curr != ' ')
|
||||
--curr;
|
||||
/* find next space */
|
||||
while (curr > start && *curr != ' ')
|
||||
--curr;
|
||||
|
||||
if (curr == start)
|
||||
input_str_index = 0;
|
||||
else
|
||||
input_str_index = curr - start + 1;
|
||||
if (curr == start)
|
||||
input_str_index = 0;
|
||||
else
|
||||
input_str_index = curr - start + 1;
|
||||
|
||||
bu_vls_strcpy(&temp, start+input_str_index);
|
||||
bu_vls_trunc(&input_str, input_str_index);
|
||||
insert_prompt();
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
bu_vls_vlscat(&input_str, &temp);
|
||||
bu_vls_free(&temp);
|
||||
bu_vls_strcpy(&temp, start+input_str_index);
|
||||
bu_vls_trunc(&input_str, input_str_index);
|
||||
insert_prompt();
|
||||
bu_log("%s", bu_vls_addr(&input_str));
|
||||
bu_vls_vlscat(&input_str, &temp);
|
||||
bu_vls_free(&temp);
|
||||
}
|
||||
} else
|
||||
insert_char(ch);
|
||||
|
||||
|
||||
+17
-5
@@ -75,6 +75,8 @@ static BOOL consoleRequired = TRUE;
|
||||
int tty_usable(int fd) {
|
||||
fd_set fdset;
|
||||
struct timeval timeout;
|
||||
if (fd < 0 || fd >= FD_SETSIZE)
|
||||
return 0;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(fd, &fdset);
|
||||
timeout.tv_sec = 0;
|
||||
@@ -228,6 +230,9 @@ main(int argc, char **argv)
|
||||
argv = __argv;
|
||||
#endif
|
||||
#if !defined(HAVE_WINDOWS_H)
|
||||
if (argc <= 0 || !argv || !argv[0]) {
|
||||
return 1;
|
||||
}
|
||||
struct bu_vls tlog = BU_VLS_INIT_ZERO;
|
||||
int status = TCL_OK;
|
||||
char *filename = NULL;
|
||||
@@ -238,6 +243,10 @@ main(int argc, char **argv)
|
||||
|
||||
/* Create the interpreter */
|
||||
INTERP = Tcl_CreateInterp();
|
||||
if (!INTERP) {
|
||||
bu_log("Failed to create Tcl interpreter\n");
|
||||
return 1;
|
||||
}
|
||||
Tcl_FindExecutable(argv[0]);
|
||||
#endif
|
||||
#if defined(HAVE_WINDOWS_H)
|
||||
@@ -251,7 +260,9 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bu_setprogname(argv[0]);
|
||||
if (argc > 0 && argv && argv[0]) {
|
||||
bu_setprogname(argv[0]);
|
||||
}
|
||||
#if defined(HAVE_WINDOWS_H)
|
||||
# ifdef BWISH
|
||||
Tk_Main(argc, argv, Tcl_WinInit);
|
||||
@@ -281,7 +292,7 @@ main(int argc, char **argv)
|
||||
filename = Tcl_ExternalToUtfDString(NULL, filename, -1, &argString);
|
||||
}
|
||||
|
||||
sprintf(buf, "%ld", (long)(argc-1));
|
||||
snprintf(buf, sizeof(buf), "%ld", (long)(argc-1));
|
||||
Tcl_SetVar(INTERP, "argc", buf, TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar(INTERP, "argv0", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY);
|
||||
|
||||
@@ -321,12 +332,13 @@ main(int argc, char **argv)
|
||||
Tcl_ResetResult(INTERP);
|
||||
fstatus = Tcl_EvalFile(INTERP, filename);
|
||||
if (fstatus != TCL_OK) {
|
||||
const char *errInfo;
|
||||
Tcl_AddErrorInfo(INTERP, "");
|
||||
errInfo = Tcl_GetVar(INTERP, "errorInfo", TCL_GLOBAL_ONLY);
|
||||
#ifdef BWISH
|
||||
displayWarning(Tcl_GetVar(INTERP, "errorInfo",
|
||||
TCL_GLOBAL_ONLY), "Error in startup script");
|
||||
displayWarning(errInfo ? errInfo : "Unknown error in startup script", "Error in startup script");
|
||||
#else
|
||||
bu_log("Error in startup script: %s\n", Tcl_GetVar(INTERP, "errorInfo", TCL_GLOBAL_ONLY));
|
||||
bu_log("Error in startup script: %s\n", errInfo ? errInfo : "unknown error");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -752,7 +752,7 @@ tessellate_part(struct creo_conv_info *cinfo, ProMdl model, struct bu_vls **snam
|
||||
}
|
||||
|
||||
/* Check solidity */
|
||||
success = bg_trimesh_solid((int)vert_tree->curr_vert, (size_t)faces.size() / 3,
|
||||
success = !bg_trimesh_solid((int)vert_tree->curr_vert, (size_t)faces.size() / 3,
|
||||
vert_tree->the_array, &faces[0], NULL);
|
||||
|
||||
/* If it's not solid and we're testing solidity, keep trying... */
|
||||
|
||||
+140
-3
@@ -232,12 +232,17 @@ fb_server_fb_open(struct pkg_conn *pcp, char *buf)
|
||||
}
|
||||
}
|
||||
|
||||
if (pcp->pkc_len < 2*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
width = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
height = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
|
||||
if (fb_server_fbp == FB_NULL) {
|
||||
/* Attempt to open new framebuffer */
|
||||
if (strlen(&buf[8]) == 0)
|
||||
if (pcp->pkc_len <= 8 || buf[8] == '\0')
|
||||
fb_server_fbp = fb_open(NULL, width, height);
|
||||
else
|
||||
fb_server_fbp = fb_open(&buf[8], width, height);
|
||||
@@ -363,6 +368,11 @@ fb_server_fb_clear(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < sizeof(RGBpixel)) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
bg[RED] = buf[0];
|
||||
bg[GRN] = buf[1];
|
||||
bg[BLU] = buf[2];
|
||||
@@ -390,6 +400,11 @@ fb_server_fb_read(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 3*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
x = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
num = (size_t)(long)pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
@@ -442,9 +457,25 @@ fb_server_fb_write(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 3*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
x = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
num = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
if (num < 0 || (size_t)num > (SIZE_MAX - 3*NET_LONG_LEN) / sizeof(RGBpixel) ||
|
||||
pcp->pkc_len < 3*NET_LONG_LEN + (size_t)num * sizeof(RGBpixel)) {
|
||||
fb_log("fb_write: packet length %zu too small for %d pixels\n", pcp->pkc_len, num);
|
||||
if (pcp->pkc_type < MSG_NORETURN) {
|
||||
(void)pkg_plong(&rbuf[0*NET_LONG_LEN], -1);
|
||||
pkg_send(MSG_RETURN, rbuf, NET_LONG_LEN, pcp);
|
||||
}
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
type = pcp->pkc_type;
|
||||
ret = fb_write(fb_server_fbp, x, y, (unsigned char *)&buf[3*NET_LONG_LEN], num);
|
||||
|
||||
@@ -473,11 +504,22 @@ fb_server_fb_readrect(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 4*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
xmin = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
ymin = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
width = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
height = pkg_glong(&buf[3*NET_LONG_LEN]);
|
||||
num = width * height;
|
||||
|
||||
if (width <= 0 || height <= 0 || (size_t)width > 8192 || (size_t)height > 8192) {
|
||||
fb_log("fb_readrect: invalid dimensions %dx%d\n", width, height);
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
num = (size_t)width * (size_t)height;
|
||||
|
||||
if (num*sizeof(RGBpixel) > buflen) {
|
||||
if (scanbuf != NULL)
|
||||
@@ -522,11 +564,28 @@ fb_server_fb_writerect(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 4*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
x = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
width = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
height = pkg_glong(&buf[3*NET_LONG_LEN]);
|
||||
|
||||
if (width <= 0 || height <= 0 || (size_t)width > 8192 || (size_t)height > 8192 ||
|
||||
pcp->pkc_len < 4*NET_LONG_LEN + (size_t)width * (size_t)height * sizeof(RGBpixel)) {
|
||||
fb_log("fb_writerect: invalid dimensions %dx%d or packet length %zu too small\n",
|
||||
width, height, pcp->pkc_len);
|
||||
if (pcp->pkc_type < MSG_NORETURN) {
|
||||
(void)pkg_plong(&rbuf[0*NET_LONG_LEN], -1);
|
||||
pkg_send(MSG_RETURN, rbuf, NET_LONG_LEN, pcp);
|
||||
}
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
type = pcp->pkc_type;
|
||||
ret = fb_writerect(fb_server_fbp, x, y, width, height,
|
||||
(unsigned char *)&buf[4*NET_LONG_LEN]);
|
||||
@@ -556,11 +615,22 @@ fb_server_fb_bwreadrect(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 4*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
xmin = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
ymin = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
width = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
height = pkg_glong(&buf[3*NET_LONG_LEN]);
|
||||
num = width * height;
|
||||
|
||||
if (width <= 0 || height <= 0 || (size_t)width > 8192 || (size_t)height > 8192) {
|
||||
fb_log("fb_bwreadrect: invalid dimensions %dx%d\n", width, height);
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
num = (size_t)width * (size_t)height;
|
||||
|
||||
if (num > buflen) {
|
||||
if (scanbuf != NULL)
|
||||
@@ -605,11 +675,28 @@ fb_server_fb_bwwriterect(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 4*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
x = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
width = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
height = pkg_glong(&buf[3*NET_LONG_LEN]);
|
||||
|
||||
if (width <= 0 || height <= 0 || (size_t)width > 8192 || (size_t)height > 8192 ||
|
||||
pcp->pkc_len < 4*NET_LONG_LEN + (size_t)width * (size_t)height) {
|
||||
fb_log("fb_bwwriterect: invalid dimensions %dx%d or packet length %zu too small\n",
|
||||
width, height, pcp->pkc_len);
|
||||
if (pcp->pkc_type < MSG_NORETURN) {
|
||||
(void)pkg_plong(&rbuf[0*NET_LONG_LEN], -1);
|
||||
pkg_send(MSG_RETURN, rbuf, NET_LONG_LEN, pcp);
|
||||
}
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
type = pcp->pkc_type;
|
||||
ret = fb_bwwriterect(fb_server_fbp, x, y, width, height,
|
||||
(unsigned char *)&buf[4*NET_LONG_LEN]);
|
||||
@@ -639,6 +726,11 @@ fb_server_fb_cursor(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 3*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
mode = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
x = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
@@ -684,11 +776,26 @@ fb_server_fb_setcursor(struct pkg_conn *pcp, char *buf)
|
||||
if (pcp == PKC_NULL) return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 4*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
xbits = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
ybits = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
xorig = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
yorig = pkg_glong(&buf[3*NET_LONG_LEN]);
|
||||
|
||||
if (xbits < 0 || ybits < 0 || xbits > 1024 || ybits > 1024 ||
|
||||
pcp->pkc_len < 4*NET_LONG_LEN + (((size_t)xbits * (size_t)ybits + 7) >> 3)) {
|
||||
if (pcp->pkc_type < MSG_NORETURN) {
|
||||
(void)pkg_plong(&rbuf[0*NET_LONG_LEN], -1);
|
||||
pkg_send(MSG_RETURN, rbuf, NET_LONG_LEN, pcp);
|
||||
}
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = fb_setcursor(fb_server_fbp, (unsigned char *)&buf[4*NET_LONG_LEN],
|
||||
xbits, ybits, xorig, yorig);
|
||||
|
||||
@@ -716,6 +823,11 @@ fb_server_fb_scursor(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 3*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
mode = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
x = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
@@ -742,6 +854,11 @@ fb_server_fb_window(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 2*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
x = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
|
||||
@@ -767,6 +884,11 @@ fb_server_fb_zoom(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 2*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
x = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
y = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
|
||||
@@ -790,6 +912,11 @@ fb_server_fb_view(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < 4*NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
xcenter = pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
ycenter = pkg_glong(&buf[1*NET_LONG_LEN]);
|
||||
xzoom = pkg_glong(&buf[2*NET_LONG_LEN]);
|
||||
@@ -869,6 +996,11 @@ fb_server_fb_wmap(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len != 0 && pcp->pkc_len < 3*256*2) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pcp->pkc_len == 0)
|
||||
ret = fb_wmap(fb_server_fbp, COLORMAP_NULL);
|
||||
else {
|
||||
@@ -935,6 +1067,11 @@ fb_server_fb_help(struct pkg_conn *pcp, char *buf)
|
||||
return;
|
||||
if (fbserv_guard(pcp, buf) < 0) return;
|
||||
|
||||
if (pcp->pkc_len < NET_LONG_LEN) {
|
||||
if (buf) (void)free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)pkg_glong(&buf[0*NET_LONG_LEN]);
|
||||
|
||||
ret = fb_help(fb_server_fbp);
|
||||
|
||||
@@ -23,10 +23,20 @@
|
||||
#include "InformationGatherer.h"
|
||||
#include "bu/log.h"
|
||||
|
||||
// flush results, if we have any, then exit
|
||||
static void reportAndExit(const std::string &message, const std::string &result = "")
|
||||
{
|
||||
if (!result.empty())
|
||||
bu_log("%s%s", result.c_str(), result.back() == '\n' ? "" : "\n");
|
||||
|
||||
bu_exit(BRLCAD_ERROR, "%s", message.c_str());
|
||||
}
|
||||
|
||||
|
||||
std::string getCmdPath(std::string exeDir, const char* cmd) {
|
||||
char buf[MAXPATHLEN] = {0};
|
||||
if (!bu_dir(buf, MAXPATHLEN, exeDir.c_str(), cmd, BU_DIR_EXT, NULL))
|
||||
bu_exit(BRLCAD_ERROR, "Couldn't find %s, aborting.\n", cmd);
|
||||
reportAndExit("Couldn't find " + std::string(cmd) + ", aborting.\n");
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
@@ -58,13 +68,13 @@ getSurfaceArea(Options* opt, std::map<std::string, std::string> UNUSED(map), std
|
||||
bu_process_create(&p, rtarea_av, BU_PROCESS_HIDE_WINDOW | BU_PROCESS_OUT_EQ_ERR);
|
||||
|
||||
if (bu_process_pid(p) <= 0) {
|
||||
bu_exit(BRLCAD_ERROR, "Problem with getSurfaceArea, aborting\n");
|
||||
reportAndExit("Problem with getSurfaceArea, aborting\n");
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
std::string result = "";
|
||||
std::string result;
|
||||
int read_cnt = 0;
|
||||
while ((read_cnt = bu_process_read_n(p, BU_PROCESS_STDOUT, 128-1, buffer)) > 0) {
|
||||
while ((read_cnt = bu_process_read_n(p, BU_PROCESS_STDOUT, sizeof(buffer) - 1, buffer)) > 0) {
|
||||
/* NOTE: read does not ensure null-termination, thus buffersize-1 */
|
||||
buffer[read_cnt] = '\0';
|
||||
result += buffer;
|
||||
@@ -80,7 +90,7 @@ getSurfaceArea(Options* opt, std::map<std::string, std::string> UNUSED(map), std
|
||||
try {
|
||||
surfArea += stod(result);
|
||||
} catch (const std::invalid_argument& ia) {
|
||||
bu_exit(BRLCAD_ERROR, "Invalid argument for getSurfaceArea. Got (%s), aborting.\n", ia.what());
|
||||
reportAndExit("Invalid argument for getSurfaceArea. Got (" + std::string(ia.what()) + "), aborting.\n", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,7 +210,7 @@ getVerificationData(struct ged* UNUSED(g), Options* opt, std::map<std::string, s
|
||||
struct bu_process* p;
|
||||
int read_cnt = 0;
|
||||
char buffer[1024] = {0};
|
||||
std::string result = "";
|
||||
std::string result;
|
||||
std::string ncpu(std::to_string(opt->getNCPU()));
|
||||
std::string dFile(opt->getDensityFile());
|
||||
|
||||
@@ -233,21 +243,23 @@ getVerificationData(struct ged* UNUSED(g), Options* opt, std::map<std::string, s
|
||||
bu_process_create(&p, const_cast<const char**>(gqa_av_vec.data()), BU_PROCESS_HIDE_WINDOW | BU_PROCESS_OUT_EQ_ERR);
|
||||
|
||||
if (bu_process_pid(p) <= 0) {
|
||||
bu_exit(BRLCAD_ERROR, "Problem in getVerificationData gqa process creation, aborting\n");
|
||||
reportAndExit("Problem in getVerificationData gqa process creation, aborting\n");
|
||||
}
|
||||
|
||||
result = "";
|
||||
while ((read_cnt = bu_process_read_n(p, BU_PROCESS_STDOUT, 1024-1, buffer)) > 0) {
|
||||
while ((read_cnt = bu_process_read_n(p, BU_PROCESS_STDOUT, sizeof(buffer) - 1, buffer)) > 0) {
|
||||
buffer[read_cnt] = '\0';
|
||||
result += buffer;
|
||||
}
|
||||
|
||||
if (bu_process_wait_n(&p, 0) != 0) {
|
||||
bu_exit(BRLCAD_ERROR, "Problem collecting gqa volume and mass, aborting\n");
|
||||
const int gqa_status = bu_process_wait_n(&p, 0);
|
||||
|
||||
// sanity - we should have clean status code and not the "no density found" message
|
||||
const bool no_density_data = result.find(no_density_msg) != std::string::npos;
|
||||
if (gqa_status != 0 && (!no_density_data || !dFile.empty())) {
|
||||
reportAndExit("Problem collecting gqa volume and mass, aborting\n", result);
|
||||
}
|
||||
|
||||
// make sure we did not get 'no density file' error message
|
||||
if (result.find(no_density_msg) == std::string::npos) {
|
||||
if (!no_density_data) {
|
||||
// NOTE: tmp_val is zeroed at each parseLabeledNumber call
|
||||
if (parseLabeledNumber(tmp_val, result, volume_label))
|
||||
volume += tmp_val;
|
||||
@@ -263,17 +275,17 @@ getVerificationData(struct ged* UNUSED(g), Options* opt, std::map<std::string, s
|
||||
bu_process_create(&p, const_cast<const char**>(gqa_av_vec.data()), BU_PROCESS_HIDE_WINDOW | BU_PROCESS_OUT_EQ_ERR);
|
||||
|
||||
if (bu_process_pid(p) <= 0) {
|
||||
bu_exit(BRLCAD_ERROR, "Problem in getVerificationData gqa process creation, aborting\n");
|
||||
reportAndExit("Problem in getVerificationData gqa process creation, aborting\n");
|
||||
}
|
||||
|
||||
result = "";
|
||||
while ((read_cnt = bu_process_read_n(p, BU_PROCESS_STDOUT, 1024-1, buffer)) > 0) {
|
||||
result.clear();
|
||||
while ((read_cnt = bu_process_read_n(p, BU_PROCESS_STDOUT, sizeof(buffer) - 1, buffer)) > 0) {
|
||||
buffer[read_cnt] = '\0';
|
||||
result += buffer;
|
||||
}
|
||||
|
||||
if (bu_process_wait_n(&p, 0) != 0) {
|
||||
bu_exit(BRLCAD_ERROR, "Problem collecting gqa volume, aborting\n");
|
||||
reportAndExit("Problem collecting gqa volume, aborting\n", result);
|
||||
}
|
||||
|
||||
if (parseLabeledNumber(tmp_val, result, volume_label))
|
||||
@@ -381,7 +393,7 @@ InformationGatherer::getMainComp()
|
||||
ged_exec_exists(g, 2, cmd);
|
||||
std::string res = bu_vls_addr(g->ged_result_str);
|
||||
if (res != "1") {
|
||||
bu_exit(BRLCAD_ERROR, "Could not find component (%s), aborting.\n", topname);
|
||||
reportAndExit("Could not find component (" + topcomp + "), aborting.\n");
|
||||
}
|
||||
|
||||
int entities = getNumEntities(opt->getTopComp());
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
|
||||
// OpenCV header files
|
||||
#include <opencv2/opencv.hpp>
|
||||
#if CV_VERSION_MAJOR >= 5
|
||||
#include <opencv2/geometry.hpp>
|
||||
#endif
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
|
||||
|
||||
+3
-2
@@ -43,6 +43,7 @@ main(int argc, char *argv[])
|
||||
int i, j;
|
||||
int db_index;
|
||||
int c;
|
||||
int ret;
|
||||
const char **av;
|
||||
struct ged *gedp;
|
||||
|
||||
@@ -103,14 +104,14 @@ main(int argc, char *argv[])
|
||||
bu_exit(1, usage, argv[0]);
|
||||
}
|
||||
|
||||
(void)ged_exec_gqa(gedp, j, av);
|
||||
ret = ged_exec_gqa(gedp, j, av);
|
||||
if (bu_vls_strlen(gedp->ged_result_str) > 0)
|
||||
bu_log("%s", bu_vls_addr(gedp->ged_result_str));
|
||||
ged_close(gedp);
|
||||
|
||||
bu_free((void *)av, "av");
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+147
-40
@@ -42,6 +42,7 @@ struct isst_nmg_data {
|
||||
struct db_i *dbip;
|
||||
struct bn_tol *tol;
|
||||
struct bu_list *vlfree;
|
||||
struct adrt_mesh_s **meshes;
|
||||
};
|
||||
|
||||
struct gcv_data {
|
||||
@@ -51,8 +52,6 @@ struct gcv_data {
|
||||
|
||||
static void nmg_to_adrt_gcvwrite(struct nmgregion *r, const struct db_full_path *pathp, struct db_tree_state *tsp, void *client_data);
|
||||
|
||||
static struct gcv_data gcvwriter = {{nmg_to_adrt_gcvwrite, NULL, NULL}, NULL};
|
||||
|
||||
/* load the region into the tie image */
|
||||
static void
|
||||
nmg_to_adrt_internal(TIE_3 **tribuf, struct tie_s *cur_tie, struct adrt_mesh_s *mesh, struct nmgregion *r)
|
||||
@@ -60,9 +59,14 @@ nmg_to_adrt_internal(TIE_3 **tribuf, struct tie_s *cur_tie, struct adrt_mesh_s *
|
||||
struct model *m;
|
||||
struct shell *s;
|
||||
|
||||
if (!tribuf || !tribuf[0] || !tribuf[1] || !tribuf[2] || !cur_tie || !mesh || !r)
|
||||
return;
|
||||
|
||||
NMG_CK_REGION(r);
|
||||
|
||||
m = r->m_p;
|
||||
if (!m)
|
||||
return;
|
||||
NMG_CK_MODEL(m);
|
||||
|
||||
/* Check triangles */
|
||||
@@ -84,7 +88,7 @@ nmg_to_adrt_internal(TIE_3 **tribuf, struct tie_s *cur_tie, struct adrt_mesh_s *
|
||||
for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd))
|
||||
{
|
||||
struct edgeuse *eu;
|
||||
int vert_count=0;
|
||||
int vert_count = 0;
|
||||
|
||||
NMG_CK_LOOPUSE(lu);
|
||||
|
||||
@@ -97,21 +101,26 @@ nmg_to_adrt_internal(TIE_3 **tribuf, struct tie_s *cur_tie, struct adrt_mesh_s *
|
||||
struct vertex *v;
|
||||
|
||||
NMG_CK_EDGEUSE(eu);
|
||||
if (!eu->vu_p || !eu->vu_p->v_p)
|
||||
continue;
|
||||
|
||||
v = eu->vu_p->v_p;
|
||||
NMG_CK_VERTEX(v);
|
||||
if (!v->vg_p)
|
||||
continue;
|
||||
|
||||
/* convert mm to m */
|
||||
VSCALE((*tribuf[vert_count]).v, v->vg_p->coord, 1.0/1000.0);
|
||||
if (vert_count < 3) {
|
||||
VSCALE((*tribuf[vert_count]).v, v->vg_p->coord, 1.0/1000.0);
|
||||
}
|
||||
vert_count++;
|
||||
}
|
||||
if (vert_count > 3)
|
||||
if (vert_count != 3)
|
||||
{
|
||||
bu_log("lu %p has %d vertices!\n", (void *)lu, vert_count);
|
||||
bu_exit(1, "ERROR: LU is not a triangle");
|
||||
}
|
||||
else if (vert_count < 3)
|
||||
if (vert_count > 3)
|
||||
bu_log("lu %p has %d vertices (not a triangle)\n", (void *)lu, vert_count);
|
||||
continue;
|
||||
}
|
||||
|
||||
TIE_VAL(tie_push)(cur_tie, tribuf, 1, mesh, 0);
|
||||
}
|
||||
@@ -129,12 +138,20 @@ nmg_to_adrt_regstart(struct db_tree_state *ts, const struct db_full_path *path,
|
||||
* if it's a simple single bot region, just eat the bots and return -1.
|
||||
* Omnomnom. Return 0 to do nmg eval.
|
||||
*/
|
||||
struct gcv_region_end_data *rd = (struct gcv_region_end_data *)client_data;
|
||||
struct isst_nmg_data *d = (struct isst_nmg_data *)rd->client_data;
|
||||
struct gcv_data *gd = (struct gcv_data *)client_data;
|
||||
if (!gd || !gd->region_end_data.client_data || !gd->meshes || !*gd->meshes)
|
||||
return 0;
|
||||
|
||||
struct isst_nmg_data *d = (struct isst_nmg_data *)gd->region_end_data.client_data;
|
||||
struct directory *dir;
|
||||
struct rt_db_internal intern;
|
||||
struct adrt_mesh_s *mesh;
|
||||
unsigned char rgb[3] = { 0xc0, 0xc0, 0xc0 };
|
||||
char *path_str;
|
||||
int ret = 0;
|
||||
|
||||
if (!ts || !path || !rci || !d->dbip || !d->cur_tie || !d->tribuf)
|
||||
return 0;
|
||||
|
||||
RT_CHECK_COMB(rci);
|
||||
|
||||
@@ -142,26 +159,27 @@ nmg_to_adrt_regstart(struct db_tree_state *ts, const struct db_full_path *path,
|
||||
if (rci->tree == NULL)
|
||||
return 0;
|
||||
RT_CK_TREE(rci->tree);
|
||||
if ( rci->tree->tr_op != OP_DB_LEAF )
|
||||
if (rci->tree->tr_op != OP_DB_LEAF)
|
||||
return 0;
|
||||
if ((dir = db_lookup(d->dbip, rci->tree->tr_l.tl_name, 1)) == NULL) {
|
||||
printf("Lookup failed: %s\n", rci->tree->tr_l.tl_name);
|
||||
bu_log("Lookup failed: %s\n", rci->tree->tr_l.tl_name);
|
||||
return 0;
|
||||
}
|
||||
if (dir->d_minor_type != ID_BOT && dir->d_minor_type != ID_NMG)
|
||||
return 0;
|
||||
if (rt_db_get_internal(&intern, dir, d->dbip, (fastf_t *)NULL) < 0) {
|
||||
printf("Failed to load\n");
|
||||
bu_log("Failed to load: %s\n", rci->tree->tr_l.tl_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dir->d_minor_type == ID_NMG)
|
||||
if (dir->d_minor_type == ID_NMG) {
|
||||
rt_db_free_internal(&intern);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: where is this released? */
|
||||
BU_ALLOC(mesh, struct adrt_mesh_s);
|
||||
|
||||
BU_LIST_PUSH(&((*gcvwriter.meshes)->l), &(mesh->l));
|
||||
BU_LIST_PUSH(&((*gd->meshes)->l), &(mesh->l));
|
||||
|
||||
mesh->texture = NULL;
|
||||
mesh->flags = 0;
|
||||
@@ -172,54 +190,76 @@ nmg_to_adrt_regstart(struct db_tree_state *ts, const struct db_full_path *path,
|
||||
rt_comb_get_color(d->dbip, rgb, rci);
|
||||
VSCALE(mesh->attributes->color.v, rgb, 1.0/256.0);
|
||||
|
||||
bu_strlcpy(mesh->name, db_path_to_string(path), sizeof(mesh->name));
|
||||
path_str = db_path_to_string(path);
|
||||
if (path_str) {
|
||||
bu_strlcpy(mesh->name, path_str, sizeof(mesh->name));
|
||||
bu_free(path_str, "db_path_to_string");
|
||||
} else {
|
||||
mesh->name[0] = '\0';
|
||||
}
|
||||
|
||||
if (intern.idb_minor_type == ID_NMG) {
|
||||
nmg_to_adrt_internal(d->tribuf, d->cur_tie, mesh, (struct nmgregion *)intern.idb_ptr);
|
||||
return -1;
|
||||
ret = -1;
|
||||
} else if (intern.idb_minor_type == ID_BOT) {
|
||||
size_t i;
|
||||
struct rt_bot_internal *bot = (struct rt_bot_internal *)intern.idb_ptr;
|
||||
|
||||
RT_BOT_CK_MAGIC(bot);
|
||||
|
||||
for (i=0;i<bot->num_faces;i++)
|
||||
{
|
||||
VSCALE((*d->tribuf[0]).v, (bot->vertices+3*bot->faces[3*i+0]), 1.0/1000.0);
|
||||
VSCALE((*d->tribuf[1]).v, (bot->vertices+3*bot->faces[3*i+1]), 1.0/1000.0);
|
||||
VSCALE((*d->tribuf[2]).v, (bot->vertices+3*bot->faces[3*i+2]), 1.0/1000.0);
|
||||
if (bot->vertices && bot->faces) {
|
||||
for (i = 0; i < bot->num_faces; i++)
|
||||
{
|
||||
size_t v0 = (size_t)bot->faces[3*i+0];
|
||||
size_t v1 = (size_t)bot->faces[3*i+1];
|
||||
size_t v2 = (size_t)bot->faces[3*i+2];
|
||||
|
||||
TIE_VAL(tie_push)(d->cur_tie, d->tribuf, 1, mesh, 0);
|
||||
if (v0 >= bot->num_vertices || v1 >= bot->num_vertices || v2 >= bot->num_vertices)
|
||||
continue;
|
||||
|
||||
VSCALE((*d->tribuf[0]).v, (bot->vertices+3*v0), 1.0/1000.0);
|
||||
VSCALE((*d->tribuf[1]).v, (bot->vertices+3*v1), 1.0/1000.0);
|
||||
VSCALE((*d->tribuf[2]).v, (bot->vertices+3*v2), 1.0/1000.0);
|
||||
|
||||
TIE_VAL(tie_push)(d->cur_tie, d->tribuf, 1, mesh, 0);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
ret = -1;
|
||||
} else {
|
||||
bu_log("Strange, %d is not %d or %d\n", intern.idb_minor_type, ID_BOT, ID_NMG);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
bu_log("Strange, %d is not %d or %d\n", intern.idb_minor_type, ID_BOT, ID_NMG);
|
||||
return 0;
|
||||
rt_db_free_internal(&intern);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nmg_to_adrt_gcvwrite(struct nmgregion *r, const struct db_full_path *pathp, struct db_tree_state *tsp, void *client_data)
|
||||
{
|
||||
|
||||
struct isst_nmg_data *d = (struct isst_nmg_data *)client_data;
|
||||
struct model *m;
|
||||
struct adrt_mesh_s *mesh;
|
||||
char *path_str;
|
||||
|
||||
if (!r || !pathp || !tsp || !d || !d->meshes || !*d->meshes)
|
||||
return;
|
||||
|
||||
NMG_CK_REGION(r);
|
||||
RT_CK_FULL_PATH(pathp);
|
||||
|
||||
m = r->m_p;
|
||||
if (!m)
|
||||
return;
|
||||
NMG_CK_MODEL(m);
|
||||
|
||||
/* triangulate model */
|
||||
nmg_triangulate_model(m, d->vlfree, d->tol);
|
||||
|
||||
/* FIXME: where is this released? */
|
||||
BU_ALLOC(mesh, struct adrt_mesh_s);
|
||||
|
||||
BU_LIST_PUSH(&((*gcvwriter.meshes)->l), &(mesh->l));
|
||||
BU_LIST_PUSH(&((*d->meshes)->l), &(mesh->l));
|
||||
|
||||
mesh->texture = NULL;
|
||||
mesh->flags = 0;
|
||||
@@ -228,11 +268,27 @@ nmg_to_adrt_gcvwrite(struct nmgregion *r, const struct db_full_path *pathp, stru
|
||||
mesh->matid = tsp->ts_gmater;
|
||||
|
||||
VMOVE(mesh->attributes->color.v, tsp->ts_mater.ma_color);
|
||||
bu_strlcpy(mesh->name, db_path_to_string(pathp), sizeof(mesh->name));
|
||||
path_str = db_path_to_string(pathp);
|
||||
if (path_str) {
|
||||
bu_strlcpy(mesh->name, path_str, sizeof(mesh->name));
|
||||
bu_free(path_str, "db_path_to_string");
|
||||
} else {
|
||||
mesh->name[0] = '\0';
|
||||
}
|
||||
|
||||
nmg_to_adrt_internal(d->tribuf, d->cur_tie, mesh, r);
|
||||
}
|
||||
|
||||
GFile::GFile()
|
||||
: QObject(), tie(NULL), meshes(NULL), dbip(NULL), tribuf(NULL), current_file()
|
||||
{
|
||||
}
|
||||
|
||||
GFile::~GFile()
|
||||
{
|
||||
closedb();
|
||||
}
|
||||
|
||||
int
|
||||
GFile::load_g(const char *filename, int argc, const char *argv[])
|
||||
{
|
||||
@@ -241,6 +297,12 @@ GFile::load_g(const char *filename, int argc, const char *argv[])
|
||||
struct bg_tess_tol ttol; /* tessellation tolerance in mm */
|
||||
struct db_tree_state tree_state; /* includes tol & model */
|
||||
struct isst_nmg_data d;
|
||||
struct gcv_data gcvwriter;
|
||||
|
||||
if (!filename)
|
||||
return -1;
|
||||
|
||||
closedb();
|
||||
|
||||
RT_DBTS_INIT(&tree_state);
|
||||
tree_state.ts_tol = &tol;
|
||||
@@ -255,7 +317,6 @@ GFile::load_g(const char *filename, int argc, const char *argv[])
|
||||
ttol.norm = 0.0;
|
||||
|
||||
/* Set up calculation tolerance defaults */
|
||||
/* FIXME: These need to be improved */
|
||||
tol.magic = BN_TOL_MAGIC;
|
||||
tol.dist = 0.0005;
|
||||
tol.dist_sq = tol.dist * tol.dist;
|
||||
@@ -274,10 +335,14 @@ GFile::load_g(const char *filename, int argc, const char *argv[])
|
||||
*/
|
||||
if ((dbip = db_open(filename, DB_OPEN_READONLY)) == DBI_NULL) {
|
||||
bu_log("Unable to open geometry database file (%s)\n", filename);
|
||||
nmg_km(the_model);
|
||||
return -1;
|
||||
}
|
||||
if (db_dirbuild(dbip)) {
|
||||
bu_log("ERROR: db_dirbuild failed\n");
|
||||
db_close(dbip);
|
||||
dbip = NULL;
|
||||
nmg_km(the_model);
|
||||
return -1;
|
||||
}
|
||||
d.dbip = dbip;
|
||||
@@ -290,13 +355,16 @@ GFile::load_g(const char *filename, int argc, const char *argv[])
|
||||
|
||||
TIE_VAL(tie_init)(d.cur_tie, BU_PAGE_SIZE, TIE_KDTREE_FAST);
|
||||
|
||||
/* FIXME: where is this released? */
|
||||
BU_ALLOC(this->meshes, struct adrt_mesh_s);
|
||||
BU_LIST_INIT(&((this->meshes)->l));
|
||||
|
||||
gcvwriter.meshes = &this->meshes;
|
||||
d.meshes = &this->meshes;
|
||||
|
||||
memset(&gcvwriter, 0, sizeof(gcvwriter));
|
||||
gcvwriter.region_end_data.write_region = nmg_to_adrt_gcvwrite;
|
||||
gcvwriter.region_end_data.vlfree = &rt_vlfree;
|
||||
gcvwriter.region_end_data.client_data = &d;
|
||||
gcvwriter.meshes = &this->meshes;
|
||||
|
||||
tribuf = (TIE_3 **)bu_malloc(sizeof(TIE_3 *) * 3, "triangle tribuffer tribuffer");
|
||||
tribuf[0] = (TIE_3 *)bu_malloc(sizeof(TIE_3) * 3, "triangle tribuffer");
|
||||
@@ -318,20 +386,59 @@ GFile::load_g(const char *filename, int argc, const char *argv[])
|
||||
nmg_km(the_model);
|
||||
rt_vlist_cleanup();
|
||||
db_close(dbip);
|
||||
bu_free(tribuf[0], "vert");
|
||||
bu_free(tribuf[1], "vert");
|
||||
bu_free(tribuf[2], "vert");
|
||||
bu_free(tribuf, "tri");
|
||||
dbip = NULL;
|
||||
|
||||
if (tribuf) {
|
||||
bu_free(tribuf[0], "vert");
|
||||
bu_free(tribuf[1], "vert");
|
||||
bu_free(tribuf[2], "vert");
|
||||
bu_free(tribuf, "tri");
|
||||
tribuf = NULL;
|
||||
}
|
||||
|
||||
TIE_VAL(tie_prep)(d.cur_tie);
|
||||
|
||||
current_file = QString::fromLocal8Bit(filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
GFile::closedb()
|
||||
{
|
||||
bu_free(tie, "free tie");
|
||||
if (this->tie) {
|
||||
TIE_VAL(tie_free)(this->tie);
|
||||
bu_free(this->tie, "free tie");
|
||||
this->tie = NULL;
|
||||
}
|
||||
|
||||
if (this->meshes) {
|
||||
struct adrt_mesh_s *mesh;
|
||||
while (BU_LIST_WHILE(mesh, adrt_mesh_s, &this->meshes->l)) {
|
||||
BU_LIST_DEQUEUE(&mesh->l);
|
||||
if (mesh->attributes) {
|
||||
bu_free(mesh->attributes, "mesh attributes");
|
||||
mesh->attributes = NULL;
|
||||
}
|
||||
bu_free(mesh, "mesh");
|
||||
}
|
||||
bu_free(this->meshes, "mesh head");
|
||||
this->meshes = NULL;
|
||||
}
|
||||
|
||||
if (this->tribuf) {
|
||||
if (this->tribuf[0]) bu_free(this->tribuf[0], "vert");
|
||||
if (this->tribuf[1]) bu_free(this->tribuf[1], "vert");
|
||||
if (this->tribuf[2]) bu_free(this->tribuf[2], "vert");
|
||||
bu_free(this->tribuf, "tri");
|
||||
this->tribuf = NULL;
|
||||
}
|
||||
|
||||
if (this->dbip) {
|
||||
db_close(this->dbip);
|
||||
this->dbip = NULL;
|
||||
}
|
||||
|
||||
current_file.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ class GFile : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GFile();
|
||||
virtual ~GFile();
|
||||
|
||||
int load_g(const char *filename, int argc, const char **argv);
|
||||
void closedb();
|
||||
|
||||
|
||||
@@ -28,14 +28,19 @@
|
||||
int
|
||||
ISSTApp::load_g(const char *filename, int argc, const char *argv[])
|
||||
{
|
||||
if (!filename)
|
||||
return -1;
|
||||
|
||||
if (g.load_g(filename, argc, argv)) {
|
||||
w.statusBar()->showMessage("open failed");
|
||||
if (w.statusBar())
|
||||
w.statusBar()->showMessage("open failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// The OpenGL widget manages the rendering, so let it know about the
|
||||
// TIE data structure associated with the current model
|
||||
w.canvas->set_tie(g.tie);
|
||||
if (w.canvas)
|
||||
w.canvas->set_tie(g.tie);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+125
-60
@@ -28,6 +28,8 @@
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "bu/parallel.h"
|
||||
#include "bu/log.h"
|
||||
#include "bu/malloc.h"
|
||||
#include "isstgl.h"
|
||||
|
||||
#include <chrono>
|
||||
@@ -37,23 +39,25 @@
|
||||
TIERenderer::TIERenderer(isstGL *w)
|
||||
: m_w(w)
|
||||
{
|
||||
// Initialize TIE camera
|
||||
memset(&camera, 0, sizeof(camera));
|
||||
memset(&tile, 0, sizeof(tile));
|
||||
camera_pos_init[0] = camera_pos_init[1] = camera_pos_init[2] = 0.0;
|
||||
camera_focus_init[0] = camera_focus_init[1] = camera_focus_init[2] = 0.0;
|
||||
|
||||
// Initialize TIE camera
|
||||
camera.type = RENDER_CAMERA_PERSPECTIVE;
|
||||
camera.fov = 25;
|
||||
camera.w = 512;
|
||||
camera.h = 512;
|
||||
render_camera_init(&camera, bu_avail_cpus());
|
||||
render_phong_init(&camera.render, NULL);
|
||||
|
||||
// Initialize texture buffer
|
||||
TIENET_BUFFER_INIT(buffer_image);
|
||||
texdata = realloc(texdata, camera.w * camera.h * 3);
|
||||
texdata_size = camera.w * camera.h;
|
||||
texdata_size = (long)camera.w * (long)camera.h;
|
||||
texdata = malloc((size_t)texdata_size * 3);
|
||||
|
||||
// Initialize TIE tile
|
||||
//
|
||||
// Note: If orig_x and orig_Y are not initialized, output pixel placement
|
||||
// in the buffer may be randomly offset - you may see no image, or an image
|
||||
// in the wrong place (or it may happen to work if the values happen to be
|
||||
// zero anyway...)
|
||||
tile.orig_x = 0;
|
||||
tile.orig_y = 0;
|
||||
tile.format = RENDER_CAMERA_BIT_DEPTH_24;
|
||||
@@ -62,80 +66,116 @@ TIERenderer::TIERenderer(isstGL *w)
|
||||
TIERenderer::~TIERenderer()
|
||||
{
|
||||
TIENET_BUFFER_FREE(buffer_image);
|
||||
free(texdata);
|
||||
if (texdata) {
|
||||
free(texdata);
|
||||
texdata = NULL;
|
||||
}
|
||||
if (camera.view_list) {
|
||||
bu_free(camera.view_list, "camera view_list");
|
||||
camera.view_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void TIERenderer::resize()
|
||||
{
|
||||
// If something changed, we need to re-render - otherwise, no-op
|
||||
if (!changed)
|
||||
if (!changed || !m_w)
|
||||
return;
|
||||
|
||||
int w = m_w->width();
|
||||
int h = m_w->height();
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
// Translated from Tcl/Tk ISST logic for resolution adjustment
|
||||
if (resolution_factor == 0) {
|
||||
camera.w = w;
|
||||
camera.h = h;
|
||||
} else {
|
||||
camera.w = resolution_factor;
|
||||
camera.h = camera.w * h / w;
|
||||
camera.w = (resolution_factor > 0) ? resolution_factor : 1;
|
||||
camera.h = (int)((long long)camera.w * h / w);
|
||||
if (camera.h <= 0)
|
||||
camera.h = 1;
|
||||
}
|
||||
|
||||
// Set tile size
|
||||
tile.size_x = camera.w;
|
||||
tile.size_y = camera.h;
|
||||
|
||||
|
||||
// Set up the raytracing image buffer
|
||||
TIENET_BUFFER_SIZE(buffer_image, (uint32_t)(3 * camera.w * camera.h));
|
||||
TIENET_BUFFER_SIZE(buffer_image, (uint32_t)(3 * (size_t)camera.w * (size_t)camera.h));
|
||||
|
||||
if (texdata_size < camera.w * camera.h) {
|
||||
texdata_size = camera.w * camera.h;
|
||||
texdata = realloc(texdata, camera.w * camera.h * 3);
|
||||
size_t new_size = (size_t)camera.w * (size_t)camera.h;
|
||||
if (texdata_size < (long)new_size) {
|
||||
void *new_texdata = realloc(texdata, new_size * 3);
|
||||
if (new_texdata) {
|
||||
texdata = new_texdata;
|
||||
texdata_size = (long)new_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (texid == 0) {
|
||||
glGenTextures(1, &texid);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
|
||||
// Set up the TeXImage2D buffer that will hold the results of the raytrace
|
||||
// for OpenGL
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, camera.w, camera.h, 0, GL_RGB, GL_UNSIGNED_BYTE, texdata);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, camera.w, camera.h, 0, GL_RGB, GL_UNSIGNED_BYTE, texdata);
|
||||
}
|
||||
|
||||
void TIERenderer::res_incr()
|
||||
{
|
||||
// Increase setting controlling raytracing grid density.
|
||||
// Maximum is one raytraced pixel per window pixel
|
||||
if (!m_w)
|
||||
return;
|
||||
resolution++;
|
||||
CLAMP(resolution, 1, 20);
|
||||
resolution_factor = (resolution == 20) ? 0 : lrint(floor(m_w->width() * .05 * resolution));
|
||||
int win_w = m_w->width();
|
||||
if (win_w <= 0)
|
||||
win_w = 512;
|
||||
resolution_factor = (resolution == 20) ? 0 : lrint(floor(win_w * .05 * resolution));
|
||||
if (resolution < 20 && resolution_factor < 1)
|
||||
resolution_factor = 1;
|
||||
scaled = true;
|
||||
}
|
||||
|
||||
void TIERenderer::res_decr()
|
||||
{
|
||||
// Decrease setting controlling raytracing grid density.
|
||||
// Minimum is clamped - too course and the image is meaningless
|
||||
if (!m_w)
|
||||
return;
|
||||
resolution--;
|
||||
CLAMP(resolution, 1, 20);
|
||||
resolution_factor = (resolution == 20) ? 0 : lrint(floor(m_w->height() * .05 * resolution));
|
||||
int win_w = m_w->width();
|
||||
if (win_w <= 0)
|
||||
win_w = 512;
|
||||
resolution_factor = (resolution == 20) ? 0 : lrint(floor(win_w * .05 * resolution));
|
||||
if (resolution < 20 && resolution_factor < 1)
|
||||
resolution_factor = 1;
|
||||
scaled = true;
|
||||
}
|
||||
|
||||
void TIERenderer::render()
|
||||
{
|
||||
if (m_exiting)
|
||||
if (m_exiting || !m_w)
|
||||
return;
|
||||
|
||||
int w = m_w->width();
|
||||
int h = m_w->height();
|
||||
// Zero size == nothing to do
|
||||
if (!w || !h)
|
||||
// Zero or negative size == nothing to do
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
if (!tie) {
|
||||
// No scene loaded yet
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
return;
|
||||
}
|
||||
|
||||
if (scaled) {
|
||||
changed = true;
|
||||
scaled = false;
|
||||
@@ -163,7 +203,6 @@ void TIERenderer::render()
|
||||
return;
|
||||
Q_ASSERT(ctx->thread() == QThread::currentThread());
|
||||
|
||||
|
||||
// Have context, initialize if necessary
|
||||
m_w->makeCurrent();
|
||||
if (!m_init) {
|
||||
@@ -174,7 +213,6 @@ void TIERenderer::render()
|
||||
// Ready for actual OpenGL calls.
|
||||
resize();
|
||||
|
||||
|
||||
changed = false;
|
||||
|
||||
// IMPORTANT - this reset is necessary or the resultant image will
|
||||
@@ -187,20 +225,25 @@ void TIERenderer::render()
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glViewport(0,0, m_w->width(), m_w->height());
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glViewport(0, 0, m_w->width(), m_w->height());
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, m_w->width(), m_w->height(), 0, -1, 1);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
glLoadIdentity();
|
||||
glColor3f(1,1,1);
|
||||
glColor3f(1, 1, 1);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, camera.w, camera.h, GL_RGB, GL_UNSIGNED_BYTE, buffer_image.data + sizeof(camera_tile_t));
|
||||
|
||||
size_t req_bytes = sizeof(camera_tile_t) + 3 * (size_t)camera.w * (size_t)camera.h;
|
||||
if (buffer_image.data && buffer_image.size >= req_bytes) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, camera.w, camera.h, GL_RGB, GL_UNSIGNED_BYTE, buffer_image.data + sizeof(camera_tile_t));
|
||||
}
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
|
||||
glTexCoord2d(0, 0); glVertex3f(0, 0, 0);
|
||||
@@ -210,7 +253,6 @@ void TIERenderer::render()
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
// Make no context current on this thread and move the QOpenGLWidget's
|
||||
// context back to the gui thread.
|
||||
m_w->doneCurrent();
|
||||
@@ -253,22 +295,29 @@ isstGL::isstGL(QWidget *parent)
|
||||
|
||||
isstGL::~isstGL()
|
||||
{
|
||||
m_renderer->prepareExit();
|
||||
m_thread->quit();
|
||||
m_thread->wait();
|
||||
delete m_thread;
|
||||
if (m_renderer) {
|
||||
m_renderer->prepareExit();
|
||||
}
|
||||
if (m_thread) {
|
||||
m_thread->quit();
|
||||
m_thread->wait();
|
||||
delete m_thread;
|
||||
m_thread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void isstGL::onAboutToCompose()
|
||||
{
|
||||
// We are on the gui thread here. Composition is about to
|
||||
// begin. Wait until the render thread finishes.
|
||||
m_renderer->lockRenderer();
|
||||
if (m_renderer)
|
||||
m_renderer->lockRenderer();
|
||||
}
|
||||
|
||||
void isstGL::onFrameSwapped()
|
||||
{
|
||||
m_renderer->unlockRenderer();
|
||||
if (m_renderer)
|
||||
m_renderer->unlockRenderer();
|
||||
// Assuming a blocking swap, our animation is driven purely by the
|
||||
// vsync in this example.
|
||||
emit renderRequested();
|
||||
@@ -276,18 +325,21 @@ void isstGL::onFrameSwapped()
|
||||
|
||||
void isstGL::onAboutToResize()
|
||||
{
|
||||
m_renderer->lockRenderer();
|
||||
if (m_renderer)
|
||||
m_renderer->lockRenderer();
|
||||
}
|
||||
|
||||
void isstGL::onResized()
|
||||
{
|
||||
m_renderer->changed = true;
|
||||
m_renderer->unlockRenderer();
|
||||
if (m_renderer) {
|
||||
m_renderer->changed = true;
|
||||
m_renderer->unlockRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
void isstGL::grabContext()
|
||||
{
|
||||
if (m_renderer->m_exiting)
|
||||
if (!m_renderer || m_renderer->m_exiting)
|
||||
return;
|
||||
m_renderer->lockRenderer();
|
||||
QMutexLocker lock(m_renderer->grabMutex());
|
||||
@@ -299,15 +351,22 @@ void isstGL::grabContext()
|
||||
void
|
||||
isstGL::set_tie(struct tie_s *in_tie)
|
||||
{
|
||||
if (!m_renderer)
|
||||
return;
|
||||
|
||||
m_renderer->lockRenderer();
|
||||
m_renderer->tie = in_tie;
|
||||
if (in_tie) {
|
||||
// Initialize the camera position
|
||||
VSETALL(m_renderer->camera.pos, in_tie->radius);
|
||||
VMOVE(m_renderer->camera.focus, in_tie->mid);
|
||||
|
||||
// Initialize the camera position
|
||||
VSETALL(m_renderer->camera.pos, m_renderer->tie->radius);
|
||||
VMOVE(m_renderer->camera.focus, m_renderer->tie->mid);
|
||||
|
||||
// Record the initial settings for use in subsequent calculations
|
||||
VSETALL(m_renderer->camera_pos_init, m_renderer->tie->radius);
|
||||
VMOVE(m_renderer->camera_focus_init, m_renderer->tie->mid);
|
||||
// Record the initial settings for use in subsequent calculations
|
||||
VSETALL(m_renderer->camera_pos_init, in_tie->radius);
|
||||
VMOVE(m_renderer->camera_focus_init, in_tie->mid);
|
||||
m_renderer->changed = true;
|
||||
}
|
||||
m_renderer->unlockRenderer();
|
||||
|
||||
// Having just loaded a new TIE scene,
|
||||
// we need a new image
|
||||
@@ -315,6 +374,8 @@ isstGL::set_tie(struct tie_s *in_tie)
|
||||
}
|
||||
|
||||
void isstGL::keyPressEvent(QKeyEvent *k) {
|
||||
if (!k || !m_renderer)
|
||||
return;
|
||||
//QString kstr = QKeySequence(k->key()).toString();
|
||||
//bu_log("%s\n", kstr.toStdString().c_str());
|
||||
switch (k->key()) {
|
||||
@@ -337,6 +398,8 @@ void isstGL::keyPressEvent(QKeyEvent *k) {
|
||||
|
||||
void isstGL::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
if (!e)
|
||||
return;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
bu_log("(%d,%d)\n", e->x(), e->y());
|
||||
if (x_prev > -INT_MAX && y_prev > -INT_MAX) {
|
||||
@@ -349,8 +412,8 @@ void isstGL::mouseMoveEvent(QMouseEvent *e)
|
||||
if (x_prev > -INT_MAX && y_prev > -INT_MAX) {
|
||||
bu_log("Delta: (%f,%f)\n", e->position().x() - x_prev, e->position().y() - y_prev);
|
||||
}
|
||||
x_prev = e->position().x();
|
||||
y_prev = e->position().y();
|
||||
x_prev = (int)e->position().x();
|
||||
y_prev = (int)e->position().y();
|
||||
#endif
|
||||
|
||||
QOpenGLWidget::mouseMoveEvent(e);
|
||||
@@ -358,7 +421,9 @@ void isstGL::mouseMoveEvent(QMouseEvent *e)
|
||||
|
||||
void isstGL::save_image() {
|
||||
QImage image = this->grabFramebuffer();
|
||||
image.save("file.png");
|
||||
if (!image.isNull()) {
|
||||
image.save("file.png");
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
||||
+23
-18
@@ -34,8 +34,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
bu_setprogname(argv[0]);
|
||||
if (argc > 0 && argv && argv[0]) {
|
||||
bu_setprogname(argv[0]);
|
||||
}
|
||||
|
||||
ISSTApp app(argc, argv);
|
||||
app.setOrganizationName("BRL-CAD");
|
||||
@@ -50,29 +51,33 @@ int main(int argc, char *argv[])
|
||||
argc--; argv++;
|
||||
|
||||
// If we have command line arguments, process them
|
||||
if (argc > 1) {
|
||||
if (argc >= 1 && argv && argv[0]) {
|
||||
const char *filename = argv[0];
|
||||
argc--; argv++;
|
||||
app.load_g(filename, argc, (const char **)argv);
|
||||
}
|
||||
|
||||
// This is an illustration of how to force an exact size for
|
||||
// the OpenGL canvas. Useful when we need a framebuffer window
|
||||
// to exactly match a specified size.
|
||||
QSize cminsize = app.w.canvas->minimumSize();
|
||||
QSize cmaxsize = app.w.canvas->maximumSize();
|
||||
app.w.canvas->setMinimumSize(1100,800);
|
||||
app.w.canvas->setMaximumSize(1100,800);
|
||||
app.w.canvas->updateGeometry();
|
||||
if (app.w.canvas) {
|
||||
// This is an illustration of how to force an exact size for
|
||||
// the OpenGL canvas. Useful when we need a framebuffer window
|
||||
// to exactly match a specified size.
|
||||
QSize cminsize = app.w.canvas->minimumSize();
|
||||
QSize cmaxsize = app.w.canvas->maximumSize();
|
||||
app.w.canvas->setMinimumSize(1100,800);
|
||||
app.w.canvas->setMaximumSize(1100,800);
|
||||
app.w.canvas->updateGeometry();
|
||||
|
||||
// Draw the window
|
||||
app.w.show();
|
||||
// Draw the window
|
||||
app.w.show();
|
||||
|
||||
// Having forced the size we wanted, restore the original settings
|
||||
// to allow for subsequent change (if it would have been allowed
|
||||
// by the original settings.)
|
||||
app.w.canvas->setMinimumSize(cminsize);
|
||||
app.w.canvas->setMaximumSize(cmaxsize);
|
||||
// Having forced the size we wanted, restore the original settings
|
||||
// to allow for subsequent change (if it would have been allowed
|
||||
// by the original settings.)
|
||||
app.w.canvas->setMinimumSize(cminsize);
|
||||
app.w.canvas->setMaximumSize(cmaxsize);
|
||||
} else {
|
||||
app.w.show();
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -63,16 +63,22 @@ ISST_MainWindow::open_file()
|
||||
const char *file_filters = "BRL-CAD (*.g *.asc);;All Files (*)";
|
||||
QString fileName = QFileDialog::getOpenFileName((QWidget *)this,
|
||||
"Open Geometry File",
|
||||
qApp->applicationDirPath(),
|
||||
qApp ? qApp->applicationDirPath() : QString(),
|
||||
file_filters,
|
||||
NULL,
|
||||
QFileDialog::DontUseNativeDialog);
|
||||
if (!fileName.isEmpty()) {
|
||||
int ret = ((ISSTApp *)qApp)->load_g(fileName.toLocal8Bit(), 0, NULL);
|
||||
if (ret) {
|
||||
statusBar()->showMessage("open failed");
|
||||
} else {
|
||||
statusBar()->showMessage(fileName);
|
||||
ISSTApp *app = qobject_cast<ISSTApp *>(qApp);
|
||||
int ret = -1;
|
||||
if (app) {
|
||||
ret = app->load_g(fileName.toLocal8Bit().constData(), 0, NULL);
|
||||
}
|
||||
if (statusBar()) {
|
||||
if (ret) {
|
||||
statusBar()->showMessage("open failed");
|
||||
} else {
|
||||
statusBar()->showMessage(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,7 +104,8 @@ void ISST_MainWindow::write_settings()
|
||||
|
||||
void ISST_MainWindow::save_image()
|
||||
{
|
||||
canvas->save_image();
|
||||
if (canvas)
|
||||
canvas->save_image();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+16
-3
@@ -87,10 +87,20 @@ draw_char(struct fb *fbp, struct vfont *vfp, struct vfont_dispatch *vdp,
|
||||
int i, j, base, ln;
|
||||
int totwid = cw;
|
||||
int bytes_wide = (cw + 7) >> 3;
|
||||
int rW, rH;
|
||||
|
||||
if (!fbp || !vfp || !vdp || !vfp->vf_bits)
|
||||
return;
|
||||
|
||||
rW = fb_getwidth(fbp);
|
||||
rH = fb_getheight(fbp);
|
||||
|
||||
if (cw <= 0 || ch <= 0 || cw + 4 >= FONTBUFSZ || ch + 4 >= FONTBUFSZ)
|
||||
return;
|
||||
|
||||
if (x < 0 || x + totwid + 3 > rW)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
memset((char *)&filterbuf[i][0], 0, (totwid + 4) * sizeof(int));
|
||||
|
||||
@@ -103,8 +113,11 @@ draw_char(struct fb *fbp, struct vfont *vfp, struct vfont_dispatch *vdp,
|
||||
base = (vdp->vd_down % 2) ? 1 : 2;
|
||||
|
||||
for (i = ch + base; i >= base; i--) {
|
||||
int fy = y - vdp->vd_down + i;
|
||||
if (fy < 0 || fy >= rH)
|
||||
continue;
|
||||
squash(filterbuf[i - 1], filterbuf[i], filterbuf[i + 1], resbuf, totwid + 4);
|
||||
fb_read(fbp, x, y - vdp->vd_down + i, (unsigned char *)fbline, totwid + 3);
|
||||
fb_read(fbp, x, fy, (unsigned char *)fbline, totwid + 3);
|
||||
for (j = 0; j < (totwid + 3) - 1; j++) {
|
||||
int tmp;
|
||||
tmp = fbline[j][RED] & 0377;
|
||||
@@ -114,7 +127,7 @@ draw_char(struct fb *fbp, struct vfont *vfp, struct vfont_dispatch *vdp,
|
||||
tmp = fbline[j][BLU] & 0377;
|
||||
fbline[j][BLU] = (int)(color[BLU] * resbuf[j] + (1 - resbuf[j]) * tmp) & 0377;
|
||||
}
|
||||
(void)fb_write(fbp, x, y - vdp->vd_down + i, (unsigned char *)fbline, totwid + 3);
|
||||
(void)fb_write(fbp, x, fy, (unsigned char *)fbline, totwid + 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +203,7 @@ fbtext_draw(struct fb *fbp, struct fbtext *t, int x, int y, const char *s, const
|
||||
currx += 8;
|
||||
continue;
|
||||
}
|
||||
if (currx + cw > fb_getwidth(fbp) - 1)
|
||||
if (currx + cw + 3 > fb_getwidth(fbp))
|
||||
break;
|
||||
|
||||
draw_char(fbp, t->vfp, vdp, currx, y, color, cw, ch);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user