Squashed 'third_party/flatbuffers/' changes from bc44fad35..8aa8b9139
8aa8b9139 Fix handling of +/-inf defaults in TS/rust/go/dart codegen (#7588)
001adf782 Add support for parsing proto map fields (#7613)
dbc58ab77 Fix help output for --gen-includes (#7611)
2facfeec7 Fix missing spaces in flatc help text (#7612)
4de2814c7 Fix: arduino platform build (#7625)
37b1acdaf Fix current official name of macOS (#7627)
a22434e2a Add missing #include <algorithm> for std::min/std::max uses, and #include <limits> for std::numeric_limits<> (#7624)
214cc9468 Bump Rust version to 22.10.26 before publication (#7622)
a4ff275d9 Added option to not requires an EoF token when parsing JSON (#7620)
15f32c690 python: object generation prefix and suffix (#7565)
051afd882 Add CreateSharedString to python builder (#7608)
728c033ad Add check for presence of realpath to CMakeLists.txt to support more platforms (#7603)
4c514483d Update DartTest.sh golden files (#7606)
c2d9c2080 [TS] Add support for fixed length arrays on Typescript (#5864) (#7021) (#7581)
e34ae4c6b `build.yml`: Fix missing 'v' in version
e54536127 `build.yml` Update to Kotlin Wrapper 1.0.5
49d9f941c `release.yml` Use env var for passphrase
cefc21c1f `release.yml` Add GPG key for Maven
3e64fa724 `release.yml`: Add Maven Steps
b15f3c57e `release_yml` Use new dotnet version
ff802c680 `release.yml` Use NuGet Key directly
b401957d5 `release.yml` Changed Push to follow examples
8c8151f8f `release.yml` Fix nuget push command
ebb7c203d `release.yml` Add Nuget support
203241ed3 FlatBuffers Version 22.10.26 (#7607)
ac485609c `setup.py`: Define version directly
de5b85aa6 `release.yml`: Switch to `python` directory
de3df2d88 `release.yml`: Add publishing to PyPi
043a24f2e [Python] Fixed the issue with nested unions relying on InitFromBuf. (#7576)
5a48b0d7d release.yml: Typo
ce307556f release.yml: Remove `npm ci`
cb616e27c Create release.yml (#7605)
a54ca1e75 FlatBuffers Version 22.10.25 (#7604)
5b3fadcc1 [vector] Allow to iterate with mutables (#7586)
872a49746 [Nim] Bfbs Nim Generator (#7534)
e30170296 Make type conversions explicit. (#7595)
f7b734438 Fix LongEnum definitions (#7596)
5792623df Rust fix compilation for no_std targets #2 (#7553)
0edb27528 Update Rust version (#7574)
acc6a20d3 tests/test.cpp contains a couple of tests that are only executed (#7571)
04cd037ba Fix #7580 by documenting union schema evolution rules (#7585)
e1c5db988 Turn on clippy for Rust and fix lints for non-generated code (#7575)
b80142b90 Update documentation to mention enum value attributes (#7570)
54418f371 Add support for metadata attributes for enum values (#7567) (#7568)
c92e78a9f FlatBuffers Version 22.9.29 (#7557)
d243b904c [TS] Make strict compliant and improve typings (#7549)
374f8fb5f Rust soundness fixes (#7518)
dadbff571 Moves swift package to root of repository so it can be used directly … (#7548)
76ddae006 FlatBuffers Version 22.9.24 (#7547)
cfe157ec5 Emit internal enums when swift_implementation_only (#7545)
413115858 [Python] Python fixed size array (#7529)
88046190e Upgrade grpc to 1.49.0 and make sure it builds (#7538)
72aa85a75 [C++] Rare bad buffer content alignment if sizeof(T) != alignof(T) (#7520)
bfceebb7f Fix conform (#7532)
git-subtree-dir: third_party/flatbuffers
git-subtree-split: 8aa8b9139eb330f27816a5b8b5bbef402fbe3632
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
Change-Id: I943faba499baf58e9f561b1e4734922188ba8626
diff --git a/rust/flatbuffers/src/verifier.rs b/rust/flatbuffers/src/verifier.rs
index 36a5775..047d4f6 100644
--- a/rust/flatbuffers/src/verifier.rs
+++ b/rust/flatbuffers/src/verifier.rs
@@ -1,14 +1,14 @@
-#[cfg(feature = "no_std")]
+use crate::follow::Follow;
+use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
+#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::ops::Range;
use core::option::Option;
-use crate::follow::Follow;
-use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
-#[cfg(feature="no_std")]
-use thiserror_core2::Error;
-#[cfg(not(feature="no_std"))]
-use thiserror::Error;
+#[cfg(all(nightly, not(feature = "std")))]
+use core::error::Error;
+#[cfg(feature = "std")]
+use std::error::Error;
/// Traces the location of data errors. Not populated for Dos detecting errors.
/// Useful for MissingRequiredField and Utf8Error in particular, though
@@ -28,8 +28,10 @@
position: usize,
},
}
+
#[derive(PartialEq, Eq, Default, Debug, Clone)]
pub struct ErrorTrace(Vec<ErrorTraceDetail>);
+
impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
#[inline]
fn as_ref(&self) -> &[ErrorTraceDetail] {
@@ -39,64 +41,138 @@
/// Describes how a flatuffer is invalid and, for data errors, roughly where. No extra tracing
/// information is given for DoS detecting errors since it will probably be a lot.
-#[derive(Clone, Error, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
pub enum InvalidFlatbuffer {
- #[error("Missing required field `{required}`.\n{error_trace}")]
MissingRequiredField {
required: &'static str,
error_trace: ErrorTrace,
},
- #[error(
- "Union exactly one of union discriminant (`{field_type}`) and value \
- (`{field}`) are present.\n{error_trace}"
- )]
InconsistentUnion {
field: &'static str,
field_type: &'static str,
error_trace: ErrorTrace,
},
- #[error("Utf8 error for string in {range:?}: {error}\n{error_trace}")]
Utf8Error {
- #[source]
error: core::str::Utf8Error,
range: Range<usize>,
error_trace: ErrorTrace,
},
- #[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
- range.start, range.end)]
MissingNullTerminator {
range: Range<usize>,
error_trace: ErrorTrace,
},
- #[error("Type `{unaligned_type}` at position {position} is unaligned.\n{error_trace}")]
Unaligned {
position: usize,
unaligned_type: &'static str,
error_trace: ErrorTrace,
},
- #[error("Range [{}, {}) is out of bounds.\n{error_trace}", range.start, range.end)]
RangeOutOfBounds {
range: Range<usize>,
error_trace: ErrorTrace,
},
- #[error(
- "Signed offset at position {position} has value {soffset} which points out of bounds.\
- \n{error_trace}"
- )]
SignedOffsetOutOfBounds {
soffset: SOffsetT,
position: usize,
error_trace: ErrorTrace,
},
// Dos detecting errors. These do not get error traces since it will probably be very large.
- #[error("Too many tables.")]
TooManyTables,
- #[error("Apparent size too large.")]
ApparentSizeTooLarge,
- #[error("Nested table depth limit reached.")]
DepthLimitReached,
}
+#[cfg(any(nightly, feature = "std"))]
+impl Error for InvalidFlatbuffer {
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ if let InvalidFlatbuffer::Utf8Error { error: source, .. } = self {
+ Some(source)
+ } else {
+ None
+ }
+ }
+}
+
+impl core::fmt::Display for InvalidFlatbuffer {
+ fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+ match self {
+ InvalidFlatbuffer::MissingRequiredField {
+ required,
+ error_trace,
+ } => {
+ writeln!(f, "Missing required field `{}`.\n{}", required, error_trace)?;
+ }
+ InvalidFlatbuffer::InconsistentUnion {
+ field,
+ field_type,
+ error_trace,
+ } => {
+ writeln!(
+ f,
+ "Exactly one of union discriminant (`{}`) and value (`{}`) are present.\n{}",
+ field_type, field, error_trace
+ )?;
+ }
+ InvalidFlatbuffer::Utf8Error {
+ error,
+ range,
+ error_trace,
+ } => {
+ writeln!(
+ f,
+ "Utf8 error for string in {:?}: {}\n{}",
+ range, error, error_trace
+ )?;
+ }
+ InvalidFlatbuffer::MissingNullTerminator { range, error_trace } => {
+ writeln!(
+ f,
+ "String in range [{}, {}) is missing its null terminator.\n{}",
+ range.start, range.end, error_trace
+ )?;
+ }
+ InvalidFlatbuffer::Unaligned {
+ position,
+ unaligned_type,
+ error_trace,
+ } => {
+ writeln!(
+ f,
+ "Type `{}` at position {} is unaligned.\n{}",
+ unaligned_type, position, error_trace
+ )?;
+ }
+ InvalidFlatbuffer::RangeOutOfBounds { range, error_trace } => {
+ writeln!(
+ f,
+ "Range [{}, {}) is out of bounds.\n{}",
+ range.start, range.end, error_trace
+ )?;
+ }
+ InvalidFlatbuffer::SignedOffsetOutOfBounds {
+ soffset,
+ position,
+ error_trace,
+ } => {
+ writeln!(
+ f,
+ "Signed offset at position {} has value {} which points out of bounds.\n{}",
+ position, soffset, error_trace
+ )?;
+ }
+ InvalidFlatbuffer::TooManyTables {} => {
+ writeln!(f, "Too many tables.")?;
+ }
+ InvalidFlatbuffer::ApparentSizeTooLarge {} => {
+ writeln!(f, "Apparent size too large.")?;
+ }
+ InvalidFlatbuffer::DepthLimitReached {} => {
+ writeln!(f, "Nested table depth limit reached.")?;
+ }
+ }
+ Ok(())
+ }
+}
+
impl core::fmt::Display for ErrorTrace {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use ErrorTraceDetail::*;
@@ -184,6 +260,7 @@
},
)
}
+
/// Adds a TableField trace detail if `res` is a data error.
fn trace_elem<T>(res: Result<T>, index: usize, position: usize) -> Result<T> {
append_trace(res, ErrorTraceDetail::VectorElement { index, position })
@@ -205,6 +282,7 @@
// options to error un-recognized enums and unions? possible footgun.
// Ignore nested flatbuffers, etc?
}
+
impl Default for VerifierOptions {
fn default() -> Self {
Self {
@@ -226,6 +304,7 @@
num_tables: usize,
apparent_size: usize,
}
+
impl<'opts, 'buf> Verifier<'opts, 'buf> {
pub fn new(opts: &'opts VerifierOptions, buffer: &'buf [u8]) -> Self {
Self {
@@ -247,9 +326,12 @@
/// memory since `buffer: &[u8]` has alignment 1.
///
/// ### WARNING
+ ///
/// This does not work for flatbuffers-structs as they have alignment 1 according to
/// `core::mem::align_of` but are meant to have higher alignment within a Flatbuffer w.r.t.
/// `buffer[0]`. TODO(caspern).
+ ///
+ /// Note this does not impact soundness as this crate does not assume alignment of structs
#[inline]
fn is_aligned<T>(&self, pos: usize) -> Result<()> {
if pos % core::mem::align_of::<T>() == 0 {
@@ -307,9 +389,9 @@
// signed offsets are subtracted.
let derefed = if offset > 0 {
- pos.checked_sub(offset.abs() as usize)
+ pos.checked_sub(offset.unsigned_abs() as usize)
} else {
- pos.checked_add(offset.abs() as usize)
+ pos.checked_add(offset.unsigned_abs() as usize)
};
if let Some(x) = derefed {
if x < self.buffer.len() {
@@ -372,6 +454,7 @@
// Verifier struct which holds the surrounding state and options.
verifier: &'ver mut Verifier<'opts, 'buf>,
}
+
impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
fn deref(&mut self, field: VOffsetT) -> Result<Option<usize>> {
let field = field as usize;
@@ -439,7 +522,9 @@
}
(Some(k), Some(v)) => {
trace_field(Key::run_verifier(self.verifier, k), key_field_name, k)?;
- let discriminant = Key::follow(self.verifier.buffer, k);
+ // Safety:
+ // Run verifier on `k` above
+ let discriminant = unsafe { Key::follow(self.verifier.buffer, k) };
trace_field(
verify_union(discriminant, self.verifier, v),
val_field_name,
@@ -486,16 +571,27 @@
}
pub trait SimpleToVerifyInSlice {}
+
impl SimpleToVerifyInSlice for bool {}
+
impl SimpleToVerifyInSlice for i8 {}
+
impl SimpleToVerifyInSlice for u8 {}
+
impl SimpleToVerifyInSlice for i16 {}
+
impl SimpleToVerifyInSlice for u16 {}
+
impl SimpleToVerifyInSlice for i32 {}
+
impl SimpleToVerifyInSlice for u32 {}
+
impl SimpleToVerifyInSlice for f32 {}
+
impl SimpleToVerifyInSlice for i64 {}
+
impl SimpleToVerifyInSlice for u64 {}
+
impl SimpleToVerifyInSlice for f64 {}
impl<T: SimpleToVerifyInSlice> Verifiable for Vector<'_, T> {