mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 14:34:19 +00:00
fix(mysql): handle MySQL sending more or less bytes than we expect for an integer type
This commit is contained in:
parent
e5a7619344
commit
e9a562f89a
2 changed files with 54 additions and 54 deletions
|
@ -1,3 +1,5 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
use crate::decode::Decode;
|
||||
|
@ -7,17 +9,6 @@ use crate::mysql::protocol::text::{ColumnFlags, ColumnType};
|
|||
use crate::mysql::{MySql, MySqlTypeInfo, MySqlValueFormat, MySqlValueRef};
|
||||
use crate::types::Type;
|
||||
|
||||
fn int_accepts(ty: &MySqlTypeInfo) -> bool {
|
||||
matches!(
|
||||
ty.r#type,
|
||||
ColumnType::Tiny
|
||||
| ColumnType::Short
|
||||
| ColumnType::Long
|
||||
| ColumnType::Int24
|
||||
| ColumnType::LongLong
|
||||
) && !ty.flags.contains(ColumnFlags::UNSIGNED)
|
||||
}
|
||||
|
||||
impl Type<MySql> for i8 {
|
||||
fn type_info() -> MySqlTypeInfo {
|
||||
MySqlTypeInfo::binary(ColumnType::Tiny)
|
||||
|
@ -74,16 +65,34 @@ impl Encode<'_, MySql> for i64 {
|
|||
}
|
||||
}
|
||||
|
||||
fn int_accepts(ty: &MySqlTypeInfo) -> bool {
|
||||
matches!(
|
||||
ty.r#type,
|
||||
ColumnType::Tiny
|
||||
| ColumnType::Short
|
||||
| ColumnType::Long
|
||||
| ColumnType::Int24
|
||||
| ColumnType::LongLong
|
||||
) && !ty.flags.contains(ColumnFlags::UNSIGNED)
|
||||
}
|
||||
|
||||
fn int_decode(value: MySqlValueRef<'_>) -> Result<i64, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
MySqlValueFormat::Binary => {
|
||||
let buf = value.as_bytes()?;
|
||||
LittleEndian::read_int(buf, buf.len())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
impl Decode<'_, MySql> for i8 {
|
||||
fn accepts(ty: &MySqlTypeInfo) -> bool {
|
||||
int_accepts(ty)
|
||||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => value.as_bytes()?[0] as i8,
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
int_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,10 +102,7 @@ impl Decode<'_, MySql> for i16 {
|
|||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => LittleEndian::read_i16(value.as_bytes()?),
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
int_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,10 +112,7 @@ impl Decode<'_, MySql> for i32 {
|
|||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => LittleEndian::read_i32(value.as_bytes()?),
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
int_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,9 +122,6 @@ impl Decode<'_, MySql> for i64 {
|
|||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => LittleEndian::read_i64(value.as_bytes()?),
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
int_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
use crate::decode::Decode;
|
||||
|
@ -15,17 +17,6 @@ fn uint_type_info(ty: ColumnType) -> MySqlTypeInfo {
|
|||
}
|
||||
}
|
||||
|
||||
fn uint_accepts(ty: &MySqlTypeInfo) -> bool {
|
||||
matches!(
|
||||
ty.r#type,
|
||||
ColumnType::Tiny
|
||||
| ColumnType::Short
|
||||
| ColumnType::Long
|
||||
| ColumnType::Int24
|
||||
| ColumnType::LongLong
|
||||
) && ty.flags.contains(ColumnFlags::UNSIGNED)
|
||||
}
|
||||
|
||||
impl Type<MySql> for u8 {
|
||||
fn type_info() -> MySqlTypeInfo {
|
||||
uint_type_info(ColumnType::Tiny)
|
||||
|
@ -82,16 +73,34 @@ impl Encode<'_, MySql> for u64 {
|
|||
}
|
||||
}
|
||||
|
||||
fn uint_accepts(ty: &MySqlTypeInfo) -> bool {
|
||||
matches!(
|
||||
ty.r#type,
|
||||
ColumnType::Tiny
|
||||
| ColumnType::Short
|
||||
| ColumnType::Long
|
||||
| ColumnType::Int24
|
||||
| ColumnType::LongLong
|
||||
) && ty.flags.contains(ColumnFlags::UNSIGNED)
|
||||
}
|
||||
|
||||
fn uint_decode(value: MySqlValueRef<'_>) -> Result<u64, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
MySqlValueFormat::Binary => {
|
||||
let buf = value.as_bytes()?;
|
||||
LittleEndian::read_uint(buf, buf.len())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
impl Decode<'_, MySql> for u8 {
|
||||
fn accepts(ty: &MySqlTypeInfo) -> bool {
|
||||
uint_accepts(ty)
|
||||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => value.as_bytes()?[0] as u8,
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
uint_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,10 +110,7 @@ impl Decode<'_, MySql> for u16 {
|
|||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => LittleEndian::read_u16(value.as_bytes()?),
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
uint_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,10 +120,7 @@ impl Decode<'_, MySql> for u32 {
|
|||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => LittleEndian::read_u32(value.as_bytes()?),
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
uint_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,9 +130,6 @@ impl Decode<'_, MySql> for u64 {
|
|||
}
|
||||
|
||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Binary => LittleEndian::read_u64(value.as_bytes()?),
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
})
|
||||
uint_decode(value)?.try_into().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue