From eacd0ebd18fd46601d8716f4075b779beb062181 Mon Sep 17 00:00:00 2001 From: Fedor Telnov <f.telnov@picodata.io> Date: Tue, 13 Aug 2024 15:46:50 +0300 Subject: [PATCH] fix: spec-compliant MP ext marker type It used to serialize MP ext marker type as char, while it is signed integer due to MP specification. On most platforms char is mapped to i8, so no runtime errors were normally seen. It was detected on linux aarch64, where char is u8. Markdown spec [reference](https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family). --- CHANGELOG.md | 1 + tarantool/src/datetime.rs | 5 ++--- tarantool/src/decimal.rs | 8 ++++---- tarantool/src/ffi/datetime.rs | 2 +- tarantool/src/ffi/decimal.rs | 2 +- tarantool/src/ffi/uuid.rs | 2 +- tarantool/src/uuid.rs | 5 ++--- 7 files changed, 12 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d689ee2..b5a0dd2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Fixed - Use after free in `fiber::Builder::start_non_joinable` when the fiber exits without yielding. +- Incorrect, off-spec MP Ext type: caused runtime errors on some platforms. ### Deprecated diff --git a/tarantool/src/datetime.rs b/tarantool/src/datetime.rs index cb32a694..2cc837f3 100644 --- a/tarantool/src/datetime.rs +++ b/tarantool/src/datetime.rs @@ -2,7 +2,6 @@ use crate::ffi::datetime as ffi; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use std::fmt::Display; -use std::os::raw::c_char; use time::{Duration, UtcOffset}; type Inner = time::OffsetDateTime; @@ -132,7 +131,7 @@ impl serde::Serialize for Datetime { S: serde::Serializer, { #[derive(Serialize)] - struct _ExtStruct<'a>((c_char, &'a serde_bytes::Bytes)); + struct _ExtStruct<'a>((i8, &'a serde_bytes::Bytes)); let data = self.as_bytes_tt(); let mut data = data.as_slice(); @@ -149,7 +148,7 @@ impl<'de> serde::Deserialize<'de> for Datetime { D: serde::Deserializer<'de>, { #[derive(Deserialize)] - struct _ExtStruct((c_char, serde_bytes::ByteBuf)); + struct _ExtStruct((i8, serde_bytes::ByteBuf)); let _ExtStruct((kind, bytes)) = serde::Deserialize::deserialize(deserializer)?; diff --git a/tarantool/src/decimal.rs b/tarantool/src/decimal.rs index 71b54c6b..4f1502b3 100644 --- a/tarantool/src/decimal.rs +++ b/tarantool/src/decimal.rs @@ -438,7 +438,7 @@ mod tarantool_decimal { S: serde::Serializer, { #[derive(Serialize)] - struct _ExtStruct((std::os::raw::c_char, serde_bytes::ByteBuf)); + struct _ExtStruct((i8, serde_bytes::ByteBuf)); let data = unsafe { let len = ffi::decimal_len(&self.inner) as usize; @@ -457,7 +457,7 @@ mod tarantool_decimal { D: serde::Deserializer<'de>, { #[derive(Deserialize)] - struct _ExtStruct((std::os::raw::c_char, serde_bytes::ByteBuf)); + struct _ExtStruct((i8, serde_bytes::ByteBuf)); match serde::Deserialize::deserialize(deserializer)? { _ExtStruct((ffi::MP_DECIMAL, bytes)) => { @@ -1142,7 +1142,7 @@ mod standalone_decimal { S: serde::Serializer, { #[derive(serde::Serialize)] - struct _ExtStruct((std::os::raw::c_char, serde_bytes::ByteBuf)); + struct _ExtStruct((i8, serde_bytes::ByteBuf)); let data = { let mut data = vec![]; @@ -1162,7 +1162,7 @@ mod standalone_decimal { { use serde::de::Error; #[derive(serde::Deserialize)] - struct _ExtStruct((std::os::raw::c_char, serde_bytes::ByteBuf)); + struct _ExtStruct((i8, serde_bytes::ByteBuf)); match serde::Deserialize::deserialize(deserializer)? { _ExtStruct((ffi::MP_DECIMAL, bytes)) => { diff --git a/tarantool/src/ffi/datetime.rs b/tarantool/src/ffi/datetime.rs index 163fb3a4..a3db4f6e 100644 --- a/tarantool/src/ffi/datetime.rs +++ b/tarantool/src/ffi/datetime.rs @@ -1,4 +1,4 @@ -pub const MP_DATETIME: std::os::raw::c_char = 4; +pub const MP_DATETIME: i8 = 4; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/tarantool/src/ffi/decimal.rs b/tarantool/src/ffi/decimal.rs index c4780077..9deb91f0 100644 --- a/tarantool/src/ffi/decimal.rs +++ b/tarantool/src/ffi/decimal.rs @@ -28,7 +28,7 @@ impl Hash for decNumber { pub const DECDPUN: usize = 3; pub const DECNUMUNITS: u32 = 13; pub const DECIMAL_MAX_DIGITS: u32 = 38; -pub const MP_DECIMAL: c_char = 1; +pub const MP_DECIMAL: i8 = 1; crate::define_dlsym_reloc! { /// Return decimal precision, diff --git a/tarantool/src/ffi/uuid.rs b/tarantool/src/ffi/uuid.rs index bd44759c..b07c22ba 100644 --- a/tarantool/src/ffi/uuid.rs +++ b/tarantool/src/ffi/uuid.rs @@ -1,4 +1,4 @@ -pub const MP_UUID: std::os::raw::c_char = 2; +pub const MP_UUID: i8 = 2; #[repr(C)] #[derive(Copy, Clone)] diff --git a/tarantool/src/uuid.rs b/tarantool/src/uuid.rs index d5c99b06..b64f7129 100644 --- a/tarantool/src/uuid.rs +++ b/tarantool/src/uuid.rs @@ -1,5 +1,4 @@ use crate::ffi::uuid as ffi; -use std::os::raw::c_char; pub use ::uuid::{adapter, Error}; use serde::{Deserialize, Serialize}; @@ -217,7 +216,7 @@ impl serde::Serialize for Uuid { S: serde::Serializer, { #[derive(Serialize)] - struct _ExtStruct((c_char, serde_bytes::ByteBuf)); + struct _ExtStruct((i8, serde_bytes::ByteBuf)); let data = self.as_bytes(); _ExtStruct((ffi::MP_UUID, serde_bytes::ByteBuf::from(data as &[_]))).serialize(serializer) @@ -230,7 +229,7 @@ impl<'de> serde::Deserialize<'de> for Uuid { D: serde::Deserializer<'de>, { #[derive(Deserialize)] - struct _ExtStruct((c_char, serde_bytes::ByteBuf)); + struct _ExtStruct((i8, serde_bytes::ByteBuf)); let _ExtStruct((kind, bytes)) = serde::Deserialize::deserialize(deserializer)?; -- GitLab