mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 14:10:19 +00:00
Correctly parse multiple tags in the divelog
The old parsing code overwrote the first comma with a '\0' and then
checked the index against the length of the buffer - which was changed by
replacing the ',' with the '\0'.
This means that since commit 78acf20848
("Don't crash on loading tags
longer than 127 chars") Subsurface has potentially damaged / lost data in
dive files!
Added a test dive that shows the issue if opened by a Subsurface version
after the commit mentioned above but before this commit.
Reported-by: Miika Turkia <miika.turkia@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
007aa79fd7
commit
89a58e23e0
2 changed files with 72 additions and 12 deletions
62
dives/test29.xml
Normal file
62
dives/test29.xml
Normal file
|
@ -0,0 +1,62 @@
|
|||
<divelog program='subsurface' version='2'>
|
||||
<settings>
|
||||
</settings>
|
||||
<dives>
|
||||
<dive number='29' tags='boat, wreck' date='2011-12-13' time='06:35:00' duration='30:00 min'>
|
||||
<location>irrelevant dive location</location>
|
||||
<notes>This is a dive that has two tags, boat and wreck</notes>
|
||||
<divecomputer model='Model Product' deviceid='e04d0248' diveid='00000002'>
|
||||
<depth max='20.1 m' mean='18.293 m' />
|
||||
<temperature water='20.0 C' />
|
||||
<sample time='0:06 min' depth='1.86 m' temp='20.0 C' ndl='99:00 min' />
|
||||
<sample time='1:00 min' depth='20.1 m' />
|
||||
<sample time='27:00 min' depth='20.1 m' />
|
||||
<sample time='28:00 min' depth='3.0 m' />
|
||||
<sample time='29:00 min' depth='3.0 m' />
|
||||
<sample time='30:00 min' depth='0.3 m' />
|
||||
</divecomputer>
|
||||
</dive>
|
||||
<dive number='30' tags='' date='2011-12-13' time='07:35:00' duration='30:00 min'>
|
||||
<location>irrelevant dive location</location>
|
||||
<notes>This is a dive that has an empty tags property in the XML file</notes>
|
||||
<divecomputer model='Model Product' deviceid='e04d0248' diveid='00000002'>
|
||||
<depth max='20.1 m' mean='18.293 m' />
|
||||
<temperature water='20.0 C' />
|
||||
<sample time='0:06 min' depth='1.86 m' temp='20.0 C' ndl='99:00 min' />
|
||||
<sample time='1:00 min' depth='20.1 m' />
|
||||
<sample time='27:00 min' depth='20.1 m' />
|
||||
<sample time='28:00 min' depth='3.0 m' />
|
||||
<sample time='29:00 min' depth='3.0 m' />
|
||||
<sample time='30:00 min' depth='0.3 m' />
|
||||
</divecomputer>
|
||||
</dive>
|
||||
<dive number='31' tags=',' date='2011-12-13' time='08:35:00' duration='30:00 min'>
|
||||
<location>irrelevant dive location</location>
|
||||
<notes>This is a dive that has a tags property with just a comma in the XML file</notes>
|
||||
<divecomputer model='Model Product' deviceid='e04d0248' diveid='00000002'>
|
||||
<depth max='20.1 m' mean='18.293 m' />
|
||||
<temperature water='20.0 C' />
|
||||
<sample time='0:06 min' depth='1.86 m' temp='20.0 C' ndl='99:00 min' />
|
||||
<sample time='1:00 min' depth='20.1 m' />
|
||||
<sample time='27:00 min' depth='20.1 m' />
|
||||
<sample time='28:00 min' depth='3.0 m' />
|
||||
<sample time='29:00 min' depth='3.0 m' />
|
||||
<sample time='30:00 min' depth='0.3 m' />
|
||||
</divecomputer>
|
||||
</dive>
|
||||
<dive number='32' tags='a, boat' date='2011-12-13' time='09:35:00' duration='30:00 min'>
|
||||
<location>irrelevant dive location</location>
|
||||
<notes>This is a dive that has a single letter tag 'a' (plus the boat tag)</notes>
|
||||
<divecomputer model='Model Product' deviceid='e04d0248' diveid='00000002'>
|
||||
<depth max='20.1 m' mean='18.293 m' />
|
||||
<temperature water='20.0 C' />
|
||||
<sample time='0:06 min' depth='1.86 m' temp='20.0 C' ndl='99:00 min' />
|
||||
<sample time='1:00 min' depth='20.1 m' />
|
||||
<sample time='27:00 min' depth='20.1 m' />
|
||||
<sample time='28:00 min' depth='3.0 m' />
|
||||
<sample time='29:00 min' depth='3.0 m' />
|
||||
<sample time='30:00 min' depth='0.3 m' />
|
||||
</divecomputer>
|
||||
</dive>
|
||||
</dives>
|
||||
</divelog>
|
22
parse-xml.c
22
parse-xml.c
|
@ -220,19 +220,18 @@ static void divetags(char *buffer, void *_tags)
|
|||
struct tag_entry *tags = _tags;
|
||||
int i = 0, start = 0, end = 0;
|
||||
enum ParseState state = FINDEND;
|
||||
i=0;
|
||||
while(i < strlen(buffer)) {
|
||||
int len = buffer ? strlen(buffer) : 0;
|
||||
|
||||
while(i < len) {
|
||||
if (buffer[i] == ',') {
|
||||
if (state == FINDSTART) {
|
||||
/* Detect empty tags */
|
||||
} else if (state == FINDEND) {
|
||||
/* Found end of tag */
|
||||
if (i > 1) {
|
||||
if(buffer[i-1] != '\\') {
|
||||
buffer[end-start+1] = '\0';
|
||||
if (i > 0 && buffer[i - 1] != '\\') {
|
||||
buffer[i] = '\0';
|
||||
state=FINDSTART;
|
||||
taglist_add_tag(tags, buffer+start);
|
||||
}
|
||||
} else {
|
||||
state=FINDSTART;
|
||||
}
|
||||
|
@ -245,18 +244,17 @@ static void divetags(char *buffer, void *_tags)
|
|||
state = FINDEND;
|
||||
start = i;
|
||||
} else if (state == FINDEND) {
|
||||
end=i;
|
||||
end = i;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (state == FINDEND) {
|
||||
if (end < start)
|
||||
end = strlen(buffer)-1;
|
||||
if (strlen(buffer) > 0) {
|
||||
buffer[end-start+1] = '\0';
|
||||
state=FINDSTART;
|
||||
taglist_add_tag(tags, buffer+start);
|
||||
end = len - 1;
|
||||
if (len > 0) {
|
||||
buffer[end + 1] = '\0';
|
||||
taglist_add_tag(tags, buffer + start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue