Skip to content

Commit 401ece5

Browse files
committed
fix: ipnet not decoding IP address strings
1 parent a706674 commit 401ece5

File tree

3 files changed

+19
-8
lines changed

3 files changed

+19
-8
lines changed

sqlx-postgres/src/types/ipnet/ipaddr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ where
5151
fn decode(value: PgValueRef<'db>) -> Result<Self, BoxDynError> {
5252
let ipnet = IpNet::decode(value)?;
5353

54-
if matches!(ipnet, IpNet::V4(_)) && ipnet.prefix_len() != 32
55-
|| matches!(ipnet, IpNet::V6(_)) && ipnet.prefix_len() != 128
54+
if matches!(ipnet, IpNet::V4(net) if net.prefix_len() != 32)
55+
|| matches!(ipnet, IpNet::V6(net) if net.prefix_len() != 128)
5656
{
5757
Err("lossy decode from inet/cidr")?
5858
}

sqlx-postgres/src/types/ipnet/ipnet.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::net::{Ipv4Addr, Ipv6Addr};
1+
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
22

33
#[cfg(feature = "ipnet")]
44
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
@@ -75,7 +75,14 @@ impl Decode<'_, Postgres> for IpNet {
7575
let bytes = match value.format() {
7676
PgValueFormat::Binary => value.as_bytes()?,
7777
PgValueFormat::Text => {
78-
return Ok(value.as_str()?.parse()?);
78+
let s = value.as_str()?;
79+
println!("{s}");
80+
if s.contains('/') {
81+
return Ok(s.parse()?);
82+
}
83+
// IpNet::from_str doesn't handle conversion from IpAddr to IpNet
84+
let addr: IpAddr = s.parse()?;
85+
return Ok(addr.into());
7986
}
8087
};
8188

tests/postgres/types.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ extern crate time_ as time;
22

33
use std::net::SocketAddr;
44
use std::ops::Bound;
5+
use std::str::FromStr;
56

67
use sqlx::postgres::types::{Oid, PgCiText, PgInterval, PgMoney, PgRange};
78
use sqlx::postgres::Postgres;
89
use sqlx_test::{new, test_decode_type, test_prepared_type, test_type};
910

1011
use sqlx_core::executor::Executor;
1112
use sqlx_core::types::Text;
12-
use std::str::FromStr;
1313

1414
test_type!(null<Option<i16>>(Postgres,
1515
"NULL::int2" == None::<i16>
@@ -174,15 +174,19 @@ test_type!(uuid_vec<Vec<sqlx::types::Uuid>>(Postgres,
174174
#[cfg(feature = "ipnet")]
175175
test_type!(ipnet<sqlx::types::ipnet::IpNet>(Postgres,
176176
"'127.0.0.1'::inet"
177-
== "127.0.0.1"
177+
== "127.0.0.1/32"
178178
.parse::<sqlx::types::ipnet::IpNet>()
179179
.unwrap(),
180180
"'8.8.8.8/24'::inet"
181181
== "8.8.8.8/24"
182182
.parse::<sqlx::types::ipnet::IpNet>()
183183
.unwrap(),
184+
"'10.1.1/24'::inet"
185+
== "10.1.1.0/24"
186+
.parse::<sqlx::types::ipnet::IpNet>()
187+
.unwrap(),
184188
"'::ffff:1.2.3.0'::inet"
185-
== "::ffff:1.2.3.0"
189+
== "::ffff:1.2.3.0/128"
186190
.parse::<sqlx::types::ipnet::IpNet>()
187191
.unwrap(),
188192
"'2001:4f8:3:ba::/64'::inet"
@@ -264,7 +268,7 @@ test_type!(bitvec<sqlx::types::BitVec>(
264268
test_type!(ipnet_vec<Vec<sqlx::types::ipnet::IpNet>>(Postgres,
265269
"'{127.0.0.1,8.8.8.8/24}'::inet[]"
266270
== vec![
267-
"127.0.0.1".parse::<sqlx::types::ipnet::IpNet>().unwrap(),
271+
"127.0.0.1/32".parse::<sqlx::types::ipnet::IpNet>().unwrap(),
268272
"8.8.8.8/24".parse::<sqlx::types::ipnet::IpNet>().unwrap()
269273
]
270274
));

0 commit comments

Comments
 (0)