Reject multiple GPX document roots

Found while testing crates/meta/src/gpx.rs:111

Co-Authored-By: GPT-6-Luna <noreply@openai.com>
This commit is contained in:
Max Mittelstädt
2026-10-30 06:15:05 +00:00
co-authored by GPT-6-Luna
parent 445dd3106e
commit 4c4d322bec
+12
View File
@@ -101,6 +101,7 @@ pub fn parse_gpx(s: &str) -> Result<Tracklog, GpxError> {
reader.config_mut().check_end_names = true;
let mut path: Vec<Vec<u8>> = Vec::new();
let mut seen_gpx = false;
let mut seen_root = false;
let mut log = Tracklog::default();
let mut segment: u32 = 0;
let mut pt: Option<Pending> = None;
@@ -111,6 +112,12 @@ pub fn parse_gpx(s: &str) -> Result<Tracklog, GpxError> {
Event::Start(ref e) | Event::Empty(ref e) => {
let name = local(e.name().as_ref()).to_vec();
let parent = path.last().map(Vec::as_slice);
if path.is_empty() {
if seen_root {
return Err(GpxError::Xml("multiple document elements".into()));
}
seen_root = true;
}
match name.as_slice() {
b"gpx" if path.is_empty() => seen_gpx = true,
b"trk" if parent == Some(b"gpx") => log.tracks += 1,
@@ -371,6 +378,11 @@ mod tests {
assert!((g.longitude - -179.5).abs() < 1e-9, "{g:?}");
}
#[test]
fn rejects_multiple_document_roots() {
assert!(matches!(parse_gpx("<gpx/><gpx/>"), Err(GpxError::Xml(_))));
}
#[test]
fn rejects_non_gpx_and_bad_input() {
assert_eq!(parse_gpx("<kml><Document/></kml>"), Err(GpxError::NotGpx));