From 02055ba067ddc157c907d11107b08df8eb55a303 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Wed, 7 Feb 2024 19:34:26 +0100 Subject: [PATCH] planner: fix crash when planning with surface interval The planner uses a one-past-end pseudo cylinder for marking the surface interval outside of water. This overflowed arrays in setup_gas_sensor_pressure(). See #4086. Note: contains a second unrelated crash report. As a band-aid allocate bigger arrays. But obviously, the proper fix is to not generate invalid gas-change events. Signed-off-by: Berthold Stoeger --- core/profile.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/profile.c b/core/profile.c index 2a6e633f1..1df947804 100644 --- a/core/profile.c +++ b/core/profile.c @@ -751,12 +751,14 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive if (pi->nr_cylinders == 0) return; - int *seen = malloc(pi->nr_cylinders * sizeof(*seen)); - int *first = malloc(pi->nr_cylinders * sizeof(*first)); - int *last = malloc(pi->nr_cylinders * sizeof(*last)); + /* FIXME: The planner uses a dummy one-past-end cylinder for surface air! */ + int num_cyl = pi->nr_cylinders + 1; + int *seen = malloc(num_cyl * sizeof(*seen)); + int *first = malloc(num_cyl * sizeof(*first)); + int *last = malloc(num_cyl * sizeof(*last)); const struct divecomputer *secondary; - for (i = 0; i < pi->nr_cylinders; i++) { + for (i = 0; i < num_cyl; i++) { seen[i] = 0; first[i] = 0; last[i] = INT_MAX; @@ -769,7 +771,11 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive int sec = ev->time.seconds; if (cyl < 0) + continue; // unknown cylinder + if (cyl >= num_cyl) { + fprintf(stderr, "setup_gas_sensor_pressure(): invalid cylinder idx %d\n", cyl); continue; + } last[prev] = sec; prev = cyl;