Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: validate integers to prevent overflow #3231

Merged
merged 5 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion psl/builtin-connectors/src/cockroach_datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use native_types::{CockroachType, NativeType};
use psl_core::{
datamodel_connector::{
helper::{arg_vec_from_opt, args_vec_from_opt, parse_one_opt_u32, parse_two_opt_u32},
int_type::IntType,
Connector, ConnectorCapability, ConstraintScope, NativeTypeConstructor, NativeTypeInstance,
ReferentialIntegrity, StringFilter,
},
Expand Down Expand Up @@ -156,7 +157,7 @@ impl Connector for CockroachDatamodelConnector {
// Int
CockroachType::Int2 => ScalarType::Int,
CockroachType::Int4 => ScalarType::Int,
CockroachType::Oid => ScalarType::Int,
CockroachType::Oid => ScalarType::Int, // Unsigned 32-bit int
// BigInt
CockroachType::Int8 => ScalarType::BigInt,
// Float
Expand Down Expand Up @@ -379,6 +380,17 @@ impl Connector for CockroachDatamodelConnector {
}
}
}

fn int_type(&self, native_type: serde_json::Value) -> Option<IntType> {
let nt: CockroachType = serde_json::from_value(native_type).unwrap();

match nt {
CockroachType::Int2 => Some(IntType::Signed16),
CockroachType::Int4 => Some(IntType::Signed32),
CockroachType::Oid => Some(IntType::Unsigned32),
_ => None,
}
}
}

/// An `@default(sequence())` function.
Expand Down
11 changes: 10 additions & 1 deletion psl/builtin-connectors/src/mongodb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use mongodb_types::*;
use native_types::{MongoDbType, NativeType};
use psl_core::{
datamodel_connector::{
Connector, ConnectorCapability, ConstraintScope, NativeTypeConstructor, NativeTypeInstance,
int_type::IntType, Connector, ConnectorCapability, ConstraintScope, NativeTypeConstructor, NativeTypeInstance,
ReferentialIntegrity,
},
diagnostics::{DatamodelError, Diagnostics, Span},
Expand Down Expand Up @@ -132,4 +132,13 @@ impl Connector for MongoDbDatamodelConnector {
fn allowed_referential_integrity_settings(&self) -> enumflags2::BitFlags<ReferentialIntegrity> {
ReferentialIntegrity::Prisma.into()
}

fn int_type(&self, native_type: serde_json::Value) -> Option<IntType> {
let nt: MongoDbType = serde_json::from_value(native_type).unwrap();

match nt {
MongoDbType::Int => Some(IntType::Signed32),
_ => None,
}
}
}
12 changes: 12 additions & 0 deletions psl/builtin-connectors/src/mssql_datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use once_cell::sync::Lazy;
use psl_core::{
datamodel_connector::{
helper::{arg_vec_from_opt, args_vec_from_opt, parse_one_opt_u32, parse_two_opt_u32},
int_type::IntType,
Connector, ConnectorCapability, ConstraintScope, NativeTypeConstructor, NativeTypeInstance,
ReferentialIntegrity,
},
Expand Down Expand Up @@ -438,6 +439,17 @@ impl Connector for MsSqlDatamodelConnector {
});
}
}

fn int_type(&self, native_type: serde_json::Value) -> Option<IntType> {
let nt: MsSqlType = serde_json::from_value(native_type).unwrap();

match nt {
TinyInt => Some(IntType::Unsigned8),
SmallInt => Some(IntType::Signed16),
Int => Some(IntType::Signed32),
_ => None,
}
}
}

/// A collection of types stored outside of the row to the heap, having
Expand Down
19 changes: 19 additions & 0 deletions psl/builtin-connectors/src/mysql_datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use native_types::{
use psl_core::{
datamodel_connector::{
helper::{args_vec_from_opt, parse_one_opt_u32, parse_one_u32, parse_two_opt_u32},
int_type::IntType,
Connector, ConnectorCapability, ConstraintScope, NativeTypeConstructor, NativeTypeInstance,
ReferentialIntegrity,
},
Expand Down Expand Up @@ -405,4 +406,22 @@ impl Connector for MySqlDatamodelConnector {

Ok(())
}

fn int_type(&self, native_type: serde_json::Value) -> Option<IntType> {
let nt: MySqlType = serde_json::from_value(native_type).unwrap();

match nt {
MySqlType::TinyInt => Some(IntType::Signed8),
MySqlType::SmallInt => Some(IntType::Signed16),
MySqlType::MediumInt => Some(IntType::Signed24),
MySqlType::Int => Some(IntType::Signed32),
MySqlType::UnsignedTinyInt => Some(IntType::Unsigned8),
MySqlType::UnsignedSmallInt => Some(IntType::Unsigned16),
MySqlType::UnsignedMediumInt => Some(IntType::Unsigned24),
MySqlType::UnsignedInt => Some(IntType::Unsigned32),
// Technically stored as an Unsigned8 but with values ranging from 1901 and 2155
MySqlType::Year => Some(IntType::Custom(1901, 2155)),
_ => None,
}
}
}
13 changes: 13 additions & 0 deletions psl/builtin-connectors/src/postgres_datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use native_types::{
use psl_core::{
datamodel_connector::{
helper::{arg_vec_from_opt, args_vec_from_opt, parse_one_opt_u32, parse_two_opt_u32},
int_type::IntType,
Connector, ConnectorCapability, ConstraintScope, NativeTypeConstructor, NativeTypeInstance,
ReferentialIntegrity, StringFilter,
},
Expand Down Expand Up @@ -179,6 +180,7 @@ impl Connector for PostgresDatamodelConnector {
//Int
SmallInt => ScalarType::Int,
Integer => ScalarType::Int,
// Unsigned 32-bit int
Oid => ScalarType::Int,
//BigInt
BigInt => ScalarType::BigInt,
Expand Down Expand Up @@ -452,6 +454,17 @@ impl Connector for PostgresDatamodelConnector {
_ => (),
}
}

fn int_type(&self, native_type: serde_json::Value) -> Option<IntType> {
let nt: PostgresType = serde_json::from_value(native_type).unwrap();

match nt {
SmallInt => Some(IntType::Signed16),
Integer => Some(IntType::Signed32),
Oid => Some(IntType::Unsigned32),
_ => None,
}
}
}

fn allowed_index_operator_classes(algo: IndexAlgorithm, field: walkers::ScalarFieldWalker<'_>) -> Vec<OperatorClass> {
Expand Down
6 changes: 5 additions & 1 deletion psl/builtin-connectors/src/sqlite_datamodel_connector.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use enumflags2::BitFlags;
use psl_core::{
datamodel_connector::{
Connector, ConnectorCapability, ConstraintScope, NativeTypeConstructor, NativeTypeInstance,
Connector, ConnectorCapability, ConstraintScope, IntType, NativeTypeConstructor, NativeTypeInstance,
ReferentialIntegrity,
},
diagnostics::{DatamodelError, Span},
Expand Down Expand Up @@ -115,4 +115,8 @@ impl Connector for SqliteDatamodelConnector {

Ok(())
}

fn int_type(&self, _native_type: serde_json::Value) -> Option<IntType> {
None
}
}
7 changes: 7 additions & 0 deletions psl/psl-core/src/datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub mod capabilities;
pub mod constraint_names;
/// Helpers for implementors of `Connector`.
pub mod helper;
/// Type to represent the storage and unsignedness of an integer type.
pub mod int_type;
/// Extensions for parser database walkers with context from the connector.
pub mod walker_ext_traits;

Expand All @@ -19,6 +21,7 @@ pub use self::{
capabilities::{ConnectorCapabilities, ConnectorCapability},
empty_connector::EmptyDatamodelConnector,
filters::*,
int_type::IntType,
native_type_constructor::NativeTypeConstructor,
native_type_instance::NativeTypeInstance,
referential_integrity::ReferentialIntegrity,
Expand Down Expand Up @@ -93,6 +96,10 @@ pub trait Connector: Send + Sync {
self.referential_actions(integrity).contains(action)
}

/// Given a native integer type, returns its storage and unsignedness.
/// Returns `None` if the native type is not an integer.
fn int_type(&self, native_type: serde_json::Value) -> Option<IntType>;

/// This is used by the query engine schema builder.
///
/// For a given scalar type + native type combination, this method should return the name to be
Expand Down
4 changes: 4 additions & 0 deletions psl/psl-core/src/datamodel_connector/empty_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ impl Connector for EmptyDatamodelConnector {
fn validate_url(&self, _url: &str) -> Result<(), String> {
Ok(())
}

fn int_type(&self, _native_type: serde_json::Value) -> Option<IntType> {
None
}
}

#[cfg(test)]
Expand Down
28 changes: 28 additions & 0 deletions psl/psl-core/src/datamodel_connector/int_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#[derive(Debug, Clone, PartialEq)]
pub enum IntType {
Signed8,
Signed16,
Signed24,
Signed32,
Unsigned8,
Unsigned16,
Unsigned24,
Unsigned32,
Custom(i64, i64),
}

impl std::fmt::Display for IntType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
IntType::Signed8 => f.write_str("8-bit signed integer"),
IntType::Signed16 => f.write_str("16-bit signed integer"),
IntType::Signed24 => f.write_str("24-bit signed integer"),
IntType::Signed32 => f.write_str("32-bit signed integer"),
IntType::Unsigned8 => f.write_str("8-bit unsigned integer"),
IntType::Unsigned16 => f.write_str("16-bit unsigned integer"),
IntType::Unsigned24 => f.write_str("24-bit unsigned integer"),
IntType::Unsigned32 => f.write_str("32-bit unsigned integer"),
IntType::Custom(min, max) => write!(f, "custom integer (min: {}, max: {})", min, max),
}
}
}