Skip to content
Permalink
Browse files

Validate decoded hex length is even

  • Loading branch information...
CodeSandwich committed May 15, 2019
1 parent cee51f9 commit 314bdc97c868c38cdecb34a7d9aa9031f41c1969
Showing with 54 additions and 23 deletions.
  1. +54 −23 chain-crypto/src/hex.rs
@@ -24,6 +24,8 @@ pub enum DecodeError {
/// A character was encountered is not part of the supported
/// hexadecimal alphabet. Contains the index of the faulty byte.
InvalidHexChar(usize),
/// Length of hex string is not even. Last character doesn't have a pair to encode a whole byte.
UnevenHexLength(usize),
}

impl fmt::Display for DecodeError {
@@ -32,6 +34,9 @@ impl fmt::Display for DecodeError {
DecodeError::InvalidHexChar(idx) => {
write!(f, "Non-hexadecimal character at byte index {}", idx)
}
DecodeError::UnevenHexLength(len) => {
write!(f, "Hex has uneven number of characters {}", len)
}
}
}
}
@@ -69,42 +74,68 @@ fn decode_bytes(input: &[u8]) -> Result<Vec<u8>, DecodeError> {
b.push(buf);
}
}

Ok(b)
match modulus {
0 => Ok(b),
_ => Err(DecodeError::UnevenHexLength(b.len() * 2 + 1)),
}
}

#[cfg(test)]
mod tests {
fn encode<D: AsRef<[u8]>>(input: D, expected: &str) {
let encoded = super::encode(input);
assert_eq!(encoded, expected);
}
fn decode<S: AsRef<[u8]>>(expected: &[u8], input: S) {
let decoded = super::decode(input).unwrap();
assert_eq!(decoded.as_slice(), expected);
use super::*;

fn assert_decode(input: impl AsRef<[u8]>, expected: impl AsRef<[u8]>) {
let result = decode(&input);

let input_str = format!("{:?}", input.as_ref());
let actual = result.expect(&format!("Failed to decode '{}'", input_str));
assert_eq!(
actual,
expected.as_ref(),
"Decoded invalid data from '{}'",
input_str
);
}

#[test]
fn test_vector_1() {
encode(&[1, 2, 3, 4], "01020304");
decode(&[1, 2, 3, 4], "01020304");
fn refute_decode(input: impl AsRef<[u8]>, expected: DecodeError) {
let result = decode(&input);

let input_str = format!("{:?}", input.as_ref());
let actual = result.expect_err(&format!("Did not fail to decode '{}'", input_str));
assert_eq!(
actual, expected,
"Invalid error when decoding '{}'",
input_str
);
}

#[test]
fn test_vector_2() {
encode(&[0xff, 0x0f, 0xff, 0xff], "ff0fffff");
decode(&[0xff, 0x0f, 0xff, 0xff], "ff0fffff");
fn test_decode() {
assert_decode("01020304", [0x01, 0x02, 0x03, 0x04]);
assert_decode(b"01020304", [0x01, 0x02, 0x03, 0x04]);
assert_decode("0123456789", [0x01, 0x23, 0x45, 0x67, 0x89]);
assert_decode("abcdef", [0xAB, 0xCD, 0xEF]);
assert_decode("ABCDEF", [0xAB, 0xCD, 0xEF]);
assert_decode(" 0\t\r102 \n", [0x01, 0x02]);
refute_decode("010x0304", DecodeError::InvalidHexChar(3));
refute_decode("0102030", DecodeError::UnevenHexLength(7));
}

#[test]
fn test_bytes() {
encode(&[1, 2, 3, 4], "01020304");
decode(&[1, 2, 3, 4], b"01020304");
fn assert_encode(input: impl AsRef<[u8]>, expected: &str) {
let actual = encode(&input);

assert_eq!(
actual,
expected,
"Invalid output for input {:?}",
input.as_ref()
);
}

#[test]
fn test_string() {
encode("1234", "31323334");
decode(&[1, 2, 3, 4], "01020304");
fn test_encode() {
assert_encode([0x01, 0x02, 0x03, 0x04], "01020304");
assert_encode([0x01, 0x23, 0x45, 0x67, 0x89], "0123456789");
assert_encode([0xAB, 0xCD, 0xEF], "abcdef");
}
}

0 comments on commit 314bdc9

Please sign in to comment.
You can’t perform that action at this time.