summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAriel Dabalsa <arieldabalsa@gmail.com>2017-05-05 11:07:29 -0400
committerMarkus Unterwaditzer <markus@unterwaditzer.net>2017-05-05 23:14:33 +0200
commitf4605c6e3849355d64751f1d606a6cc253d56579 (patch)
treefc9ed30c5d76489bc3ec259419167f985cb6db63
parentb5c072e344279d64dd0d25d9f47443d96038e8ce (diff)
Fix infinite loop on mismatched BEGIN/END tags
-rw-r--r--src/vobject/lib.rs22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/vobject/lib.rs b/src/vobject/lib.rs
index 2938565..bb3c91d 100644
--- a/src/vobject/lib.rs
+++ b/src/vobject/lib.rs
@@ -382,9 +382,7 @@ impl<'s> Parser<'s> {
property = try!(self.consume_property());
if property.name == "BEGIN" {
self.pos = previous_pos;
- while let Ok(subcomponent) = self.consume_component() {
- component.subcomponents.push(subcomponent);
- };
+ component.subcomponents.push(try!(self.consume_component()));
} else if property.name == "END" {
if property.raw_value != c_name {
self.pos = begin_pos;
@@ -531,7 +529,7 @@ impl ParseError {
#[cfg(test)]
mod tests {
- use super::Parser;
+ use super::{Parser, ParseError};
#[test]
fn test_unfold1() {
@@ -583,5 +581,21 @@ mod tests {
assert_eq!(p.pos, 4);
}
+ #[test]
+ fn mismatched_begin_end_tags_returns_error() {
+ // Test for infinite loops as well
+ use std::sync::mpsc::{channel, RecvTimeoutError};
+ use std::time::Duration;
+ let mut p = Parser {input: "BEGIN:a\nBEGIN:b\nEND:a", pos: 0};
+
+ let (tx, rx) = channel();
+ ::std::thread::spawn(move|| { tx.send(p.consume_component()) });
+
+ match rx.recv_timeout(Duration::from_millis(50)) {
+ Err(RecvTimeoutError::Timeout) => assert!(false),
+ Ok(Err(ParseError {desc: _} )) => assert!(true),
+ _ => assert!(false),
+ }
+ }
}