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> {