From 9de593a0e576489c460c1ac0bb89a3bbbd2adee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Hatcher?= <161827182+nhatcher-frequenz@users.noreply.github.com> Date: Sat, 5 Jul 2025 01:51:43 +0200 Subject: [PATCH] fix[sqlx-postgres]: do a checked_mul to prevent panic when casting from db (#3919) --- sqlx-postgres/src/types/rust_decimal.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sqlx-postgres/src/types/rust_decimal.rs b/sqlx-postgres/src/types/rust_decimal.rs index 549043d9..d679ae91 100644 --- a/sqlx-postgres/src/types/rust_decimal.rs +++ b/sqlx-postgres/src/types/rust_decimal.rs @@ -62,7 +62,9 @@ impl TryFrom<&'_ PgNumeric> for Decimal { .checked_powi(weight as i64) .ok_or("value not representable as rust_decimal::Decimal")?; - let part = Decimal::from(digit) * mul; + let part = Decimal::from(digit) + .checked_mul(mul) + .ok_or("value not representable as rust_decimal::Decimal")?; value = value .checked_add(part) @@ -383,6 +385,19 @@ mod tests { assert_eq!(actual_decimal.scale(), 0); } + #[test] + fn mult_overflow() { + // -24_0711_6702_1036_7100_2022_8579_3280.00 + let large_negative_number = PgNumeric::Number { + sign: PgNumericSign::Negative, + scale: 0, + weight: 7, + digits: vec![24, 0711, 6702, 1036, 7100, 2022, 8579, 3280], + }; + + assert!(Decimal::try_from(large_negative_number).is_err()); + } + #[test] fn max_value_max_scale() { let mut max_value_max_scale = Decimal::MAX;