@@ -870,16 +870,22 @@ pub fn parse_method<'a>(bytes: &mut Bytes<'a>) -> Result<&'a str> {
870870 const POST : [ u8 ; 4 ] = * b"POST" ;
871871 match bytes. peek_n :: < [ u8 ; 4 ] > ( 4 ) {
872872 Some ( GET ) => {
873- unsafe {
874- bytes. advance_and_commit ( 4 ) ;
875- }
876- Ok ( Status :: Complete ( "GET" ) )
873+ // SAFETY: matched the ASCII string and boundary checked
874+ let method = unsafe {
875+ bytes. advance ( 4 ) ;
876+ let buf = bytes. slice_skip ( 1 ) ;
877+ str:: from_utf8_unchecked ( buf)
878+ } ;
879+ Ok ( Status :: Complete ( method) )
877880 }
878881 Some ( POST ) if bytes. peek_ahead ( 4 ) == Some ( b' ' ) => {
879- unsafe {
880- bytes. advance_and_commit ( 5 ) ;
881- }
882- Ok ( Status :: Complete ( "POST" ) )
882+ // SAFETY: matched the ASCII string and boundary checked
883+ let method = unsafe {
884+ bytes. advance ( 5 ) ;
885+ let buf = bytes. slice_skip ( 1 ) ;
886+ str:: from_utf8_unchecked ( buf)
887+ } ;
888+ Ok ( Status :: Complete ( method) )
883889 }
884890 _ => parse_token ( bytes) ,
885891 }
@@ -2421,4 +2427,23 @@ mod tests {
24212427 assert_eq ! ( offsetnz( x) , i) ;
24222428 }
24232429 }
2430+
2431+ #[ test]
2432+ fn test_method_within_buffer ( ) {
2433+ const REQUEST : & [ u8 ] = b"GET / HTTP/1.1\r \n \r \n " ;
2434+
2435+ let mut headers = [ EMPTY_HEADER ; 0 ] ;
2436+ let mut request = Request :: new ( & mut headers[ ..] ) ;
2437+
2438+ crate :: ParserConfig :: default ( )
2439+ . parse_request ( & mut request, REQUEST )
2440+ . unwrap ( ) ;
2441+
2442+ // SAFETY: will not wrap
2443+ let buf_end = unsafe { REQUEST . as_ptr ( ) . add ( REQUEST . len ( ) ) } ;
2444+ // Check that the method str is within the buffer
2445+ let method = request. method . unwrap ( ) ;
2446+ assert ! ( REQUEST . as_ptr( ) <= method. as_ptr( ) ) ;
2447+ assert ! ( method. as_ptr( ) <= buf_end) ;
2448+ }
24242449}
0 commit comments