@@ -16,18 +16,11 @@ use super::{Decoder, Encoder};
1616/// [`LinesCodec::new_with_max_length`]. Without a length limit, the internal read buffer can grow
1717/// without bound if a peer sends an unbounded amount of data without a `\n`, potentially leading
1818/// to memory exhaustion (DoS).
19- ///
20- /// # Direct `Decoder` Use
21- ///
22- /// `LinesCodec` caches the index after the last byte it searched when [`Decoder::decode`] returns
23- /// `Ok(None)`. Callers that invoke `decode` directly must pass the same [`BytesMut`] with newly
24- /// read bytes appended. If the buffer is replaced or bytes before the cached offset are changed,
25- /// create a new `LinesCodec` before decoding the replacement buffer.
2619#[ derive( Debug , Copy , Clone ) ]
2720#[ non_exhaustive]
2821pub struct LinesCodec {
2922 max_length : usize ,
30- // Next byte index to examine for `\n` after a previous incomplete decode.
23+ // Next byte index to examine for `\n` after an incomplete decode.
3124 next_index : usize ,
3225}
3326
@@ -91,11 +84,13 @@ impl Decoder for LinesCodec {
9184 return Ok ( None ) ;
9285 }
9386
94- let start = self . next_index . min ( src. len ( ) ) ;
95- debug_assert ! (
96- memchr( b'\n' , & src[ ..start] ) . is_none( ) ,
97- "LinesCodec buffer changed before cached search offset"
98- ) ;
87+ // Framed reads append to the same buffer after incomplete decodes. We do not currently
88+ // expect callers to replace it, but fall back to a fresh scan if they do.
89+ let start = if self . next_index < src. len ( ) {
90+ self . next_index
91+ } else {
92+ 0
93+ } ;
9994
10095 let len = match memchr ( b'\n' , & src[ start..] ) {
10196 Some ( n) => start + n,
0 commit comments