star-cad

Geometric operators for computer-aided design
git clone git://git.meso-star.fr/star-cad.git
Log | Files | Refs | README | LICENSE

commit 84858a1d8153c8963f76860f4984232b074d5e48
parent f0088ebd351d50b5cf1d648e11693e69315a2336
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed, 15 Oct 2025 11:39:15 +0200

Fix invalid memory accesses

Access memory just after releasing it.

Diffstat:
Msrc/scad_device.c | 104++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/scad_geometry.c | 3++-
2 files changed, 57 insertions(+), 50 deletions(-)

diff --git a/src/scad_device.c b/src/scad_device.c @@ -28,63 +28,76 @@ #include <rsys/rsys.h> /******************************************************************************* + * The unique device in scad-cad + ******************************************************************************/ +static struct scad_device* g_device = NULL; + +/******************************************************************************* * Local functions ******************************************************************************/ static res_T -device_release(struct scad_device* dev) +device_release(void) { res_T res = RES_OK; - struct htable_geometries tmp; - struct htable_geometries_iterator it, end; int log, empty; - enum scad_log_refcounting option; + enum scad_log_refcounting option_ref; + int option_dec; enum log_type log_type; + struct mem_allocator* allocator; - ASSERT(dev); + ASSERT(g_device); - option = dev->options.Misc.LogRefCounting; - empty = htable_geometries_is_empty(&dev->allgeom); + allocator = g_device->allocator; + option_ref = g_device->options.Misc.LogRefCounting; + option_dec = g_device->options.Misc.DebugEmptyContext; + empty = htable_geometries_is_empty(&g_device->allgeom); log_type = empty ? LOG_OUTPUT : LOG_WARNING; - log = (option & SCAD_LOG_DIMTAGS_ALL) - || (!empty && (option & SCAD_LOG_DIMTAGS_ONLY_UNDELETED)); - dev->log = log; - dev->log_type = log_type; - - /* Duplicate the htable we iterate on as dev->allgeom will be altered during - * the process (through calls to geometry_release) */ - htable_geometries_init(dev->allocator, &tmp); - CHK(RES_OK == htable_geometries_copy(&tmp, &dev->allgeom)); - htable_geometries_begin(&tmp, &it); - htable_geometries_end(&tmp, &end); - if(log && empty) { - logger_print(dev->logger, log_type, "No scad geometry.\n"); - } - while(!htable_geometries_iterator_eq(&it, &end)) { - struct scad_geometry* geom = *htable_geometries_iterator_key_get(&it); - while(geom->ref > 0) { - SCAD(geometry_ref_put(geom)); + log = (option_ref & SCAD_LOG_DIMTAGS_ALL) + || (!empty && (option_ref & SCAD_LOG_DIMTAGS_ONLY_UNDELETED)); + g_device->log = log; + g_device->log_type = log_type; + + if(empty) { + if(log) logger_print(g_device->logger, log_type, "No scad geometry.\n"); + } else { + struct htable_geometries tmp; + struct htable_geometries_iterator it, end; + /* Duplicate the htable we iterate on as dev->allgeom will be altered during + * the process (through calls to geometry_release) */ + htable_geometries_init(allocator, &tmp); + CHK(RES_OK == htable_geometries_copy(&tmp, &g_device->allgeom)); + htable_geometries_begin(&tmp, &it); + htable_geometries_end(&tmp, &end); + while(!htable_geometries_iterator_eq(&it, &end)) { + struct scad_geometry* geom = *htable_geometries_iterator_key_get(&it); + long cpt = geom->ref; + while(cpt-- > 0) { + SCAD(geometry_ref_put(geom)); + } + htable_geometries_iterator_next(&it); } - htable_geometries_iterator_next(&it); - } - htable_names_release(&dev->geometry_names); - htable_geometries_release(&dev->allgeom); - htable_tags2desc_release(dev->tags2desc); - htable_tags2desc_release(dev->tags2desc+1); - htable_size_modifiers_release(&dev->size_modifiers_by_dim[0]); - htable_size_modifiers_release(&dev->size_modifiers_by_dim[1]); - htable_size_modifiers_release(&dev->size_modifiers_by_dim[2]); - htable_size_modifiers_release(&dev->size_modifiers_by_dim[3]); + htable_geometries_release(&tmp); + } + htable_names_release(&g_device->geometry_names); + htable_geometries_release(&g_device->allgeom); + htable_tags2desc_release(g_device->tags2desc); + htable_tags2desc_release(g_device->tags2desc+1); + htable_size_modifiers_release(&g_device->size_modifiers_by_dim[0]); + htable_size_modifiers_release(&g_device->size_modifiers_by_dim[1]); + htable_size_modifiers_release(&g_device->size_modifiers_by_dim[2]); + htable_size_modifiers_release(&g_device->size_modifiers_by_dim[3]); if(log) { - logger_print(dev->logger, log_type, "End finalizing scad.\n"); + logger_print(g_device->logger, log_type, "End finalizing scad.\n"); } - MEM_RM(dev->allocator, dev); - htable_geometries_release(&tmp); - if(dev->options.Misc.DebugEmptyContext) { + if(option_dec) { /* After releasing all star-cad stuff, gmsh and OCC contexts must be empty */ - return check_empty_gmsh_occ(dev); + res = check_empty_gmsh_occ(g_device); } + MEM_RM(allocator, g_device); + g_device = NULL; + return res; } @@ -123,11 +136,6 @@ log_message(struct scad_device* dev, const char* msg, ...) } /******************************************************************************* - * The unique device in scad-cad - ******************************************************************************/ -static struct scad_device* g_device = NULL; - -/******************************************************************************* * Exported scad_device functions ******************************************************************************/ res_T @@ -661,8 +669,7 @@ exit: return res; error: if(g_device) { - device_release(g_device); - g_device = NULL; + device_release(); } goto exit; } @@ -690,8 +697,7 @@ scad_finalize "Finalizing scad; undeleted tags will be automatically unregistered.\n"); } - tmp_res = device_release(g_device); - g_device = NULL; + tmp_res = device_release(); gmshFinalize(&ierr); ERR(gmsh_err_to_res_T(ierr)); diff --git a/src/scad_geometry.c b/src/scad_geometry.c @@ -654,7 +654,8 @@ scad_scene_clear } while(!htable_geometries_iterator_eq(&it, &end)) { struct scad_geometry* geom = *htable_geometries_iterator_key_get(&it); - while(geom->ref > 0) { + long cpt = geom->ref; + while(cpt-- > 0) { ERR(scad_geometry_ref_put(geom)); } htable_geometries_iterator_next(&it);