@@ -314,9 +314,11 @@ mod extension {
314314 use std:: str;
315315
316316 #[ derive( Clone , PartialEq , Eq , Hash ) ]
317+ // Invariant: the first self.1 bytes of self.0 are valid UTF-8.
317318 pub struct InlineExtension ( [ u8 ; InlineExtension :: MAX ] , u8 ) ;
318319
319320 #[ derive( Clone , PartialEq , Eq , Hash ) ]
321+ // Invariant: self.0 contains valid UTF-8.
320322 pub struct AllocatedExtension ( Box < [ u8 ] > ) ;
321323
322324 impl InlineExtension {
@@ -328,11 +330,15 @@ mod extension {
328330
329331 write_checked ( src, & mut data) ?;
330332
333+ // Invariant: write_checked ensures that the first src.len() bytes
334+ // of data are valid UTF-8.
331335 Ok ( InlineExtension ( data, src. len ( ) as u8 ) )
332336 }
333337
334338 pub fn as_str ( & self ) -> & str {
335339 let InlineExtension ( ref data, len) = self ;
340+ // Safety: the invariant of InlineExtension ensures that the first
341+ // len bytes of data contain valid UTF-8.
336342 unsafe { str:: from_utf8_unchecked ( & data[ ..* len as usize ] ) }
337343 }
338344 }
@@ -343,10 +349,14 @@ mod extension {
343349
344350 write_checked ( src, & mut data) ?;
345351
352+ // Invariant: data is exactly src.len() long and write_checked
353+ // ensures that the first src.len() bytes of data are valid UTF-8.
346354 Ok ( AllocatedExtension ( data. into_boxed_slice ( ) ) )
347355 }
348356
349357 pub fn as_str ( & self ) -> & str {
358+ // Safety: the invariant of AllocatedExtension ensures that self.0
359+ // contains valid UTF-8.
350360 unsafe { str:: from_utf8_unchecked ( & self . 0 ) }
351361 }
352362 }
@@ -363,6 +373,9 @@ mod extension {
363373 //
364374 // https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01#Method
365375 //
376+ // Note that this definition means that any &[u8] that consists solely of valid
377+ // characters is also valid UTF-8 because the valid method characters are a
378+ // subset of the valid 1 byte UTF-8 encoding.
366379 const METHOD_CHARS : [ u8 ; 256 ] = [
367380 // 0 1 2 3 4 5 6 7 8 9
368381 b'\0' , b'\0' , b'\0' , b'\0' , b'\0' , b'\0' , b'\0' , b'\0' , b'\0' , b'\0' , // x
@@ -393,6 +406,8 @@ mod extension {
393406 b'\0' , b'\0' , b'\0' , b'\0' , b'\0' , b'\0' // 25x
394407 ] ;
395408
409+ // write_checked ensures (among other things) that the first src.len() bytes
410+ // of dst are valid UTF-8
396411 fn write_checked ( src : & [ u8 ] , dst : & mut [ u8 ] ) -> Result < ( ) , InvalidMethod > {
397412 for ( i, & b) in src. iter ( ) . enumerate ( ) {
398413 let b = METHOD_CHARS [ b as usize ] ;
0 commit comments