aboutsummaryrefslogtreecommitdiffstats
path: root/src/xml/reader.rs
diff options
context:
space:
mode:
authorEdward Barnard2015-09-23 19:24:51 +0100
committerEdward Barnard2015-09-23 19:24:51 +0100
commitb06b6c6631a728d5a82da456c69d0bc3b562436c (patch)
treed9f0f6fc306ff56ccffe7614c3461c3d452a1b00 /src/xml/reader.rs
parenta835f3bc2b35baf25bd744d4dd3c70295f2dca74 (diff)
downloadrust-plist-b06b6c6631a728d5a82da456c69d0bc3b562436c.tar.bz2
Handle errors in xml parsing
Diffstat (limited to 'src/xml/reader.rs')
-rw-r--r--src/xml/reader.rs48
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