mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-11 23:40:57 +00:00
Rust soundness fixes (#7518)
* Rust soundness fixes * Second pass * Make init_from_table unsafe * Remove SafeSliceAccess * Clippy * Remove create_vector_of_strings * More clippy * Remove deprecated root type accessors * More soundness fixes * Fix EndianScalar for bool * Add TriviallyTransmutable * Add debug assertions * Review comments * Review feedback
This commit is contained in:
committed by
GitHub
parent
dadbff5714
commit
374f8fb5fb
@@ -59,10 +59,8 @@ impl core::fmt::Debug for Color {
|
||||
impl<'a> flatbuffers::Follow<'a> for Color {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
let b = unsafe {
|
||||
flatbuffers::read_scalar_at::<i8>(buf, loc)
|
||||
};
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
@@ -70,21 +68,21 @@ impl<'a> flatbuffers::Follow<'a> for Color {
|
||||
impl flatbuffers::Push for Color {
|
||||
type Output = Color;
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
unsafe { flatbuffers::emplace_scalar::<i8>(dst, self.0); }
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
flatbuffers::emplace_scalar::<i8>(dst, self.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::EndianScalar for Color {
|
||||
type Scalar = i8;
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
let b = i8::to_le(self.0);
|
||||
Self(b)
|
||||
fn to_little_endian(self) -> i8 {
|
||||
self.0.to_le()
|
||||
}
|
||||
#[inline]
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn from_little_endian(self) -> Self {
|
||||
let b = i8::from_le(self.0);
|
||||
fn from_little_endian(v: i8) -> Self {
|
||||
let b = i8::from_le(v);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,10 +55,8 @@ impl core::fmt::Debug for Equipment {
|
||||
impl<'a> flatbuffers::Follow<'a> for Equipment {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
let b = unsafe {
|
||||
flatbuffers::read_scalar_at::<u8>(buf, loc)
|
||||
};
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
@@ -66,21 +64,21 @@ impl<'a> flatbuffers::Follow<'a> for Equipment {
|
||||
impl flatbuffers::Push for Equipment {
|
||||
type Output = Equipment;
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
unsafe { flatbuffers::emplace_scalar::<u8>(dst, self.0); }
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
flatbuffers::emplace_scalar::<u8>(dst, self.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::EndianScalar for Equipment {
|
||||
type Scalar = u8;
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
let b = u8::to_le(self.0);
|
||||
Self(b)
|
||||
fn to_little_endian(self) -> u8 {
|
||||
self.0.to_le()
|
||||
}
|
||||
#[inline]
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn from_little_endian(self) -> Self {
|
||||
let b = u8::from_le(self.0);
|
||||
fn from_little_endian(v: u8) -> Self {
|
||||
let b = u8::from_le(v);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ pub struct Monster<'a> {
|
||||
impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
|
||||
type Inner = Monster<'a>;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table { buf, loc } }
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table::new(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
Monster { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
@@ -73,7 +73,7 @@ impl<'a> Monster<'a> {
|
||||
x.to_string()
|
||||
});
|
||||
let inventory = self.inventory().map(|x| {
|
||||
x.to_vec()
|
||||
x.into_iter().collect()
|
||||
});
|
||||
let color = self.color();
|
||||
let weapons = self.weapons().map(|x| {
|
||||
@@ -106,49 +106,84 @@ impl<'a> Monster<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn pos(&self) -> Option<&'a Vec3> {
|
||||
self._tab.get::<Vec3>(Monster::VT_POS, None)
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<Vec3>(Monster::VT_POS, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn mana(&self) -> i16 {
|
||||
self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()}
|
||||
}
|
||||
#[inline]
|
||||
pub fn hp(&self) -> i16 {
|
||||
self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()}
|
||||
}
|
||||
#[inline]
|
||||
pub fn name(&self) -> Option<&'a str> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None)
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn inventory(&self) -> Option<&'a [u8]> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None).map(|v| v.safe_slice())
|
||||
pub fn inventory(&self) -> Option<flatbuffers::Vector<'a, u8>> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn color(&self) -> Color {
|
||||
self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()}
|
||||
}
|
||||
#[inline]
|
||||
pub fn weapons(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon<'a>>>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None)
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn equipped_type(&self) -> Equipment {
|
||||
self._tab.get::<Equipment>(Monster::VT_EQUIPPED_TYPE, Some(Equipment::NONE)).unwrap()
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<Equipment>(Monster::VT_EQUIPPED_TYPE, Some(Equipment::NONE)).unwrap()}
|
||||
}
|
||||
#[inline]
|
||||
pub fn equipped(&self) -> Option<flatbuffers::Table<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_EQUIPPED, None)
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Monster::VT_EQUIPPED, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn path(&self) -> Option<&'a [Vec3]> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None).map(|v| v.safe_slice())
|
||||
pub fn path(&self) -> Option<flatbuffers::Vector<'a, Vec3>> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None)}
|
||||
}
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn equipped_as_weapon(&self) -> Option<Weapon<'a>> {
|
||||
if self.equipped_type() == Equipment::Weapon {
|
||||
self.equipped().map(Weapon::init_from_table)
|
||||
self.equipped().map(|t| {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid union in this slot
|
||||
unsafe { Weapon::init_from_table(t) }
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -365,18 +400,6 @@ impl MonsterT {
|
||||
})
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
|
||||
unsafe { flatbuffers::root_unchecked::<Monster<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
|
||||
unsafe { flatbuffers::size_prefixed_root_unchecked::<Monster<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a `Monster`
|
||||
/// and returns it.
|
||||
|
||||
@@ -29,39 +29,25 @@ impl core::fmt::Debug for Vec3 {
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Vec3 {}
|
||||
impl flatbuffers::SafeSliceAccess for Vec3 {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Vec3 {
|
||||
type Inner = &'a Vec3;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
<&'a Vec3>::follow(buf, loc)
|
||||
}
|
||||
}
|
||||
impl<'a> flatbuffers::Follow<'a> for &'a Vec3 {
|
||||
type Inner = &'a Vec3;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
flatbuffers::follow_cast_ref::<Vec3>(buf, loc)
|
||||
}
|
||||
}
|
||||
impl<'b> flatbuffers::Push for Vec3 {
|
||||
type Output = Vec3;
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
let src = unsafe {
|
||||
::core::slice::from_raw_parts(self as *const Vec3 as *const u8, Self::size())
|
||||
};
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
}
|
||||
impl<'b> flatbuffers::Push for &'b Vec3 {
|
||||
type Output = Vec3;
|
||||
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
let src = unsafe {
|
||||
::core::slice::from_raw_parts(*self as *const Vec3 as *const u8, Self::size())
|
||||
};
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
let src = ::core::slice::from_raw_parts(self as *const Vec3 as *const u8, Self::size());
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
}
|
||||
@@ -95,70 +81,88 @@ impl<'a> Vec3 {
|
||||
}
|
||||
|
||||
pub fn x(&self) -> f32 {
|
||||
let mut mem = core::mem::MaybeUninit::<f32>::uninit();
|
||||
unsafe {
|
||||
let mut mem = core::mem::MaybeUninit::<<f32 as EndianScalar>::Scalar>::uninit();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
EndianScalar::from_little_endian(unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.0[0..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
core::mem::size_of::<f32>(),
|
||||
core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
}.from_little_endian()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_x(&mut self, x: f32) {
|
||||
let x_le = x.to_little_endian();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const f32 as *const u8,
|
||||
&x_le as *const _ as *const u8,
|
||||
self.0[0..].as_mut_ptr(),
|
||||
core::mem::size_of::<f32>(),
|
||||
core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn y(&self) -> f32 {
|
||||
let mut mem = core::mem::MaybeUninit::<f32>::uninit();
|
||||
unsafe {
|
||||
let mut mem = core::mem::MaybeUninit::<<f32 as EndianScalar>::Scalar>::uninit();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
EndianScalar::from_little_endian(unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.0[4..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
core::mem::size_of::<f32>(),
|
||||
core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
}.from_little_endian()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_y(&mut self, x: f32) {
|
||||
let x_le = x.to_little_endian();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const f32 as *const u8,
|
||||
&x_le as *const _ as *const u8,
|
||||
self.0[4..].as_mut_ptr(),
|
||||
core::mem::size_of::<f32>(),
|
||||
core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn z(&self) -> f32 {
|
||||
let mut mem = core::mem::MaybeUninit::<f32>::uninit();
|
||||
unsafe {
|
||||
let mut mem = core::mem::MaybeUninit::<<f32 as EndianScalar>::Scalar>::uninit();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
EndianScalar::from_little_endian(unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.0[8..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
core::mem::size_of::<f32>(),
|
||||
core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
}.from_little_endian()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_z(&mut self, x: f32) {
|
||||
let x_le = x.to_little_endian();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const f32 as *const u8,
|
||||
&x_le as *const _ as *const u8,
|
||||
self.0[8..].as_mut_ptr(),
|
||||
core::mem::size_of::<f32>(),
|
||||
core::mem::size_of::<<f32 as EndianScalar>::Scalar>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ pub struct Weapon<'a> {
|
||||
impl<'a> flatbuffers::Follow<'a> for Weapon<'a> {
|
||||
type Inner = Weapon<'a>;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table { buf, loc } }
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table::new(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ impl<'a> Weapon<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
Weapon { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
@@ -60,11 +60,17 @@ impl<'a> Weapon<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn name(&self) -> Option<&'a str> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Weapon::VT_NAME, None)
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Weapon::VT_NAME, None)}
|
||||
}
|
||||
#[inline]
|
||||
pub fn damage(&self) -> i16 {
|
||||
self._tab.get::<i16>(Weapon::VT_DAMAGE, Some(0)).unwrap()
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<i16>(Weapon::VT_DAMAGE, Some(0)).unwrap()}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user