From 361678dcbea78d5d4155439eb90936e3f0f36114 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 18 Jul 2021 12:33:31 +0200 Subject: parser: don't create samples with invalid cylinder ids By default, the parser would create samples with cylinder ids 0 and 1. This creates out-of-bound accesses for the common one-cylinder (or even no-cylinder) dives. These were harmless when the cylinder-table was of a fixed size. Since changing to a dynamic cylinder-table, these became actual out-of-bound accesses. Don't create such samples in the parser. Signed-off-by: Berthold Stoeger --- core/load-git.c | 12 ++++++++++-- core/parse.c | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/core/load-git.c b/core/load-git.c index 9753e0586..c44a880ae 100644 --- a/core/load-git.c +++ b/core/load-git.c @@ -641,6 +641,14 @@ static char *parse_sample_unit(struct sample *sample, double val, char *unit) return end; } +/* + * If the given cylinder doesn't exist, return NO_SENSOR. + */ +static uint8_t sanitize_sensor_id(const struct dive *d, int nr) +{ + return d && nr >= 0 && nr < d->cylinders.nr ? nr : NO_SENSOR; +} + /* * By default the sample data does not change unless the * save-file gives an explicit new value. So we copy the @@ -667,8 +675,8 @@ static struct sample *new_sample(struct git_parser_state *state) sample->pressure[0].mbar = 0; sample->pressure[1].mbar = 0; } else { - sample->sensor[0] = !state->o2pressure_sensor; - sample->sensor[1] = state->o2pressure_sensor; + sample->sensor[0] = sanitize_sensor_id(state->active_dive, !state->o2pressure_sensor); + sample->sensor[1] = sanitize_sensor_id(state->active_dive, state->o2pressure_sensor); } return sample; } diff --git a/core/parse.c b/core/parse.c index 459108a26..241d5763f 100644 --- a/core/parse.c +++ b/core/parse.c @@ -364,6 +364,14 @@ void ws_end(struct parser_state *state) { } +/* + * If the given cylinder doesn't exist, return NO_SENSOR. + */ +static uint8_t sanitize_sensor_id(const struct dive *d, int nr) +{ + return d && nr >= 0 && nr < d->cylinders.nr ? nr : NO_SENSOR; +} + /* * By default the sample data does not change unless the * save-file gives an explicit new value. So we copy the @@ -392,8 +400,8 @@ void sample_start(struct parser_state *state) sample->pressure[0].mbar = 0; sample->pressure[1].mbar = 0; } else { - sample->sensor[0] = !state->o2pressure_sensor; - sample->sensor[1] = state->o2pressure_sensor; + sample->sensor[0] = sanitize_sensor_id(state->cur_dive, !state->o2pressure_sensor); + sample->sensor[1] = sanitize_sensor_id(state->cur_dive, state->o2pressure_sensor); } state->cur_sample = sample; state->next_o2_sensor = 0; -- cgit v1.2.3-70-g09d2