paupino / rust-decimal

Decimal number implementation written in pure Rust suitable for financial and fixed-precision calculations.
https://docs.rs/rust_decimal/
MIT License
972 stars 177 forks source link

Prevent scale of 29 when hydrating from unbound numeric data types in Postgresql #647

Closed paupino closed 6 months ago

paupino commented 6 months ago

This fixes #645

The way this fixes things is to avoid scale of 29 being represented internally via the postgres driver. A scale of 29, while technically available in some very minimal use cases is considered undefined behavior in rust-decimal and typically guarded against (i.e. it's very difficult, if not impossible, to reproduce this without going through the postgres driver).

Consequently, applying a ceiling to the rescale operation in this case is appropriate.

Added a couple of tests which both fail without the fix (i.e. reproducing the bug):

---- postgres::driver::test::read_small_unconstrained_numeric_type_addition stdout ----
thread 'postgres::driver::test::read_small_unconstrained_numeric_type_addition' panicked at src/postgres/driver.rs:292:9:
assertion `left == right` failed
  left: 10000000000014780214000000000
 right: 0.1000000000001478021400000000
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- postgres::driver::test::read_small_unconstrained_numeric_type stdout ----
thread 'postgres::driver::test::read_small_unconstrained_numeric_type' panicked at src/postgres/driver.rs:271:9:
assertion `left == right` failed
  left: "0.10000000000000000000000000000"
 right: "0.1000000000000000000000000000"