From 534c5d391ba2ad867b38314d230edf091bd8dbab Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 13 Oct 2024 07:26:50 +0200 Subject: [PATCH] Safely and correctly convert InetAddress to IpAddr Removes use of unsafe code for conversion and implicitly fixes endianess issues in conversion. Fixes #1535 --- gio/src/inet_address.rs | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/gio/src/inet_address.rs b/gio/src/inet_address.rs index 86ea89ee1a33..e5d413accf98 100644 --- a/gio/src/inet_address.rs +++ b/gio/src/inet_address.rs @@ -1,6 +1,6 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::net::IpAddr; use glib::{prelude::*, translate::*}; @@ -80,16 +80,33 @@ impl From for InetAddress { impl From for IpAddr { fn from(addr: InetAddress) -> Self { - let size = addr.native_size(); - unsafe { - let bytes = ffi::g_inet_address_to_bytes(addr.to_glib_none().0); - if size == 4 { - Self::V4(Ipv4Addr::from(*(bytes as *const [u8; 4]))) - } else if size == 16 { - Self::V6(Ipv6Addr::from(*(bytes as *const [u16; 8]))) - } else { - panic!("Unknown IP kind"); - } + match addr.to_bytes() { + Some(InetAddressBytes::V4(bytes)) => IpAddr::from(*bytes), + Some(InetAddressBytes::V6(bytes)) => IpAddr::from(*bytes), + None => panic!("Unknown IP kind"), } } } + +#[cfg(test)] +mod tests { + use std::net::IpAddr; + + use crate::InetAddress; + + #[test] + fn test_ipv6_to_rust() { + let rust_addr = "2606:50c0:8000::153".parse::().unwrap(); + assert!(rust_addr.is_ipv6()); + let gio_addr = InetAddress::from(rust_addr); + assert_eq!(rust_addr, IpAddr::from(gio_addr)); + } + + #[test] + fn test_ipv4_to_rust() { + let rust_addr = "185.199.108.153".parse::().unwrap(); + assert!(rust_addr.is_ipv4()); + let gio_addr = InetAddress::from(rust_addr); + assert_eq!(rust_addr, IpAddr::from(gio_addr)); + } +}