Skip to content

Commit 298398d

Browse files
committed
fix: avoid char-boundary panic in NBReader::try_read
1 parent f21a254 commit 298398d

1 file changed

Lines changed: 20 additions & 5 deletions

File tree

src/reader.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,9 @@ impl NBReader {
203203
pub fn try_read(&mut self) -> Option<char> {
204204
// discard eventual errors, EOF will be handled in read_until correctly
205205
let _ = self.read_into_buffer();
206-
if !self.buffer.is_empty() {
207-
self.buffer.drain(..1).last()
208-
} else {
209-
None
210-
}
206+
let first = self.buffer.chars().next()?;
207+
self.buffer.drain(..first.len_utf8());
208+
Some(first)
211209
}
212210
}
213211

@@ -457,4 +455,21 @@ mod tests {
457455
assert_eq!(None, r.try_read());
458456
assert_eq!(None, r.try_read());
459457
}
458+
459+
#[test]
460+
fn test_try_read_multibyte_byte() {
461+
// bytes >= 0x80 become two-byte chars in the internal buffer, so draining
462+
// one byte at a time used to land off a char boundary and panic
463+
let f = io::Cursor::new("é");
464+
let mut r = NBReader::new(f, Options::default());
465+
let mut count = 0;
466+
loop {
467+
match r.try_read() {
468+
Some(_) => count += 1,
469+
None if count == "é".len() => break,
470+
None => thread::sleep(time::Duration::from_millis(10)),
471+
}
472+
}
473+
assert_eq!(count, "é".len());
474+
}
460475
}

0 commit comments

Comments
 (0)