Skip to content

Commit 924d0e5

Browse files
authored
Merge pull request #1197 from allan2/time-overflow
Fix time 0.3 infinity panics
2 parents f1c5c4f + 9754f13 commit 924d0e5

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

postgres-types/src/time_03.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ fn base() -> PrimitiveDateTime {
1313
impl<'a> FromSql<'a> for PrimitiveDateTime {
1414
fn from_sql(_: &Type, raw: &[u8]) -> Result<PrimitiveDateTime, Box<dyn Error + Sync + Send>> {
1515
let t = types::timestamp_from_sql(raw)?;
16-
Ok(base() + Duration::microseconds(t))
16+
Ok(base()
17+
.checked_add(Duration::microseconds(t))
18+
.ok_or("value too large to decode")?)
1719
}
1820

1921
accepts!(TIMESTAMP);
@@ -62,7 +64,10 @@ impl ToSql for OffsetDateTime {
6264
impl<'a> FromSql<'a> for Date {
6365
fn from_sql(_: &Type, raw: &[u8]) -> Result<Date, Box<dyn Error + Sync + Send>> {
6466
let jd = types::date_from_sql(raw)?;
65-
Ok(base().date() + Duration::days(i64::from(jd)))
67+
Ok(base()
68+
.date()
69+
.checked_add(Duration::days(i64::from(jd)))
70+
.ok_or("value too large to decode")?)
6671
}
6772

6873
accepts!(DATE);

tokio-postgres/tests/test/types/time_03.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
use std::fmt;
2+
3+
use postgres_types::FromSqlOwned;
14
use time_03::{format_description, OffsetDateTime, PrimitiveDateTime};
2-
use tokio_postgres::types::{Date, Timestamp};
5+
use tokio_postgres::{
6+
types::{Date, Timestamp},
7+
Client,
8+
};
39

410
use crate::types::test_type;
511

@@ -147,3 +153,33 @@ async fn test_time_params() {
147153
)
148154
.await;
149155
}
156+
157+
#[tokio::test]
158+
async fn test_special_params_without_wrapper() {
159+
async fn assert_overflows<T>(client: &mut Client, val: &str, sql_type: &str)
160+
where
161+
T: FromSqlOwned + fmt::Debug,
162+
{
163+
let err = client
164+
.query_one(&*format!("SELECT {}::{}", val, sql_type), &[])
165+
.await
166+
.unwrap()
167+
.try_get::<_, T>(0)
168+
.unwrap_err();
169+
assert_eq!(
170+
err.to_string(),
171+
"error deserializing column 0: value too large to decode"
172+
);
173+
}
174+
175+
let mut client = crate::connect("user=postgres").await;
176+
177+
assert_overflows::<OffsetDateTime>(&mut client, "'-infinity'", "timestamptz").await;
178+
assert_overflows::<OffsetDateTime>(&mut client, "'infinity'", "timestamptz").await;
179+
180+
assert_overflows::<PrimitiveDateTime>(&mut client, "'-infinity'", "timestamp").await;
181+
assert_overflows::<PrimitiveDateTime>(&mut client, "'infinity'", "timestamp").await;
182+
183+
assert_overflows::<time_03::Date>(&mut client, "'-infinity'", "date").await;
184+
assert_overflows::<time_03::Date>(&mut client, "'infinity'", "date").await;
185+
}

0 commit comments

Comments
 (0)