diff options
Diffstat (limited to 'src/reader.rs')
-rw-r--r-- | src/reader.rs | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/reader.rs b/src/reader.rs index 074ab99..24cc098 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -30,6 +30,7 @@ pub struct Reader<R> { // to have names reference namespaces could depth: Vec<Name>, namespace_declarations: Vec<HashSet<NamespaceDeclaration>>, + root_ended: bool, } impl<R> Reader<R> { @@ -49,6 +50,7 @@ impl<R> Reader<R> { depth: Vec::new(), // TODO: make sure reserved namespaces are never overwritten namespace_declarations: vec![default_declarations], + root_ended: false, } } @@ -66,6 +68,9 @@ where } pub async fn read_prolog<'s>(&'s mut self) -> Result<Option<Declaration>> { + if self.root_ended { + return Err(Error::RootElementEnded); + } loop { let input = str::from_utf8(self.buffer.data())?; match xml::Prolog::parse(input) { @@ -114,6 +119,9 @@ where } pub async fn read_start_tag<'s>(&'s mut self) -> Result<Element> { + if self.root_ended { + return Err(Error::RootElementEnded); + } loop { let input = str::from_utf8(self.buffer.data())?; match xml::STag::parse(input) { @@ -140,6 +148,9 @@ where } pub async fn read_end_tag<'s>(&'s mut self) -> Result<()> { + if self.root_ended { + return Err(Error::RootElementEnded); + } loop { let input = str::from_utf8(self.buffer.data())?; match xml::ETag::parse(input) { @@ -150,6 +161,9 @@ where &mut self.namespace_declarations, e, )?; + if self.depth.is_empty() { + self.root_ended = true + } self.buffer.consume(len); return Ok(()); } @@ -166,6 +180,9 @@ where } pub async fn read_element<'s>(&'s mut self) -> Result<Element> { + if self.root_ended { + return Err(Error::RootElementEnded); + } loop { let input = str::from_utf8(self.buffer.data())?; match xml::Element::parse(input) { @@ -173,6 +190,9 @@ where let len = self.buffer.available_data() - rest.as_bytes().len(); let element = Reader::<R>::element_from_xml(&mut self.namespace_declarations, e)?; + if self.depth.is_empty() { + self.root_ended = true + } self.buffer.consume(len); return Ok(element); } @@ -189,6 +209,9 @@ where } pub async fn read_content<'s>(&'s mut self) -> Result<Content> { + if self.root_ended { + return Err(Error::RootElementEnded); + } let mut last_char = false; let mut text = String::new(); loop { @@ -217,6 +240,9 @@ where &mut self.namespace_declarations, element, )?; + if self.depth.is_empty() { + self.root_ended = true + } self.buffer.consume(len); return Ok(Content::Element(element)); } @@ -279,6 +305,9 @@ where &mut self.namespace_declarations, element, )?; + if self.depth.is_empty() { + self.root_ended = true + } self.buffer.consume(len); return Ok(Content::Element(element)); } @@ -722,7 +751,7 @@ impl<R> Reader<R> { } #[cfg(test)] -pub(crate) mod test { +pub mod test { use tokio::io::AsyncRead; use super::Reader; |