summaryrefslogtreecommitdiff
path: root/samples
diff options
context:
space:
mode:
authorCasper <casperneo@uchicago.edu>2020-12-07 18:37:51 -0500
committerGitHub <noreply@github.com>2020-12-07 18:37:51 -0500
commit442949bc11c4e08a04516390dd78794cd4dec746 (patch)
tree292275b264f5e50a31255a979e5a0c6cd7ee0ca0 /samples
parent9064072e8cd42be6710b293ad567acd44845f7fc (diff)
downloadflatbuffers-442949bc11c4e08a04516390dd78794cd4dec746.tar.gz
flatbuffers-442949bc11c4e08a04516390dd78794cd4dec746.tar.bz2
flatbuffers-442949bc11c4e08a04516390dd78794cd4dec746.zip
Rust Flatbuffers Verifier (#6269)
* Updated comments and fixed a fundemental type error. * bump rust flatbuffers semver * Initial commit with verifier, need to clean up * Verifier tested. Needs clean up and refactoring. * Display for InvalidFlatbuffer and better errors for strings * SimpleToVerify, some refactoring * Combined VerifierType TableAccessorFuncBody into FollowType * scrub todos * Update Rust get_root functions. There are 6 variants, with verifier options, default verifier options and no verification "fast". * Rename root fns * inline * Update to use thiserror * fix for bad compiler * improve error formatting * Replace multiply with saturating_multiply * saturating adds too * Add docs disclaiming experimental verification system Co-authored-by: Casper Neo <cneo@google.com>
Diffstat (limited to 'samples')
-rw-r--r--samples/monster_generated.rs161
-rw-r--r--samples/sample_binary.rs5
2 files changed, 151 insertions, 15 deletions
diff --git a/samples/monster_generated.rs b/samples/monster_generated.rs
index e352b758..53070c0d 100644
--- a/samples/monster_generated.rs
+++ b/samples/monster_generated.rs
@@ -77,7 +77,8 @@ impl<'a> flatbuffers::Follow<'a> for Color {
type Inner = Self;
#[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
- Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
+ let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
+ Self(b)
}
}
@@ -92,14 +93,27 @@ impl flatbuffers::Push for Color {
impl flatbuffers::EndianScalar for Color {
#[inline]
fn to_little_endian(self) -> Self {
- Self(i8::to_le(self.0))
+ let b = i8::to_le(self.0);
+ Self(b)
}
#[inline]
fn from_little_endian(self) -> Self {
- Self(i8::from_le(self.0))
+ let b = i8::from_le(self.0);
+ Self(b)
}
}
+impl<'a> flatbuffers::Verifiable for Color {
+ #[inline]
+ fn run_verifier<'o, 'b>(
+ v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
+ ) -> Result<(), flatbuffers::InvalidFlatbuffer> {
+ use self::flatbuffers::Verifiable;
+ i8::run_verifier(v, pos)
+ }
+}
+
+impl flatbuffers::SimpleToVerifyInSlice for Color {}
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MIN_EQUIPMENT: u8 = 0;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
@@ -143,11 +157,13 @@ impl std::fmt::Debug for Equipment {
}
}
}
+pub struct EquipmentUnionTableOffset {}
impl<'a> flatbuffers::Follow<'a> for Equipment {
type Inner = Self;
#[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
- Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
+ let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
+ Self(b)
}
}
@@ -162,15 +178,27 @@ impl flatbuffers::Push for Equipment {
impl flatbuffers::EndianScalar for Equipment {
#[inline]
fn to_little_endian(self) -> Self {
- Self(u8::to_le(self.0))
+ let b = u8::to_le(self.0);
+ Self(b)
}
#[inline]
fn from_little_endian(self) -> Self {
- Self(u8::from_le(self.0))
+ let b = u8::from_le(self.0);
+ Self(b)
}
}
-pub struct EquipmentUnionTableOffset {}
+impl<'a> flatbuffers::Verifiable for Equipment {
+ #[inline]
+ fn run_verifier<'o, 'b>(
+ v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
+ ) -> Result<(), flatbuffers::InvalidFlatbuffer> {
+ use self::flatbuffers::Verifiable;
+ u8::run_verifier(v, pos)
+ }
+}
+
+impl flatbuffers::SimpleToVerifyInSlice for Equipment {}
// struct Vec3, aligned to 4
#[repr(C, align(4))]
#[derive(Clone, Copy, PartialEq)]
@@ -189,6 +217,7 @@ impl std::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;
@@ -226,7 +255,15 @@ impl<'b> flatbuffers::Push for &'b Vec3 {
}
}
-
+impl<'a> flatbuffers::Verifiable for Vec3 {
+ #[inline]
+ fn run_verifier<'o, 'b>(
+ v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
+ ) -> Result<(), flatbuffers::InvalidFlatbuffer> {
+ use self::flatbuffers::Verifiable;
+ v.in_buffer::<Self>(pos)
+ }
+}
impl Vec3 {
pub fn new(_x: f32, _y: f32, _z: f32) -> Self {
Vec3 {
@@ -324,7 +361,7 @@ impl<'a> Monster<'a> {
}
#[inline]
pub fn weapons(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon<'a>>>> {
- self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Weapon<'a>>>>>(Monster::VT_WEAPONS, None)
+ self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None)
}
#[inline]
pub fn equipped_type(&self) -> Equipment {
@@ -336,7 +373,7 @@ impl<'a> Monster<'a> {
}
#[inline]
pub fn path(&self) -> Option<&'a [Vec3]> {
- self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Vec3>>>(Monster::VT_PATH, None).map(|v| v.safe_slice() )
+ self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None).map(|v| v.safe_slice())
}
#[inline]
#[allow(non_snake_case)]
@@ -350,6 +387,31 @@ impl<'a> Monster<'a> {
}
+impl flatbuffers::Verifiable for Monster<'_> {
+ #[inline]
+ fn run_verifier<'o, 'b>(
+ v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
+ ) -> Result<(), flatbuffers::InvalidFlatbuffer> {
+ use self::flatbuffers::Verifiable;
+ v.visit_table(pos)?
+ .visit_field::<Vec3>(&"pos", Self::VT_POS, false)?
+ .visit_field::<i16>(&"mana", Self::VT_MANA, false)?
+ .visit_field::<i16>(&"hp", Self::VT_HP, false)?
+ .visit_field::<flatbuffers::ForwardsUOffset<&str>>(&"name", Self::VT_NAME, false)?
+ .visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u8>>>(&"inventory", Self::VT_INVENTORY, false)?
+ .visit_field::<Color>(&"color", Self::VT_COLOR, false)?
+ .visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<Weapon>>>>(&"weapons", Self::VT_WEAPONS, false)?
+ .visit_union::<Equipment, _>(&"equipped_type", Self::VT_EQUIPPED_TYPE, &"equipped", Self::VT_EQUIPPED, false, |key, v, pos| {
+ match key {
+ Equipment::Weapon => v.verify_union_variant::<flatbuffers::ForwardsUOffset<Weapon>>("Equipment::Weapon", pos),
+ _ => Ok(()),
+ }
+ })?
+ .visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, Vec3>>>(&"path", Self::VT_PATH, false)?
+ .finish();
+ Ok(())
+ }
+}
pub struct MonsterArgs<'a> {
pub pos: Option<&'a Vec3>,
pub mana: i16,
@@ -512,6 +574,19 @@ impl<'a> Weapon<'a> {
}
}
+impl flatbuffers::Verifiable for Weapon<'_> {
+ #[inline]
+ fn run_verifier<'o, 'b>(
+ v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
+ ) -> Result<(), flatbuffers::InvalidFlatbuffer> {
+ use self::flatbuffers::Verifiable;
+ v.visit_table(pos)?
+ .visit_field::<flatbuffers::ForwardsUOffset<&str>>(&"name", Self::VT_NAME, false)?
+ .visit_field::<i16>(&"damage", Self::VT_DAMAGE, false)?
+ .finish();
+ Ok(())
+ }
+}
pub struct WeaponArgs<'a> {
pub name: Option<flatbuffers::WIPOffset<&'a str>>,
pub damage: i16,
@@ -562,16 +637,78 @@ impl std::fmt::Debug for Weapon<'_> {
}
}
#[inline]
+#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
- flatbuffers::get_root::<Monster<'a>>(buf)
+ unsafe { flatbuffers::root_unchecked::<Monster<'a>>(buf) }
}
#[inline]
+#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
- flatbuffers::get_size_prefixed_root::<Monster<'a>>(buf)
+ unsafe { flatbuffers::size_prefixed_root_unchecked::<Monster<'a>>(buf) }
}
#[inline]
+/// Verifies that a buffer of bytes contains a `Monster`
+/// and returns it.
+/// Note that verification is still experimental and may not
+/// catch every error, or be maximally performant. For the
+/// previous, unchecked, behavior use
+/// `root_as_monster_unchecked`.
+pub fn root_as_monster(buf: &[u8]) -> Result<Monster, flatbuffers::InvalidFlatbuffer> {
+ flatbuffers::root::<Monster>(buf)
+}
+#[inline]
+/// Verifies that a buffer of bytes contains a size prefixed
+/// `Monster` and returns it.
+/// Note that verification is still experimental and may not
+/// catch every error, or be maximally performant. For the
+/// previous, unchecked, behavior use
+/// `size_prefixed_root_as_monster_unchecked`.
+pub fn size_prefixed_root_as_monster(buf: &[u8]) -> Result<Monster, flatbuffers::InvalidFlatbuffer> {
+ flatbuffers::size_prefixed_root::<Monster>(buf)
+}
+#[inline]
+/// Verifies, with the given options, that a buffer of bytes
+/// contains a `Monster` and returns it.
+/// Note that verification is still experimental and may not
+/// catch every error, or be maximally performant. For the
+/// previous, unchecked, behavior use
+/// `root_as_monster_unchecked`.
+pub fn root_as_monster_with_opts<'b, 'o>(
+ opts: &'o flatbuffers::VerifierOptions,
+ buf: &'b [u8],
+) -> Result<Monster<'b>, flatbuffers::InvalidFlatbuffer> {
+ flatbuffers::root_with_opts::<Monster<'b>>(opts, buf)
+}
+#[inline]
+/// Verifies, with the given verifier options, that a buffer of
+/// bytes contains a size prefixed `Monster` and returns
+/// it. Note that verification is still experimental and may not
+/// catch every error, or be maximally performant. For the
+/// previous, unchecked, behavior use
+/// `root_as_monster_unchecked`.
+pub fn size_prefixed_root_as_monster_with_opts<'b, 'o>(
+ opts: &'o flatbuffers::VerifierOptions,
+ buf: &'b [u8],
+) -> Result<Monster<'b>, flatbuffers::InvalidFlatbuffer> {
+ flatbuffers::size_prefixed_root_with_opts::<Monster<'b>>(opts, buf)
+}
+#[inline]
+/// Assumes, without verification, that a buffer of bytes contains a Monster and returns it.
+/// # Safety
+/// Callers must trust the given bytes do indeed contain a valid `Monster`.
+pub unsafe fn root_as_monster_unchecked(buf: &[u8]) -> Monster {
+ flatbuffers::root_unchecked::<Monster>(buf)
+}
+#[inline]
+/// Assumes, without verification, that a buffer of bytes contains a size prefixed Monster and returns it.
+/// # Safety
+/// Callers must trust the given bytes do indeed contain a valid size prefixed `Monster`.
+pub unsafe fn size_prefixed_root_as_monster_unchecked(buf: &[u8]) -> Monster {
+ flatbuffers::size_prefixed_root_unchecked::<Monster>(buf)
+}
+#[inline]
pub fn finish_monster_buffer<'a, 'b>(
fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
root: flatbuffers::WIPOffset<Monster<'a>>) {
diff --git a/samples/sample_binary.rs b/samples/sample_binary.rs
index 6fb987eb..649babf3 100644
--- a/samples/sample_binary.rs
+++ b/samples/sample_binary.rs
@@ -20,8 +20,7 @@ extern crate flatbuffers;
// import the generated code
#[path = "./monster_generated.rs"]
mod monster_generated;
-pub use monster_generated::my_game::sample::{get_root_as_monster,
- Color, Equipment,
+pub use monster_generated::my_game::sample::{Color, Equipment,
Monster, MonsterArgs,
Vec3,
Weapon, WeaponArgs};
@@ -98,7 +97,7 @@ fn main() {
let buf = builder.finished_data(); // Of type `&[u8]`
// Get access to the root:
- let monster = get_root_as_monster(buf);
+ let monster = flatbuffers::root::<Monster>(buf).unwrap();
// Get and test some scalar types from the FlatBuffer.
let hp = monster.hp();