Skip to content

Commit cefd9fb

Browse files
committed
Revert "Revert "Fix usage of split_inclusive in event parser (#31)""
This reverts commit d674a04.
1 parent d674a04 commit cefd9fb

File tree

3 files changed

+53
-36
lines changed

3 files changed

+53
-36
lines changed

.circleci/config.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,14 @@ version: 2
22
jobs:
33
build:
44
docker:
5-
- image: circleci/rust:latest
6-
5+
- image: cimg/rust:1.59.0
76
steps:
87
- checkout
9-
108
- run:
11-
name: Install clippy
12-
command: rustup component add clippy
13-
- run:
14-
name: Install rustfmt
15-
command: rustup component add rustfmt
16-
9+
name: Check Version
10+
command: |
11+
cargo --version
12+
rustc --version
1713
- run:
1814
name: Check consistent formatting
1915
command: cargo fmt && git diff --exit-code

eventsource-client/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ maplit = "1.0.1"
2727
simplelog = "0.5.3"
2828
tokio = { version = "1.2.0", features = ["macros", "rt-multi-thread"] }
2929
test-case = "1.2.3"
30+
proptest = "1.0.0"
31+
3032

3133
[features]
3234
default = ["rustls"]

eventsource-client/src/event_parser.rs

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -309,34 +309,43 @@ impl EventParser {
309309
// * the first line should be appended to the incomplete line, if any
310310

311311
if let Some(incomplete_line) = self.incomplete_line.as_mut() {
312-
let line = lines
313-
.next()
314-
// split always returns at least one item
315-
.unwrap();
316-
trace!(
317-
"extending line from previous chunk: {:?}+{:?}",
318-
logify(incomplete_line),
319-
logify(line)
320-
);
312+
trace!("incomplete_line {:?}", incomplete_line);
313+
if let Some(line) = lines.next() {
314+
trace!(
315+
"extending line from previous chunk: {:?}+{:?}",
316+
logify(incomplete_line),
317+
logify(line)
318+
);
321319

322-
self.last_char_was_cr = false;
323-
if !line.is_empty() {
324-
// Checking the last character handles lines where the last character is a
325-
// terminator, but also where the entire line is a terminator.
326-
match line.last().unwrap() {
327-
b'\r' => {
328-
incomplete_line.extend_from_slice(&line[..line.len() - 1]);
329-
let il = self.incomplete_line.take();
330-
self.complete_lines.push_back(il.unwrap());
331-
self.last_char_was_cr = true;
332-
}
333-
b'\n' => {
334-
incomplete_line.extend_from_slice(&line[..line.len() - 1]);
335-
let il = self.incomplete_line.take();
336-
self.complete_lines.push_back(il.unwrap());
337-
}
338-
_ => incomplete_line.extend_from_slice(line),
339-
};
320+
self.last_char_was_cr = false;
321+
if !line.is_empty() {
322+
// Checking the last character handles lines where the last character is a
323+
// terminator, but also where the entire line is a terminator.
324+
match line.last().unwrap() {
325+
b'\r' => {
326+
trace!("\\r branch");
327+
incomplete_line.extend_from_slice(&line[..line.len() - 1]);
328+
let il = self.incomplete_line.take();
329+
self.complete_lines.push_back(il.unwrap());
330+
self.last_char_was_cr = true;
331+
}
332+
b'\n' => {
333+
trace!("\\n branch");
334+
incomplete_line.extend_from_slice(&line[..line.len() - 1]);
335+
let il = self.incomplete_line.take();
336+
self.complete_lines.push_back(il.unwrap());
337+
}
338+
_ => {
339+
trace!(
340+
"other branch, extending slice {:?} with {:?}",
341+
incomplete_line,
342+
line
343+
);
344+
incomplete_line.extend_from_slice(line);
345+
trace!("Now we have {:?}", incomplete_line);
346+
}
347+
};
348+
}
340349
}
341350
}
342351

@@ -397,6 +406,7 @@ impl EventParser {
397406
#[cfg(test)]
398407
mod tests {
399408
use super::{Error::*, *};
409+
use proptest::proptest;
400410
use test_case::test_case;
401411

402412
fn field<'a>(key: &'a str, value: &'a str) -> Result<Option<(&'a str, &'a str)>> {
@@ -693,4 +703,13 @@ mod tests {
693703
std::fs::read(format!("test-data/{}", name))
694704
.unwrap_or_else(|_| panic!("couldn't read {}", name))
695705
}
706+
707+
proptest! {
708+
#[test]
709+
fn test_decode_and_buffer_lines_does_not_crash(next in "(\r\n|\r|\n)*event: [^\n\r:]*(\r\n|\r|\n)", previous in "(\r\n|\r|\n)*event: [^\n\r:]*(\r\n|\r|\n)") {
710+
let mut parser = EventParser::new();
711+
parser.incomplete_line = Some(previous.as_bytes().to_vec());
712+
parser.decode_and_buffer_lines(Bytes::from(next));
713+
}
714+
}
696715
}

0 commit comments

Comments
 (0)