forked from BigfootDev/flatbuffers
* Fix nightly no_std * Fix nightly no_std
This commit is contained in:
@@ -12,14 +12,13 @@ categories = ["encoding", "data-structures", "memory-management"]
|
|||||||
rust = "1.51"
|
rust = "1.51"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["thiserror"]
|
default = ["std"]
|
||||||
no_std = ["core2", "thiserror_core2"]
|
std = []
|
||||||
serialize = ["serde"]
|
serialize = ["serde"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
thiserror = { version = "1.0.30", optional = true }
|
|
||||||
core2 = { version = "0.4.0", optional = true }
|
[build-dependencies]
|
||||||
# This version is compliant with mainline 1.0.30
|
rustc_version = "0.4.0"
|
||||||
thiserror_core2 = { version = "2.0.0", default-features = false, optional = true }
|
|
||||||
|
|||||||
12
rust/flatbuffers/build.rs
Normal file
12
rust/flatbuffers/build.rs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
use rustc_version::{version_meta, Channel};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let version_meta = version_meta().unwrap();
|
||||||
|
|
||||||
|
// To use nightly features we declare this and then we can use
|
||||||
|
// #[cfg(nightly)]
|
||||||
|
// for nightly only features
|
||||||
|
if version_meta.channel == Channel::Nightly {
|
||||||
|
println!("cargo:rustc-cfg=nightly")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(not(feature = "std"))]
|
||||||
use alloc::{vec, vec::Vec};
|
use alloc::{vec, vec::Vec};
|
||||||
use core::cmp::max;
|
use core::cmp::max;
|
||||||
use core::iter::{DoubleEndedIterator, ExactSizeIterator};
|
use core::iter::{DoubleEndedIterator, ExactSizeIterator};
|
||||||
|
|||||||
@@ -28,9 +28,10 @@
|
|||||||
//! At this time, to generate Rust code, you will need the latest `master` version of `flatc`, available from here: <https://github.com/google/flatbuffers>
|
//! At this time, to generate Rust code, you will need the latest `master` version of `flatc`, available from here: <https://github.com/google/flatbuffers>
|
||||||
//! (On OSX, you can install FlatBuffers from `HEAD` with the Homebrew package manager.)
|
//! (On OSX, you can install FlatBuffers from `HEAD` with the Homebrew package manager.)
|
||||||
|
|
||||||
#![cfg_attr(feature = "no_std", no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
#![cfg_attr(all(nightly, not(feature = "std")), feature(error_in_core))]
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(not(feature = "std"))]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
mod array;
|
mod array;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
use crate::follow::Follow;
|
use crate::follow::Follow;
|
||||||
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
|
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(not(feature = "std"))]
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
use core::option::Option;
|
use core::option::Option;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(all(nightly, not(feature = "std")))]
|
||||||
use thiserror::Error;
|
use core::error::Error;
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "std")]
|
||||||
use thiserror_core2::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
/// Traces the location of data errors. Not populated for Dos detecting errors.
|
/// Traces the location of data errors. Not populated for Dos detecting errors.
|
||||||
/// Useful for MissingRequiredField and Utf8Error in particular, though
|
/// Useful for MissingRequiredField and Utf8Error in particular, though
|
||||||
@@ -41,64 +41,138 @@ impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
|
|||||||
|
|
||||||
/// Describes how a flatuffer is invalid and, for data errors, roughly where. No extra tracing
|
/// 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.
|
/// 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 {
|
pub enum InvalidFlatbuffer {
|
||||||
#[error("Missing required field `{required}`.\n{error_trace}")]
|
|
||||||
MissingRequiredField {
|
MissingRequiredField {
|
||||||
required: &'static str,
|
required: &'static str,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
#[error(
|
|
||||||
"Union exactly one of union discriminant (`{field_type}`) and value \
|
|
||||||
(`{field}`) are present.\n{error_trace}"
|
|
||||||
)]
|
|
||||||
InconsistentUnion {
|
InconsistentUnion {
|
||||||
field: &'static str,
|
field: &'static str,
|
||||||
field_type: &'static str,
|
field_type: &'static str,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
#[error("Utf8 error for string in {range:?}: {error}\n{error_trace}")]
|
|
||||||
Utf8Error {
|
Utf8Error {
|
||||||
#[source]
|
|
||||||
error: core::str::Utf8Error,
|
error: core::str::Utf8Error,
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
#[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
|
|
||||||
range.start, range.end)]
|
|
||||||
MissingNullTerminator {
|
MissingNullTerminator {
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
#[error("Type `{unaligned_type}` at position {position} is unaligned.\n{error_trace}")]
|
|
||||||
Unaligned {
|
Unaligned {
|
||||||
position: usize,
|
position: usize,
|
||||||
unaligned_type: &'static str,
|
unaligned_type: &'static str,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
#[error("Range [{}, {}) is out of bounds.\n{error_trace}", range.start, range.end)]
|
|
||||||
RangeOutOfBounds {
|
RangeOutOfBounds {
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
#[error(
|
|
||||||
"Signed offset at position {position} has value {soffset} which points out of bounds.\
|
|
||||||
\n{error_trace}"
|
|
||||||
)]
|
|
||||||
SignedOffsetOutOfBounds {
|
SignedOffsetOutOfBounds {
|
||||||
soffset: SOffsetT,
|
soffset: SOffsetT,
|
||||||
position: usize,
|
position: usize,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
// Dos detecting errors. These do not get error traces since it will probably be very large.
|
// Dos detecting errors. These do not get error traces since it will probably be very large.
|
||||||
#[error("Too many tables.")]
|
|
||||||
TooManyTables,
|
TooManyTables,
|
||||||
#[error("Apparent size too large.")]
|
|
||||||
ApparentSizeTooLarge,
|
ApparentSizeTooLarge,
|
||||||
#[error("Nested table depth limit reached.")]
|
|
||||||
DepthLimitReached,
|
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 {
|
impl core::fmt::Display for ErrorTrace {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
use ErrorTraceDetail::*;
|
use ErrorTraceDetail::*;
|
||||||
|
|||||||
@@ -21,3 +21,10 @@ cargo run --bin=flatbuffers_alloc_check || exit /b 1
|
|||||||
cargo run --bin=flexbuffers_alloc_check || exit /b 1
|
cargo run --bin=flexbuffers_alloc_check || exit /b 1
|
||||||
cargo run --bin=monster_example || exit /b 1
|
cargo run --bin=monster_example || exit /b 1
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
cd rust_no_std_compilation_test
|
||||||
|
rustup install nightly
|
||||||
|
rustup component add rust-src --toolchain nightly
|
||||||
|
rustup target add thumbv7m-none-eabi
|
||||||
|
cargo build || exit /b 1
|
||||||
|
cd ..
|
||||||
|
|||||||
@@ -35,11 +35,18 @@ cd ./rust_serialize_test
|
|||||||
cargo run $TARGET_FLAG -- --quiet
|
cargo run $TARGET_FLAG -- --quiet
|
||||||
check_test_result "Rust serde tests"
|
check_test_result "Rust serde tests"
|
||||||
|
|
||||||
|
cd ../rust_no_std_compilation_test
|
||||||
|
rustup install nightly
|
||||||
|
rustup component add rust-src --toolchain nightly
|
||||||
|
rustup target add thumbv7m-none-eabi
|
||||||
|
cargo +nightly build
|
||||||
|
check_test_result "Rust flatbuffers test no_std compilation"
|
||||||
|
|
||||||
cd ../rust_usage_test
|
cd ../rust_usage_test
|
||||||
cargo test $TARGET_FLAG -- --quiet
|
cargo test $TARGET_FLAG -- --quiet
|
||||||
check_test_result "Rust tests"
|
check_test_result "Rust tests"
|
||||||
|
|
||||||
cargo test $TARGET_FLAG --no-default-features --features no_std -- --quiet
|
cargo test $TARGET_FLAG --no-default-features -- --quiet
|
||||||
check_test_result "Rust tests (no_std)"
|
check_test_result "Rust tests (no_std)"
|
||||||
|
|
||||||
cargo run $TARGET_FLAG --bin=flatbuffers_alloc_check
|
cargo run $TARGET_FLAG --bin=flatbuffers_alloc_check
|
||||||
|
|||||||
5
tests/rust_no_std_compilation_test/.cargo/config.toml
Normal file
5
tests/rust_no_std_compilation_test/.cargo/config.toml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[build]
|
||||||
|
target = "thumbv7m-none-eabi"
|
||||||
|
|
||||||
|
[unstable]
|
||||||
|
build-std = ["core", "alloc"]
|
||||||
13
tests/rust_no_std_compilation_test/Cargo.toml
Normal file
13
tests/rust_no_std_compilation_test/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust_test_no_std_compilation"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
flatbuffers = { path = "../../rust/flatbuffers", default-features = false }
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
34
tests/rust_no_std_compilation_test/src/main.rs
Normal file
34
tests/rust_no_std_compilation_test/src/main.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(default_alloc_error_handler)]
|
||||||
|
|
||||||
|
// Include flatbuffers purely to check that it compiles in a no_std binary
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use flatbuffers;
|
||||||
|
|
||||||
|
// The rest is just no_std boilerplate
|
||||||
|
|
||||||
|
use core::alloc::{GlobalAlloc, Layout};
|
||||||
|
|
||||||
|
struct NullAllocator;
|
||||||
|
unsafe impl GlobalAlloc for NullAllocator {
|
||||||
|
unsafe fn alloc(&self, _lt: Layout) -> *mut u8 {
|
||||||
|
core::ptr::null_mut()
|
||||||
|
}
|
||||||
|
unsafe fn dealloc(&self, _ptr: *mut u8, _lt: Layout) {
|
||||||
|
panic!("won't deallocate: we never allocated!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static A: NullAllocator = NullAllocator;
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ libc_alloc = { version = "1.0.3", optional = true }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["flatbuffers/default"]
|
default = ["flatbuffers/default"]
|
||||||
no_std = ["flatbuffers/no_std", "libc_alloc"]
|
no_std = ["libc_alloc"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "monster_example"
|
name = "monster_example"
|
||||||
|
|||||||
Reference in New Issue
Block a user