@@ -296,22 +296,18 @@ pub(super) fn presented_id_matches_constraint(
296296pub ( crate ) fn is_valid_ipv4_address ( ip_address : untrusted:: Input ) -> bool {
297297 let mut ip_address = untrusted:: Reader :: new ( ip_address) ;
298298 let mut is_first_byte = true ;
299- let mut current_textual_octet : [ u8 ; 3 ] = [ 0 , 0 , 0 ] ;
300- let mut current_textual_octet_size = 0 ;
299+ let mut current : [ u8 ; 3 ] = [ 0 , 0 , 0 ] ;
300+ let mut current_size = 0 ;
301301 let mut dot_count = 0 ;
302302
303303 loop {
304304 // Returns a u32 so it's possible to identify (and error) when
305305 // provided textual octets > 255, not representable by u8.
306- fn textual_octets_to_octet ( textual_octets : [ u8 ; 3 ] , textual_octet_size : usize ) -> u32 {
306+ fn radix10_to_octet ( textual_octets : & [ u8 ] ) -> u32 {
307307 let mut result: u32 = 0 ;
308- for ( i, textual_octet) in textual_octets. iter ( ) . rev ( ) . enumerate ( ) {
309- if i >= textual_octet_size {
310- break ;
311- }
312- if let Some ( digit) = char:: to_digit ( * textual_octet as char , 10 ) {
313- result += digit * 10_u32 . pow ( i as u32 ) ;
314- }
308+ for digit in textual_octets. iter ( ) {
309+ result *= 10 ;
310+ result += u32:: from ( * digit) ;
315311 }
316312 result
317313 }
@@ -331,34 +327,33 @@ pub(crate) fn is_valid_ipv4_address(ip_address: untrusted::Input) -> bool {
331327 return false ;
332328 }
333329 dot_count += 1 ;
334- if current_textual_octet_size == 0 {
330+ if current_size == 0 {
335331 // IPv4 address cannot contain two dots in a row.
336332 return false ;
337333 }
338- if textual_octets_to_octet ( current_textual_octet, current_textual_octet_size) > 255
339- {
334+ if radix10_to_octet ( & current[ ..current_size] ) > 255 {
340335 // No octet can be greater than 255.
341336 return false ;
342337 }
343338 // We move on to the next textual octet.
344- current_textual_octet = [ 0 , 0 , 0 ] ;
345- current_textual_octet_size = 0 ;
339+ current = [ 0 , 0 , 0 ] ;
340+ current_size = 0 ;
346341 }
347342 Ok ( number @ b'0' ..=b'9' ) => {
348343 if number == b'0'
349- && current_textual_octet_size == 0
344+ && current_size == 0
350345 && !ip_address. peek ( b'.' )
351346 && !ip_address. at_end ( )
352347 {
353348 // No octet can start with 0 if a dot does not follow and if we are not at the end.
354349 return false ;
355350 }
356- if current_textual_octet_size >= current_textual_octet . len ( ) {
351+ if current_size >= current . len ( ) {
357352 // More than 3 octets in a triple
358353 return false ;
359354 }
360- current_textual_octet [ current_textual_octet_size ] = u8 :: from_be ( number) ;
361- current_textual_octet_size += 1 ;
355+ current [ current_size ] = number - b'0' ;
356+ current_size += 1 ;
362357 }
363358 _ => {
364359 return false ;
@@ -367,9 +362,7 @@ pub(crate) fn is_valid_ipv4_address(ip_address: untrusted::Input) -> bool {
367362 is_first_byte = false ;
368363
369364 if ip_address. at_end ( ) {
370- if current_textual_octet_size > 0
371- && textual_octets_to_octet ( current_textual_octet, current_textual_octet_size) > 255
372- {
365+ if current_size > 0 && radix10_to_octet ( & current[ ..current_size] ) > 255 {
373366 // No octet can be greater than 255.
374367 return false ;
375368 }
0 commit comments