@@ -55,6 +55,8 @@ enum ChunkedState {
5555 Body ,
5656 BodyCr ,
5757 BodyLf ,
58+ Trailer ,
59+ TrailerLf ,
5860 EndCr ,
5961 EndLf ,
6062 End ,
@@ -196,6 +198,8 @@ impl ChunkedState {
196198 Body => ChunkedState :: read_body ( cx, body, size, buf) ,
197199 BodyCr => ChunkedState :: read_body_cr ( cx, body) ,
198200 BodyLf => ChunkedState :: read_body_lf ( cx, body) ,
201+ Trailer => ChunkedState :: read_trailer ( cx, body) ,
202+ TrailerLf => ChunkedState :: read_trailer_lf ( cx, body) ,
199203 EndCr => ChunkedState :: read_end_cr ( cx, body) ,
200204 EndLf => ChunkedState :: read_end_lf ( cx, body) ,
201205 End => Poll :: Ready ( Ok ( ChunkedState :: End ) ) ,
@@ -340,18 +344,38 @@ impl ChunkedState {
340344 }
341345 }
342346
343- fn read_end_cr < R : MemRead > (
347+ fn read_trailer < R : MemRead > (
344348 cx : & mut task:: Context < ' _ > ,
345349 rdr : & mut R ,
346350 ) -> Poll < Result < ChunkedState , io:: Error > > {
351+ trace ! ( "read_trailer" ) ;
347352 match byte ! ( rdr, cx) {
348- b'\r' => Poll :: Ready ( Ok ( ChunkedState :: EndLf ) ) ,
353+ b'\r' => Poll :: Ready ( Ok ( ChunkedState :: TrailerLf ) ) ,
354+ _ => Poll :: Ready ( Ok ( ChunkedState :: Trailer ) ) ,
355+ }
356+ }
357+ fn read_trailer_lf < R : MemRead > (
358+ cx : & mut task:: Context < ' _ > ,
359+ rdr : & mut R ,
360+ ) -> Poll < Result < ChunkedState , io:: Error > > {
361+ match byte ! ( rdr, cx) {
362+ b'\n' => Poll :: Ready ( Ok ( ChunkedState :: EndCr ) ) ,
349363 _ => Poll :: Ready ( Err ( io:: Error :: new (
350364 io:: ErrorKind :: InvalidInput ,
351- "Invalid chunk end CR " ,
365+ "Invalid trailer end LF " ,
352366 ) ) ) ,
353367 }
354368 }
369+
370+ fn read_end_cr < R : MemRead > (
371+ cx : & mut task:: Context < ' _ > ,
372+ rdr : & mut R ,
373+ ) -> Poll < Result < ChunkedState , io:: Error > > {
374+ match byte ! ( rdr, cx) {
375+ b'\r' => Poll :: Ready ( Ok ( ChunkedState :: EndLf ) ) ,
376+ _ => Poll :: Ready ( Ok ( ChunkedState :: Trailer ) ) ,
377+ }
378+ }
355379 fn read_end_lf < R : MemRead > (
356380 cx : & mut task:: Context < ' _ > ,
357381 rdr : & mut R ,
@@ -538,6 +562,15 @@ mod tests {
538562 assert_eq ! ( "1234567890abcdef" , & result) ;
539563 }
540564
565+ #[ tokio:: test]
566+ async fn test_read_chunked_trailer_with_missing_lf ( ) {
567+ let mut mock_buf = & b"10\r \n 1234567890abcdef\r \n 0\r \n bad\r \r \n " [ ..] ;
568+ let mut decoder = Decoder :: chunked ( ) ;
569+ decoder. decode_fut ( & mut mock_buf) . await . expect ( "decode" ) ;
570+ let e = decoder. decode_fut ( & mut mock_buf) . await . unwrap_err ( ) ;
571+ assert_eq ! ( e. kind( ) , io:: ErrorKind :: InvalidInput ) ;
572+ }
573+
541574 #[ tokio:: test]
542575 async fn test_read_chunked_after_eof ( ) {
543576 let mut mock_buf = & b"10\r \n 1234567890abcdef\r \n 0\r \n \r \n " [ ..] ;
0 commit comments