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:
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);