Skip to content

[Rust] Support alloc-only no_std platforms #5366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conan/travis/build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash

set -e
set -x
Expand Down
2 changes: 1 addition & 1 deletion conan/travis/install.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash

set -e
set -x
Expand Down
2 changes: 1 addition & 1 deletion grpc/build_grpc.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash

grpc_1_39_0_githash=58602e20a3f3e48f24a4114c757099b25b947f7b

Expand Down
2 changes: 1 addition & 1 deletion grpc/examples/generate.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2021 Google Inc. All rights reserved.
#
Expand Down
2 changes: 1 addition & 1 deletion grpc/examples/go/format.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2021 Google Inc. All rights reserved.
#
Expand Down
2 changes: 1 addition & 1 deletion reflection/generate_code.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2016 Google Inc. All rights reserved.
#
Expand Down
6 changes: 5 additions & 1 deletion rust/flatbuffers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ rust = "1.51"
[dependencies]
smallvec = "1.6.1"
bitflags = "1.2.1"
thiserror = "1.0.23"
thiserror = { version = "1.0.23", optional = true }

[features]
default = ["std"]
std = ["thiserror"]
6 changes: 3 additions & 3 deletions rust/flatbuffers/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
use crate::follow::Follow;
use crate::vector::VectorIter;
use crate::EndianScalar;
use std::fmt::{Debug, Formatter, Result};
use std::marker::PhantomData;
use std::mem::size_of;
use core::fmt::{Debug, Formatter, Result};
use core::marker::PhantomData;
use core::mem::size_of;

#[derive(Copy, Clone)]
pub struct Array<'a, T: 'a, const N: usize>(&'a [u8], PhantomData<T>);
Expand Down
11 changes: 6 additions & 5 deletions rust/flatbuffers/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@

extern crate smallvec;

use std::cmp::max;
use std::iter::{DoubleEndedIterator, ExactSizeIterator};
use std::marker::PhantomData;
use std::ptr::write_bytes;
use std::slice::from_raw_parts;
use alloc::{vec, vec::Vec};
use core::cmp::max;
use core::iter::{DoubleEndedIterator, ExactSizeIterator};
use core::marker::PhantomData;
use core::ptr::write_bytes;
use core::slice::from_raw_parts;

use crate::endian_scalar::{emplace_scalar, read_scalar_at};
use crate::primitives::*;
Expand Down
2 changes: 1 addition & 1 deletion rust/flatbuffers/src/endian_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
#![allow(clippy::wrong_self_convention)]

use std::mem::size_of;
use core::mem::size_of;

/// Trait for values that must be stored in little-endian byte order, but
/// might be represented in memory as big-endian. Every type that implements
Expand Down
2 changes: 1 addition & 1 deletion rust/flatbuffers/src/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

use std::marker::PhantomData;
use core::marker::PhantomData;

/// Follow is a trait that allows us to access FlatBuffers in a declarative,
/// type safe, and fast way. They compile down to almost no code (after
Expand Down
8 changes: 8 additions & 0 deletions rust/flatbuffers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@
//! 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.)

#![no_std]

// Needed for thiserror
#[cfg(feature = "std")]
extern crate std;

extern crate alloc;

mod array;
mod builder;
mod endian_scalar;
Expand Down
6 changes: 3 additions & 3 deletions rust/flatbuffers/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/

use std::marker::PhantomData;
use std::mem::size_of;
use std::ops::Deref;
use core::marker::PhantomData;
use core::mem::size_of;
use core::ops::Deref;

use crate::endian_scalar::{emplace_scalar, read_scalar, read_scalar_at};
use crate::follow::Follow;
Expand Down
4 changes: 2 additions & 2 deletions rust/flatbuffers/src/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*/

use std::cmp::max;
use std::mem::{align_of, size_of};
use core::cmp::max;
use core::mem::{align_of, size_of};

use crate::endian_scalar::emplace_scalar;

Expand Down
12 changes: 6 additions & 6 deletions rust/flatbuffers/src/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
* limitations under the License.
*/

use std::fmt::{Debug, Formatter, Result};
use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
use std::marker::PhantomData;
use std::mem::size_of;
use std::slice::from_raw_parts;
use std::str::from_utf8_unchecked;
use core::fmt::{Debug, Formatter, Result};
use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
use core::marker::PhantomData;
use core::mem::size_of;
use core::slice::from_raw_parts;
use core::str::from_utf8_unchecked;

use crate::endian_scalar::read_scalar_at;
#[cfg(target_endian = "little")]
Expand Down
79 changes: 49 additions & 30 deletions rust/flatbuffers/src/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::follow::Follow;
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
use std::ops::Range;
use alloc::vec::Vec;
use core::ops::Range;

#[cfg(feature = "std")]
use thiserror::Error;

/// Traces the location of data errors. Not populated for Dos detecting errors.
Expand All @@ -23,7 +26,7 @@ pub enum ErrorTraceDetail {
}
#[derive(PartialEq, Eq, Default, Debug, Clone)]
pub struct ErrorTrace(Vec<ErrorTraceDetail>);
impl std::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
#[inline]
fn as_ref(&self) -> &[ErrorTraceDetail] {
&self.0
Expand All @@ -32,66 +35,82 @@ impl std::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {

/// 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)]
#[cfg_attr(feature = "std", derive(Error))]
pub enum InvalidFlatbuffer {
#[error("Missing required field `{required}`.\n{error_trace}")]
#[cfg_attr(
feature = "std",
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 \
#[cfg_attr(
feature = "std",
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}")]
#[cfg_attr(
feature = "std",
error("Utf8 error for string in {range:?}: {error}\n{error_trace}")
)]
Utf8Error {
#[source]
error: std::str::Utf8Error,
#[cfg_attr(feature = "std", 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)]
#[cfg_attr(feature = "std", 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}")]
#[cfg_attr(
feature = "std",
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)]
#[cfg_attr(feature = "std", 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.\
#[cfg_attr(
feature = "std",
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.")]
#[cfg_attr(feature = "std", error("Too many tables."))]
TooManyTables,
#[error("Apparent size too large.")]
#[cfg_attr(feature = "std", error("Apparent size too large."))]
ApparentSizeTooLarge,
#[error("Nested table depth limit reached.")]
#[cfg_attr(feature = "std", error("Nested table depth limit reached."))]
DepthLimitReached,
}

impl std::fmt::Display for ErrorTrace {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
impl core::fmt::Display for ErrorTrace {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use ErrorTraceDetail::*;
for e in self.0.iter() {
match e {
Expand Down Expand Up @@ -125,7 +144,7 @@ impl std::fmt::Display for ErrorTrace {
}
}

pub type Result<T> = std::prelude::v1::Result<T, InvalidFlatbuffer>;
pub type Result<T> = core::prelude::v1::Result<T, InvalidFlatbuffer>;

impl InvalidFlatbuffer {
fn new_range_oob<T>(start: usize, end: usize) -> Result<T> {
Expand Down Expand Up @@ -245,11 +264,11 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
/// `buffer[0]`. TODO(caspern).
#[inline]
fn is_aligned<T>(&self, pos: usize) -> Result<()> {
if pos % std::mem::align_of::<T>() == 0 {
if pos % core::mem::align_of::<T>() == 0 {
Ok(())
} else {
Err(InvalidFlatbuffer::Unaligned {
unaligned_type: std::any::type_name::<T>(),
unaligned_type: core::any::type_name::<T>(),
position: pos,
error_trace: Default::default(),
})
Expand All @@ -271,7 +290,7 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
#[inline]
pub fn in_buffer<T>(&mut self, pos: usize) -> Result<()> {
self.is_aligned::<T>(pos)?;
self.range_in_buffer(pos, std::mem::size_of::<T>())
self.range_in_buffer(pos, core::mem::size_of::<T>())
}
#[inline]
fn get_u16(&mut self, pos: usize) -> Result<u16> {
Expand Down Expand Up @@ -416,7 +435,7 @@ impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
where
Key: Follow<'buf> + Verifiable,
UnionVerifier:
(std::ops::FnOnce(<Key as Follow<'buf>>::Inner, &mut Verifier, usize) -> Result<()>),
(core::ops::FnOnce(<Key as Follow<'buf>>::Inner, &mut Verifier, usize) -> Result<()>),
// NOTE: <Key as Follow<'buf>>::Inner == Key
{
// TODO(caspern): how to trace vtable errors?
Expand Down Expand Up @@ -468,14 +487,14 @@ impl<T: Verifiable> Verifiable for ForwardsUOffset<T> {
}

/// Checks and returns the range containing the flatbuffers vector.
fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<std::ops::Range<usize>> {
fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<core::ops::Range<usize>> {
let len = v.get_uoffset(pos)? as usize;
let start = pos.saturating_add(SIZE_UOFFSET);
v.is_aligned::<T>(start)?;
let size = len.saturating_mul(std::mem::size_of::<T>());
let size = len.saturating_mul(core::mem::size_of::<T>());
let end = start.saturating_add(size);
v.range_in_buffer(start, size)?;
Ok(std::ops::Range { start, end })
Ok(core::ops::Range { start, end })
}

pub trait SimpleToVerifyInSlice {}
Expand Down Expand Up @@ -509,7 +528,7 @@ impl<T: Verifiable> Verifiable for Vector<'_, ForwardsUOffset<T>> {
#[inline]
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
let range = verify_vector_range::<ForwardsUOffset<T>>(v, pos)?;
let size = std::mem::size_of::<ForwardsUOffset<T>>();
let size = core::mem::size_of::<ForwardsUOffset<T>>();
for (i, element_pos) in range.step_by(size).enumerate() {
trace_elem(
<ForwardsUOffset<T>>::run_verifier(v, element_pos),
Expand All @@ -526,7 +545,7 @@ impl<'a> Verifiable for &'a str {
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
let range = verify_vector_range::<u8>(v, pos)?;
let has_null_terminator = v.buffer.get(range.end).map(|&b| b == 0).unwrap_or(false);
let s = std::str::from_utf8(&v.buffer[range.clone()]);
let s = core::str::from_utf8(&v.buffer[range.clone()]);
if let Err(error) = s {
return Err(InvalidFlatbuffer::Utf8Error {
error,
Expand Down
2 changes: 1 addition & 1 deletion rust/flatbuffers/src/vtable_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

use std::ptr::write_bytes;
use core::ptr::write_bytes;

use crate::endian_scalar::emplace_scalar;
use crate::primitives::*;
Expand Down
2 changes: 1 addition & 1 deletion samples/csharp_sample.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2015 Google Inc. All rights reserved.
#
Expand Down
2 changes: 1 addition & 1 deletion samples/dart_sample.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -euo
#
# Copyright 2018 Dan Field. All rights reserved.
Expand Down
2 changes: 1 addition & 1 deletion samples/go_sample.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2015 Google Inc. All rights reserved.
#
Expand Down
2 changes: 1 addition & 1 deletion samples/java_sample.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2015 Google Inc. All rights reserved.
#
Expand Down
2 changes: 1 addition & 1 deletion samples/javascript_sample.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2015 Google Inc. All rights reserved.
#
Expand Down
2 changes: 1 addition & 1 deletion samples/kotlin_sample.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Copyright 2015 Google Inc. All rights reserved.
#
Expand Down
Loading