Skip to content

Commit

Permalink
Binary limits (#16684)
Browse files Browse the repository at this point in the history
## Description 

Organize better several limits...

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and do not break anything, you can
skip the following section. Otherwise, please briefly describe what has
changed under the Release Notes section.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes

---------

Co-authored-by: Ashok Menon <[email protected]>
Co-authored-by: Stefan Stanciulescu <[email protected]>
  • Loading branch information
3 people authored Mar 16, 2024
1 parent 662294d commit b80a2c9
Show file tree
Hide file tree
Showing 161 changed files with 22,881 additions and 591 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fn invalid_struct_with_actuals_in_field() {
match &mut m.struct_defs[0].field_information {
StructFieldInformation::Declared(ref mut fields) => {
fields[0].signature.0 =
StructInstantiation(StructHandleIndex::new(0), vec![TypeParameter(0)]);
StructInstantiation(Box::new((StructHandleIndex::new(0), vec![TypeParameter(0)])));
assert_eq!(
BoundsChecker::verify_module(&m).unwrap_err().major_status(),
StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ fn big_vec_unpacks() {
const N_TYPE_PARAMS: usize = 16;
let mut st = SignatureToken::Vector(Box::new(SignatureToken::U8));
let type_params = vec![st; N_TYPE_PARAMS];
st = SignatureToken::StructInstantiation(StructHandleIndex(0), type_params);
st = SignatureToken::StructInstantiation(Box::new((StructHandleIndex(0), type_params)));
const N_VEC_PUSH: u16 = 1000;
let mut code = vec![];
// 1. CopyLoc: ... -> ... st
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ fn big_signature_test() {
}
for _ in 0..INSTANTIATION_DEPTH {
let type_params = vec![st; N_TYPE_PARAMS];
st = SignatureToken::StructInstantiation(StructHandleIndex(0), type_params);
st = SignatureToken::StructInstantiation(Box::new((StructHandleIndex(0), type_params)));
}

const N_READPOP: u16 = 7500;
Expand Down
5 changes: 4 additions & 1 deletion crates/invalid-mutations/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,10 @@ fn struct_handle(token: &SignatureToken) -> Option<StructHandleIndex> {

match token {
Struct(sh_idx) => Some(*sh_idx),
StructInstantiation(sh_idx, _) => Some(*sh_idx),
StructInstantiation(struct_inst) => {
let (sh_idx, _) = &**struct_inst;
Some(*sh_idx)
},
Reference(token) | MutableReference(token) => struct_handle(token),
Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address | Signer | Vector(_)
| TypeParameter(_) => None,
Expand Down
101 changes: 101 additions & 0 deletions crates/move-binary-format/src/binary_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) The Move Contributors
// SPDX-License-Identifier: Apache-2.0


use crate::file_format_common::VERSION_MAX;

/// Configuration for the binary format related to table size.
/// Maps to all tables in the binary format.
#[derive(Clone, Debug)]
pub struct TableConfig {
pub module_handles: u16,
pub struct_handles: u16,
pub function_handles: u16,
pub function_instantiations: u16,
pub signatures: u16,
pub constant_pool: u16,
pub identifiers: u16,
pub address_identifiers: u16,
pub struct_defs: u16,
pub struct_def_instantiations: u16,
pub function_defs: u16,
pub field_handles: u16,
pub field_instantiations: u16,
pub friend_decls: u16,
}

impl TableConfig {
// The deserializer and other parts of the system already have limits in place,
// this is the "legacy" configuration that is effectively the "no limits" setup.
// This table is a noop with `u16::MAX`.
pub fn legacy() -> Self {
TableConfig {
module_handles: u16::MAX,
struct_handles: u16::MAX,
function_handles: u16::MAX,
function_instantiations: u16::MAX,
signatures: u16::MAX,
constant_pool: u16::MAX,
identifiers: u16::MAX,
address_identifiers: u16::MAX,
struct_defs: u16::MAX,
struct_def_instantiations: u16::MAX,
function_defs: u16::MAX,
field_handles: u16::MAX,
field_instantiations: u16::MAX,
friend_decls: u16::MAX,
}
}
}

/// Configuration information for deserializing a binary.
/// Controls multiple aspects of the deserialization process.
#[derive(Clone, Debug)]
pub struct BinaryConfig {
pub max_binary_format_version: u32,
pub check_no_extraneous_bytes: bool,
pub table_config: TableConfig,
}

impl BinaryConfig {
pub fn new(
max_binary_format_version: u32,
check_no_extraneous_bytes: bool,
table_config: TableConfig,
) -> Self {
Self {
max_binary_format_version,
check_no_extraneous_bytes,
table_config,
}
}

// We want to make this disappear from the public API in favor of a "true" config
pub fn legacy(max_binary_format_version: u32, check_no_extraneous_bytes: bool) -> Self {
Self {
max_binary_format_version,
check_no_extraneous_bytes,
table_config: TableConfig::legacy(),
}
}

/// Run always with the max version but with controllable "extraneous bytes check"
pub fn with_extraneous_bytes_check(check_no_extraneous_bytes: bool) -> Self {
Self {
max_binary_format_version: VERSION_MAX,
check_no_extraneous_bytes,
table_config: TableConfig::legacy(),
}
}

/// VERSION_MAX and check_no_extraneous_bytes = true
/// common "standard/default" in code base now
pub fn standard() -> Self {
Self {
max_binary_format_version: VERSION_MAX,
check_no_extraneous_bytes: true,
table_config: TableConfig::legacy(),
}
}
}

3 changes: 2 additions & 1 deletion crates/move-binary-format/src/binary_views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ impl<'a> BinaryIndexedView<'a> {
let sh = self.struct_handle_at(*idx);
Ok(sh.abilities)
}
StructInstantiation(idx, type_args) => {
StructInstantiation(struct_inst) => {
let (idx, type_args) = &**struct_inst;
let sh = self.struct_handle_at(*idx);
let declared_abilities = sh.abilities;
let type_arguments = type_args
Expand Down
5 changes: 3 additions & 2 deletions crates/move-binary-format/src/check_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,8 @@ impl<'a> BoundsChecker<'a> {
}
}
}
StructInstantiation(idx, type_params) => {
StructInstantiation(struct_inst) => {
let (idx, type_params) = &**struct_inst;
check_bounds_impl(self.view.struct_handles(), *idx)?;
if let Some(sh) = self.view.struct_handles().get(idx.into_index()) {
if sh.type_parameters.len() != type_params.len() {
Expand Down Expand Up @@ -616,7 +617,7 @@ impl<'a> BoundsChecker<'a> {
| Reference(_)
| MutableReference(_)
| Vector(_)
| StructInstantiation(_, _) => (),
| StructInstantiation(_) => (),
}
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/move-binary-format/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn sig_to_ty(sig: &SignatureToken) -> Option<MoveTypeLayout> {
| SignatureToken::MutableReference(_)
| SignatureToken::Struct(_)
| SignatureToken::TypeParameter(_)
| SignatureToken::StructInstantiation(_, _) => None,
| SignatureToken::StructInstantiation(_) => None,
}
}

Expand Down
Loading

0 comments on commit b80a2c9

Please sign in to comment.