Skip to content

Commit 2c4dbc0

Browse files
committed
textual_octets_to_octet: simplify and satisfy clippy
Seems better to convert from ascii to radix-10 at the time that is known, rather than doing that validation twice (and skipping a digit as an error handling strategy).
1 parent f39e0b4 commit 2c4dbc0

File tree

1 file changed

+15
-22
lines changed

1 file changed

+15
-22
lines changed

src/name/ip_address.rs

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -296,22 +296,18 @@ pub(super) fn presented_id_matches_constraint(
296296
pub(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

Comments
 (0)