mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-02 15:25:32 +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
@ -1,3 +1,5 @@
|
|||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
@ -7,17 +9,6 @@ use crate::mysql::protocol::text::{ColumnFlags, ColumnType};
|
|||||||
use crate::mysql::{MySql, MySqlTypeInfo, MySqlValueFormat, MySqlValueRef};
|
use crate::mysql::{MySql, MySqlTypeInfo, MySqlValueFormat, MySqlValueRef};
|
||||||
use crate::types::Type;
|
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 {
|
impl Type<MySql> for i8 {
|
||||||
fn type_info() -> MySqlTypeInfo {
|
fn type_info() -> MySqlTypeInfo {
|
||||||
MySqlTypeInfo::binary(ColumnType::Tiny)
|
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 {
|
impl Decode<'_, MySql> for i8 {
|
||||||
fn accepts(ty: &MySqlTypeInfo) -> bool {
|
fn accepts(ty: &MySqlTypeInfo) -> bool {
|
||||||
int_accepts(ty)
|
int_accepts(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
int_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => value.as_bytes()?[0] as i8,
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,10 +102,7 @@ impl Decode<'_, MySql> for i16 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
int_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => LittleEndian::read_i16(value.as_bytes()?),
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,10 +112,7 @@ impl Decode<'_, MySql> for i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
int_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => LittleEndian::read_i32(value.as_bytes()?),
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,9 +122,6 @@ impl Decode<'_, MySql> for i64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
int_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => LittleEndian::read_i64(value.as_bytes()?),
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
|
||||||
use crate::decode::Decode;
|
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 {
|
impl Type<MySql> for u8 {
|
||||||
fn type_info() -> MySqlTypeInfo {
|
fn type_info() -> MySqlTypeInfo {
|
||||||
uint_type_info(ColumnType::Tiny)
|
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 {
|
impl Decode<'_, MySql> for u8 {
|
||||||
fn accepts(ty: &MySqlTypeInfo) -> bool {
|
fn accepts(ty: &MySqlTypeInfo) -> bool {
|
||||||
uint_accepts(ty)
|
uint_accepts(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
uint_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => value.as_bytes()?[0] as u8,
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,10 +110,7 @@ impl Decode<'_, MySql> for u16 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
uint_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => LittleEndian::read_u16(value.as_bytes()?),
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,10 +120,7 @@ impl Decode<'_, MySql> for u32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
uint_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => LittleEndian::read_u32(value.as_bytes()?),
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,9 +130,6 @@ impl Decode<'_, MySql> for u64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||||
Ok(match value.format() {
|
uint_decode(value)?.try_into().map_err(Into::into)
|
||||||
MySqlValueFormat::Binary => LittleEndian::read_u64(value.as_bytes()?),
|
|
||||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user