diff options
| author | Edward Barnard | 2015-09-23 19:24:51 +0100 |
|---|---|---|
| committer | Edward Barnard | 2015-09-23 19:24:51 +0100 |
| commit | b06b6c6631a728d5a82da456c69d0bc3b562436c (patch) | |
| tree | d9f0f6fc306ff56ccffe7614c3461c3d452a1b00 /src/xml/reader.rs | |
| parent | a835f3bc2b35baf25bd744d4dd3c70295f2dca74 (diff) | |
| download | rust-plist-b06b6c6631a728d5a82da456c69d0bc3b562436c.tar.bz2 | |
Handle errors in xml parsing
Diffstat (limited to 'src/xml/reader.rs')
| -rw-r--r-- | src/xml/reader.rs | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/src/xml/reader.rs b/src/xml/reader.rs index 006a04e..8960a39 100644 --- a/src/xml/reader.rs +++ b/src/xml/reader.rs @@ -9,7 +9,8 @@ use super::super::{ParserError, ParserResult, PlistEvent}; pub struct StreamingParser<R: Read> { xml_reader: EventReader<R>, - element_stack: Vec<String> + element_stack: Vec<String>, + finished: bool } impl<R: Read> StreamingParser<R> { @@ -24,7 +25,8 @@ impl<R: Read> StreamingParser<R> { StreamingParser { xml_reader: EventReader::with_config(reader, config), - element_stack: Vec::new() + element_stack: Vec::new(), + finished: false } } @@ -34,12 +36,8 @@ impl<R: Read> StreamingParser<R> { _ => Err(ParserError::InvalidData) } } -} - -impl<R: Read> Iterator for StreamingParser<R> { - type Item = ParserResult<PlistEvent>; - fn next(&mut self) -> Option<ParserResult<PlistEvent>> { + fn next_event(&mut self) -> Option<ParserResult<PlistEvent>> { loop { match self.xml_reader.next() { XmlEvent::StartElement { name, .. } => { @@ -99,13 +97,36 @@ impl<R: Read> Iterator for StreamingParser<R> { true => return None, false => return Some(Err(ParserError::UnexpectedEof)) } - } + }, + XmlEvent::Error(_) => return Some(Err(ParserError::InvalidData)), _ => () } } } } +impl<R: Read> Iterator for StreamingParser<R> { + type Item = ParserResult<PlistEvent>; + + fn next(&mut self) -> Option<ParserResult<PlistEvent>> { + if self.finished { + None + } else { + match self.next_event() { + None => { + self.finished = true; + None + }, + ret @ Some(Err(_)) => { + self.finished = true; + ret + } + ret => ret + } + } + } +} + #[cfg(test)] mod tests { use chrono::{TimeZone, UTC}; @@ -147,4 +168,15 @@ mod tests { assert_eq!(events, comparison); } + + #[test] + fn bad_data() { + use PlistEvent::*; + + let reader = File::open(&Path::new("./tests/data/xml_error.plist")).unwrap(); + let streaming_parser = StreamingParser::new(reader); + let events: Vec<_> = streaming_parser.collect(); + + assert!(events.last().unwrap().is_err()); + } }
\ No newline at end of file |
