Skip to content

Commit

Permalink
feat: check Definition::Enum’s tag_width when validating schema (#…
Browse files Browse the repository at this point in the history
…224)

* feat: check Enum’s tag width when validating schema

* chore: add `Declaration`-s to validate errors to simplify finding error

---------

Co-authored-by: dj8yf0μl <[email protected]>
  • Loading branch information
mina86 and dj8yf0μl authored Sep 18, 2023
1 parent d22259a commit d8828e1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
22 changes: 17 additions & 5 deletions borsh/src/schema/container_ext/validate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::is_zero_size;
use super::{BorshSchemaContainer, Declaration, Definition, Fields};
use crate::__private::maybestd::vec::Vec;
use crate::__private::maybestd::{string::ToString, vec::Vec};

impl BorshSchemaContainer {
/// Validates container for violation of any well-known rules with
Expand All @@ -25,11 +25,13 @@ impl BorshSchemaContainer {

/// Possible error when validating a [`BorshSchemaContainer`], generated for some type `T`,
/// for violation of any well-known rules with respect to `borsh` serialization.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum SchemaContainerValidateError {
/// sequences of zero-sized types of dynamic length are forbidden by definition
/// see <https://github.com/near/borsh-rs/pull/202> and related ones
ZSTSequence,
ZSTSequence(Declaration),
/// Declared tag width is too large. Tags may be at most eight bytes.
TagTooWide(Declaration),
}

fn validate_impl<'a>(
Expand All @@ -56,11 +58,21 @@ fn validate_impl<'a>(
// or it uses `Definiotion::Enum` or `Definition::Sequence` to exit from recursion
// which make it non-zero size
if is_zero_size(elements, schema).unwrap_or(false) {
return Err(SchemaContainerValidateError::ZSTSequence);
return Err(SchemaContainerValidateError::ZSTSequence(
declaration.to_string(),
));
}
validate_impl(elements, schema, stack)?;
}
Definition::Enum { variants, .. } => {
Definition::Enum {
tag_width,
variants,
} => {
if *tag_width > 8 {
return Err(SchemaContainerValidateError::TagTooWide(
declaration.to_string(),
));
}
for (_, variant) in variants {
validate_impl(variant, schema, stack)?;
}
Expand Down
8 changes: 6 additions & 2 deletions borsh/tests/test_schema_validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ fn validate_for_derived_types() {

#[test]
fn validate_for_zst_sequences() {
test_err::<Vec<Vec<()>>>(SchemaContainerValidateError::ZSTSequence);
test_err::<Vec<core::ops::RangeFull>>(SchemaContainerValidateError::ZSTSequence);
test_err::<Vec<Vec<()>>>(SchemaContainerValidateError::ZSTSequence(
"Vec<nil>".to_string(),
));
test_err::<Vec<core::ops::RangeFull>>(SchemaContainerValidateError::ZSTSequence(
"Vec<RangeFull>".to_string(),
));
}

0 comments on commit d8828e1

Please sign in to comment.