parser: don't crash when parsing <weight> tags

When encountering a <weight> tag, we would parse into the last
weightsystem. However, we only create weightsystems when
encountering <weightsystem> tag. Therefore, this code would
either crash or overwrite the previous weightsystem.

Instead, create a new weightsystem for each <weight> tag.

Moreover, make sure that inside a <weightsystem> tag a
weightsystem actually exists. This should be the case,
but who knows...?

Reported-by: Nihal Gabr <gabr.nihal@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2020-11-01 14:40:57 +01:00 committed by Dirk Hohndel
parent b2b3544f3f
commit 386e08b69c

View file

@ -1223,7 +1223,10 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str
{ {
char *hash = NULL; char *hash = NULL;
cylinder_t *cyl = dive->cylinders.nr > 0 ? get_cylinder(dive, dive->cylinders.nr - 1) : NULL; cylinder_t *cyl = dive->cylinders.nr > 0 ? get_cylinder(dive, dive->cylinders.nr - 1) : NULL;
weightsystem_t *ws = dive->weightsystems.nr > 0 ?
&dive->weightsystems.weightsystems[dive->weightsystems.nr - 1] : NULL;
pressure_t p; pressure_t p;
weight_t w;
start_match("dive", name, buf); start_match("dive", name, buf);
switch (state->import_source) { switch (state->import_source) {
@ -1326,12 +1329,18 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str
return; return;
if (MATCH_STATE("airpressure.dive", pressure, &dive->surface_pressure)) if (MATCH_STATE("airpressure.dive", pressure, &dive->surface_pressure))
return; return;
if (MATCH("description.weightsystem", utf8_string, &dive->weightsystems.weightsystems[dive->weightsystems.nr - 1].description)) if (ws) {
return; if (MATCH("description.weightsystem", utf8_string, &ws->description))
if (MATCH_STATE("weight.weightsystem", weight, &dive->weightsystems.weightsystems[dive->weightsystems.nr - 1].weight)) return;
return; if (MATCH_STATE("weight.weightsystem", weight, &ws->weight))
if (MATCH_STATE("weight", weight, &dive->weightsystems.weightsystems[dive->weightsystems.nr - 1].weight)) return;
}
if (MATCH_STATE("weight", weight, &w)) {
weightsystem_t ws = empty_weightsystem;
ws.weight = w;
add_cloned_weightsystem(&dive->weightsystems, ws);
return; return;
}
if (cyl) { if (cyl) {
if (MATCH("size.cylinder", cylindersize, &cyl->type.size)) if (MATCH("size.cylinder", cylindersize, &cyl->type.size))
return; return;