Skip to content

Commit 90ae34c

Browse files
committed
add test to cover err scenario
1 parent 7dd5a3d commit 90ae34c

File tree

1 file changed

+74
-48
lines changed

1 file changed

+74
-48
lines changed

lightning/src/ln/msgs.rs

+74-48
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ impl Readable for NetAddress {
906906

907907
/// NetAddress error variants
908908
#[cfg(feature = "std")]
909-
#[derive(Debug)]
909+
#[derive(Debug, Eq, PartialEq, Clone)]
910910
pub enum NetAddressError {
911911
/// Socket address(IPv4/IPv6) parsing error
912912
SocketAdrrParseError(std::net::AddrParseError),
@@ -920,24 +920,24 @@ pub enum NetAddressError {
920920

921921
#[cfg(feature = "std")]
922922
impl FromStr for NetAddress {
923-
type Err = NetAddressError;
924-
925-
fn from_str(s: &str) -> Result<Self, Self::Err> {
926-
match std::net::SocketAddr::from_str(s) {
927-
Ok(addr) => {
928-
let port: u16 = addr.port();
929-
match addr {
930-
std::net::SocketAddr::V4(addr) => {
931-
let addr = addr.ip().octets();
932-
return Ok(NetAddress::IPv4 { addr, port });
933-
},
934-
std::net::SocketAddr::V6(addr) => {
935-
let addr = addr.ip().octets();
936-
return Ok(NetAddress::IPv6 { addr, port });
937-
},
938-
}
939-
},
940-
Err(e) => {
923+
type Err = NetAddressError;
924+
925+
fn from_str(s: &str) -> Result<Self, Self::Err> {
926+
match std::net::SocketAddr::from_str(s) {
927+
Ok(addr) => {
928+
let port: u16 = addr.port();
929+
match addr {
930+
std::net::SocketAddr::V4(addr) => {
931+
let addr = addr.ip().octets();
932+
return Ok(NetAddress::IPv4 { addr, port });
933+
},
934+
std::net::SocketAddr::V6(addr) => {
935+
let addr = addr.ip().octets();
936+
return Ok(NetAddress::IPv6 { addr, port });
937+
},
938+
}
939+
},
940+
Err(e) => {
941941
let trimmed_input = match s.rfind(":") {
942942
Some(pos) => pos,
943943
None => return Err(NetAddressError::InvalidInput("Invalid input. Expected format: \"<host>:<port>\"" .to_string())),
@@ -947,36 +947,48 @@ impl FromStr for NetAddress {
947947
Ok(port) => port,
948948
Err(_) => return Err(NetAddressError::InvalidPort),
949949
};
950-
if host.ends_with(".onion") {
951-
let onion = match host.split(".onion").nth(0) {
952-
Some(onion) => onion,
953-
None => return Err(NetAddressError::InvalidOnionV3),
954-
};
955-
let onion = match (base32::Alphabet::RFC4648 { padding: false }.decode(&onion)) {
956-
Ok(onion) => onion,
957-
Err(_) => return Err(NetAddressError::InvalidOnionV3),
958-
};
959-
match (onion.get(0), onion.get(1), onion.get(2)) {
960-
(Some(version), Some(first_checksum_flag), Some(second_checksum_flag)) => {
961-
let checksum = u16::from_be_bytes([*first_checksum_flag, *second_checksum_flag]);
962-
let ed25519_pubkey = match onion[3..35].try_into() {
963-
Ok(ed25519_pubkey) => ed25519_pubkey,
964-
Err(_) => return Err(NetAddressError::InvalidOnionV3),
965-
};
966-
return Ok(NetAddress::OnionV3 { ed25519_pubkey, checksum, version: *version, port });
967-
950+
let host: Vec<&str> = host.split(".").collect();
951+
if host.len() == 2 {
952+
match (host.get(0), host.get(1)) {
953+
(Some(domain), Some(suffix)) => {
954+
if suffix.to_string() == "onion".to_owned() {
955+
if domain.len() != 56 {
956+
return Err(NetAddressError::InvalidOnionV3);
957+
}
958+
let onion = match (base32::Alphabet::RFC4648 { padding: false }.decode(&domain)) {
959+
Ok(onion) => onion,
960+
Err(_) => return Err(NetAddressError::InvalidOnionV3),
961+
};
962+
if onion.len() < 35 {
963+
return Err(NetAddressError::InvalidOnionV3);
964+
}
965+
match (onion.get(0), onion.get(1), onion.get(2)) {
966+
(Some(version), Some(first_checksum_flag), Some(second_checksum_flag)) => {
967+
let checksum = u16::from_be_bytes([*first_checksum_flag, *second_checksum_flag]);
968+
let ed25519_pubkey = match onion[3..35].try_into() {
969+
Ok(ed25519_pubkey) => ed25519_pubkey,
970+
Err(_) => return Err(NetAddressError::InvalidOnionV3),
971+
};
972+
return Ok(NetAddress::OnionV3 { ed25519_pubkey, checksum, version: *version, port });
973+
974+
},
975+
_ => return Err(NetAddressError::InvalidOnionV3),
976+
}
977+
} else {
978+
if let Ok(hostname) = Hostname::try_from(s[..trimmed_input].to_string()) {
979+
return Ok(NetAddress::Hostname { hostname, port });
980+
} else {
981+
return Err(NetAddressError::InvalidInput("Invalid input. Expected format: \"<host>:<port>\"" .to_string()));
982+
}
983+
}
968984
},
969-
_ => return Err(NetAddressError::InvalidOnionV3),
970-
}
971-
}
972-
973-
if let Ok(hostname) = Hostname::try_from(host.to_string()) {
974-
return Ok(NetAddress::Hostname { hostname, port });
975-
}
976-
return Err(NetAddressError::SocketAdrrParseError(e))
977-
},
978-
}
979-
}
985+
_ => return Err(NetAddressError::SocketAdrrParseError(e))
986+
};
987+
}
988+
return Err(NetAddressError::SocketAdrrParseError(e))
989+
},
990+
}
991+
}
980992
}
981993

982994
/// Represents the set of gossip messages that require a signature from a node's identity key.
@@ -3854,21 +3866,35 @@ mod tests {
38543866
addr: Ipv4Addr::new(127, 0, 0, 1).octets(),
38553867
port: 1234,
38563868
}, NetAddress::from_str("127.0.0.1:1234").unwrap());
3869+
38573870
assert_eq!(NetAddress::IPv6 {
38583871
addr : Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).octets(),
38593872
port: 1234,
38603873
}, NetAddress::from_str("[0:0:0:0:0:0:0:1]:1234").unwrap());
3874+
38613875
assert_eq!(
38623876
NetAddress::Hostname {
38633877
hostname : Hostname::try_from("example.com".to_string()).unwrap(),
38643878
port: 1234,
38653879
} , NetAddress::from_str("example.com:1234").unwrap());
3880+
38663881
assert_eq!(NetAddress::OnionV3 {
38673882
ed25519_pubkey: [37, 24, 75, 5, 25, 73, 117, 194, 139, 102, 182, 107, 4, 105, 247, 246, 85,
38683883
111, 177, 172, 49, 137, 167, 155, 64, 221, 163, 47, 31, 33, 71, 3],
38693884
checksum: 48326,
38703885
version: 121,
38713886
port: 1234
38723887
}, NetAddress::from_str( "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion:1234").unwrap());
3888+
3889+
let invalid_onion_address = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6.onion:1234";
3890+
assert_eq!(super::NetAddressError::InvalidOnionV3, NetAddress::from_str(invalid_onion_address).unwrap_err().into());
3891+
3892+
assert_eq!(super::NetAddressError::InvalidInput("Invalid input. Expected format: \"<host>:<port>\"" .to_string()), NetAddress::from_str("127.0.0.1@1234").unwrap_err().into());
3893+
3894+
assert!(NetAddress::from_str("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion.onion:9735:94").is_err());
3895+
3896+
assert_eq!(super::NetAddressError::InvalidInput("Invalid input. Expected format: \"<host>:<port>\"" .to_string()), NetAddress::from_str("wrong$%#.com:1234").unwrap_err().into());
3897+
3898+
assert_eq!(super::NetAddressError::InvalidPort, NetAddress::from_str("example.com:wrong").unwrap_err().into());
38733899
}
38743900
}

0 commit comments

Comments
 (0)