Coverage Report

Created: 2026-03-31 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aws-lc-rs-1.16.2/src/hex.rs
Line
Count
Source
1
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
// SPDX-License-Identifier: Apache-2.0 OR ISC
3
4
/// Converts bytes to a lower-case hex string
5
#[allow(clippy::missing_panics_doc)]
6
0
pub fn encode<T: AsRef<[u8]>>(bytes: T) -> String {
7
0
    let bytes = bytes.as_ref();
8
0
    let mut encoding = String::with_capacity(2 * bytes.len());
9
0
    for byte in bytes {
10
0
        let upper_val = byte >> 4u8;
11
0
        let lower_val = byte & 0x0f;
12
0
        // DON'T PANIC: it shouldn't be possible to panic because only bottom 4 bits can be set.
13
0
        encoding.push(char::from_digit(u32::from(upper_val), 16).unwrap());
14
0
        encoding.push(char::from_digit(u32::from(lower_val), 16).unwrap());
15
0
    }
16
0
    encoding
17
0
}
Unexecuted instantiation: aws_lc_rs::hex::encode::<[u8; 32]>
Unexecuted instantiation: aws_lc_rs::hex::encode::<&aws_lc_rs::ed25519::PublicKey>
Unexecuted instantiation: aws_lc_rs::hex::encode::<&[u8]>
18
19
/// Converts bytes to an upper-case hex string
20
0
pub fn encode_upper<T: AsRef<[u8]>>(bytes: T) -> String {
21
0
    encode(bytes).to_ascii_uppercase()
22
0
}
23
24
/// Converts a hex string to a vector of bytes
25
/// # Errors
26
/// Returns an error if `hex_str` contains a non-hex digit.
27
#[allow(clippy::missing_panics_doc)]
28
0
pub fn decode(hex_str: &str) -> Result<Vec<u8>, String> {
29
0
    let mut bytes = Vec::<u8>::with_capacity(hex_str.len() / 2 + 1);
30
0
    let mut current_byte = b'\0';
31
0
    let mut index: u32 = 0;
32
0
    for ch in hex_str.chars() {
33
0
        if !ch.is_ascii_hexdigit() {
34
0
            return Err("Invalid hex string".to_string());
35
0
        }
36
        #[allow(clippy::cast_possible_truncation)]
37
        // DON'T PANIC: it should not be possible to panic because we verify above that the character is a
38
        // hex digit.
39
0
        let value = ch.to_digit(16).unwrap() as u8;
40
0
        if index % 2 == 0 {
41
0
            current_byte = value << 4;
42
0
        } else {
43
0
            current_byte |= value;
44
0
            bytes.push(current_byte);
45
0
        }
46
47
0
        if let Some(idx) = index.checked_add(1) {
48
0
            index = idx;
49
0
        } else {
50
0
            break;
51
        }
52
    }
53
0
    if index % 2 == 1 {
54
0
        bytes.push(current_byte);
55
0
    }
56
0
    Ok(bytes)
57
0
}
58
59
/// Converts a hex string to a vector of bytes.
60
/// It ignores any characters that are not valid hex digits.
61
#[must_use]
62
#[allow(clippy::missing_panics_doc)]
63
0
pub fn decode_dirty(hex_str: &str) -> Vec<u8> {
64
0
    let clean: String = hex_str.chars().filter(char::is_ascii_hexdigit).collect();
65
    // DON'T PANIC: it should not be possible to panic because we filter out all non-hex digits.
66
0
    decode(clean.as_str()).unwrap()
67
0
}