sqlx icon indicating copy to clipboard operation
sqlx copied to clipboard

PgNumeric::decode panics

Open marcustut opened this issue 2 years ago • 0 comments

Bug Description

I have a SQL table as follows:

CREATE TABLE compute.instance_types (
    name TEXT,
    description TEXT,
    hourly_rate NUMERIC NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (name)
);

I use query_as! that takes the following struct

    #[derive(Debug, Clone, Serialize, Deserialize)]
    pub struct InstanceType {
        pub name: String,
        pub description: Option<String>,
        pub hourly_rate: Decimal,
        pub updated_at: DateTime<Utc>,
        pub created_at: DateTime<Utc>,
    }

when I do the following query, I get the panic below

sqlx::query_as!(InstanceType, "SELECT * FROM compute.instance_types",)
    .fetch_all(&self.pg)
| thread 'tokio-runtime-worker' panicked at /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/bytes-1.5.0/src/buf/buf_impl.rs:254:9:                            │
│ assertion failed: self.remaining() >= dst.len()                                                                                                                            │
│ stack backtrace:                                                                                                                                                           │
│    0: rust_begin_unwind                                                                                                                                                    │
│              at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5                                                                        │
│    1: core::panicking::panic_fmt                                                                                                                                           │
│              at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14                                                                       │
│    2: core::panicking::panic                                                                                                                                               │
│              at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:127:5                                                                       │
│    3: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter                                                                                     │
│    4: sqlx_postgres::types::numeric::PgNumeric::decode                                                                                                                     │
│    5: sqlx_postgres::types::rust_decimal::<impl sqlx_core::decode::Decode<sqlx_postgres::database::Postgres> for rust_decimal::decimal::Decimal>::decode                   │
│    6: sqlx_core::row::Row::try_get_unchecked                                                                                                                               │
│    7: sqlx_core::query::Map<DB,F,A>::fetch_many::{{closure}}::{{closure}}

I did a little digging and I suspect that the panic was triggered by this line in sqlx-postgres/src/types/numeric.rs

let digits: Vec<_> = (0..num_digits).map(|_| buf.get_i16()).collect::<_>();

somehow the buf.get_i16() call ran out of bytes to advance and panics as mentioned here

Are there any solution to this? Or does this occur to anyone using rust_decimal?

Info

  • SQLx version: 0.7.3
  • SQLx features enabled: [ "runtime-tokio", "tls-native-tls", "postgres", "chrono", "uuid", "rust_decimal", ]
  • Database server and version: Postgres 16.1-1.pgdg110+1
  • Operating system: Linux Arm64
  • rustc --version: rust 1.75.0

marcustut avatar Jan 25 '24 21:01 marcustut