Skip to content

Commit 5a3ee10

Browse files
committed
Correctly handle incomplete parser responses
1 parent c2ec0a1 commit 5a3ee10

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/client.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ impl<T: Read + Write> Client<T> {
484484
}
485485

486486
fn read_response_onto(&mut self, data: &mut Vec<u8>) -> Result<()> {
487+
let mut continue_from = None;
487488
let mut try_first = !data.is_empty();
488489
let match_tag = format!("{}{}", TAG_PREFIX, self.tag);
489490
loop {
@@ -493,7 +494,7 @@ impl<T: Read + Write> Client<T> {
493494
} else {
494495
let start_new = data.len();
495496
try!(self.readline(data));
496-
start_new
497+
continue_from.take().unwrap_or(start_new)
497498
};
498499

499500
let break_with = {
@@ -519,7 +520,11 @@ impl<T: Read + Write> Client<T> {
519520
status => Err((status, None)),
520521
})
521522
}
522-
IResult::Done(..) | IResult::Incomplete(..) => None,
523+
IResult::Done(..) => None,
524+
IResult::Incomplete(..) => {
525+
continue_from = Some(line_start);
526+
None
527+
}
523528
_ => Some(Err((Status::Bye, None))),
524529
}
525530
};
@@ -606,6 +611,18 @@ mod tests {
606611
}
607612

608613

614+
#[test]
615+
fn fetch_body() {
616+
let response = "a0 OK Logged in.\r\n\
617+
* 2 FETCH (BODY[TEXT] {3}\r\nfoo)\r\n\
618+
a0 OK FETCH completed\r\n";
619+
let mock_stream = MockStream::new(response.as_bytes().to_vec());
620+
let mut client = Client::new(mock_stream);
621+
client.read_response().unwrap();
622+
client.read_response().unwrap();
623+
}
624+
625+
609626
#[test]
610627
fn read_greeting() {
611628
let greeting = "* OK Dovecot ready.\r\n";

0 commit comments

Comments
 (0)