Skip to content

Commit

Permalink
more overflow errors
Browse files Browse the repository at this point in the history
  • Loading branch information
lovasoa committed Aug 16, 2024
1 parent eb7f6a4 commit 6b17f07
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 17 deletions.
22 changes: 12 additions & 10 deletions sqlx-core/src/postgres/types/bigdecimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ impl TryFrom<PgNumeric> for BigDecimal {
// no optimized algorithm for base-10 so use base-100 for faster processing
let mut cents = Vec::with_capacity(digits.len() * 2);
for digit in &digits {
cents.push((digit / 100) as u8);
cents.push((digit % 100) as u8);
cents.push(u8::try_from(digit / 100).unwrap());
cents.push(u8::try_from(digit % 100).unwrap());
}

let bigint = BigInt::from_radix_be(sign, &cents, 100)
Expand All @@ -83,7 +83,7 @@ impl TryFrom<&'_ BigDecimal> for PgNumeric {

// weight is positive power of 10000
// exp is the negative power of 10
let weight_10 = base_10.len() as i64 - exp;
let weight_10 = i64::try_from(base_10.len())? - exp;

// scale is only nonzero when we have fractional digits
// since `exp` is the _negative_ decimal exponent, it tells us
Expand All @@ -105,7 +105,7 @@ impl TryFrom<&'_ BigDecimal> for PgNumeric {
base_10.len() / 4
};

let offset = weight_10.rem_euclid(4) as usize;
let offset = usize::try_from(weight_10.rem_euclid(4))?;

let mut digits = Vec::with_capacity(digits_len);

Expand All @@ -114,14 +114,16 @@ impl TryFrom<&'_ BigDecimal> for PgNumeric {
digits.push(base_10_to_10000(first));
}
} else if offset != 0 {
digits.push(base_10_to_10000(&base_10) * 10i16.pow((offset - base_10.len()) as u32));
digits.push(
base_10_to_10000(&base_10) * 10i16.pow(u32::try_from(offset - base_10.len())?),
);
}

if let Some(rest) = base_10.get(offset..) {
digits.extend(
rest.chunks(4)
.map(|chunk| base_10_to_10000(chunk) * 10i16.pow(4 - chunk.len() as u32)),
);
digits.extend(rest.chunks(4).map(|chunk| {
base_10_to_10000(chunk)
* 10i16.pow(4 - u32::try_from(chunk.len()).unwrap_or(u32::MAX))
}));
}

while let Some(&0) = digits.last() {
Expand Down Expand Up @@ -154,7 +156,7 @@ impl Encode<'_, Postgres> for BigDecimal {
fn size_hint(&self) -> usize {
// BigDecimal::digits() gives us base-10 digits, so we divide by 4 to get base-10000 digits
// and since this is just a hint we just always round up
8 + (self.digits() / 4 + 1) as usize * 2
8 + usize::try_from(self.digits() / 4 + 1).unwrap() * 2
}
}

Expand Down
14 changes: 7 additions & 7 deletions sqlx-core/src/postgres/types/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ impl TryFrom<PgNumeric> for Decimal {
};

// weight is 0 if the decimal point falls after the first base-10000 digit
let scale = (digits.len() as i64 - weight as i64 - 1) * 4;
let scale = (i64::try_from(digits.len())? - i64::from(weight) - 1) * 4;

// no optimized algorithm for base-10 so use base-100 for faster processing
let mut cents = Vec::with_capacity(digits.len() * 2);
for digit in &digits {
cents.push((digit / 100) as u8);
cents.push((digit % 100) as u8);
cents.push(u8::try_from(digit / 100)?);
cents.push(u8::try_from(digit % 100)?);
}

let bigint = BigInt::from_radix_be(sign, &cents, 100)
Expand All @@ -69,11 +69,11 @@ impl TryFrom<PgNumeric> for Decimal {
// A negative scale, meaning we have nothing on the right and must
// add zeroes to the left.
(Some(num), scale) if scale < 0 => Ok(Decimal::from_i128_with_scale(
num * 10i128.pow(scale.abs() as u32),
num * 10i128.pow(u32::try_from(scale.abs())?),
0,
)),
// A positive scale, so we have decimals on the right.
(Some(num), _) => Ok(Decimal::from_i128_with_scale(num, scale as u32)),
(Some(num), _) => Ok(Decimal::from_i128_with_scale(num, u32::try_from(scale)?)),
(None, _) => Err("Decimal's integer part out of range.".into()),
}
}
Expand Down Expand Up @@ -111,8 +111,8 @@ impl TryFrom<&'_ Decimal> for PgNumeric {
// multiple.
let groups_diff = scale % 4;
if groups_diff > 0 {
let remainder = 4 - groups_diff as u32;
let power = 10u32.pow(remainder as u32) as u128;
let remainder = 4 - groups_diff;
let power = 10u32.pow(remainder) as u128;

mantissa *= power;
}
Expand Down

0 comments on commit 6b17f07

Please sign in to comment.