Skip to main content

Budget

Struct Budget 

Source
#[non_exhaustive]
pub struct Budget {
Show 21 fields pub max_reader_input_bytes: Option<usize>, pub max_buffered_comment_events: usize, pub simple_key_max_lookahead: usize, pub flow_nesting_limit: usize, pub max_events: usize, pub max_aliases: usize, pub max_anchors: usize, pub max_recorded_anchor_events: usize, pub max_recorded_anchor_bytes: usize, pub max_property_expansion_depth: usize, pub max_total_property_interpolation_work: usize, pub max_depth: usize, pub max_inclusion_depth: u32, pub max_documents: usize, pub max_nodes: usize, pub max_total_scalar_bytes: usize, pub max_total_comment_bytes: usize, pub max_merge_keys: usize, pub enforce_alias_anchor_ratio: bool, pub alias_anchor_min_aliases: usize, pub alias_anchor_ratio_multiplier: usize,
}
Expand description

Resource budgets for YAML parsing and deserialization.

The defaults are intentionally permissive for typical configuration files while stopping obvious resource-amplifying inputs. Tune these per your application if you regularly process very large YAML streams.

Example: using a Budget with from_str_with_options to parse into a small Config struct.

use serde::Deserialize;

#[derive(Debug, Deserialize, PartialEq)]
struct Config {
    name: String,
    enabled: bool,
    retries: i32,
}

let yaml = r#"
  name: My Application
  enabled: true
  retries: 5
"#;

let options = serde_saphyr::options! {
    budget: serde_saphyr::budget! {
        // Example override
        max_documents: 2,
    },
};

let cfg: Config = serde_saphyr::from_str_with_options(yaml, options).unwrap();
assert_eq!(cfg.retries, 5);

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§max_reader_input_bytes: Option<usize>

Hard cap on the size of the input in bytes. This limit only applies to reader-based input, to avoid resource exhaustion from large malicious inputs (even when they are valid YAML). String inputs can be checked by the caller when needed because they are already in memory. If the limit is exceeded, serde_saphyr::Error::IOError is returned with a std::io::Error cause using ErrorKind::FileTooLarge.

If set to None, this check is not active. This may be needed when reading from stream into iterator, where potentially infinite input may need to be supported.

Default: 256 Mb

§max_buffered_comment_events: usize

Maximum number of consecutive comment events the parser may buffer while resolving an ambiguous collection entry.

A value of 0 rejects the first comment that would need buffering.

Default: 32

§simple_key_max_lookahead: usize

Maximum number of characters the scanner may inspect while resolving a simple key.

A key at exactly this limit is accepted. Values above 1,024 relax YAML’s simple-key length restriction, while lower values impose a stricter resource limit.

Default: 1,024

§flow_nesting_limit: usize

Maximum number of simultaneously nested flow collections.

A value of 0 rejects the first flow collection opener.

Default: 255

§max_events: usize

Maximum total parser events (counting every event).

Default: 1,000,000

§max_aliases: usize

Maximum number of alias (*ref) events allowed.

Default: 50,000

§max_anchors: usize

Maximal total number of anchors (distinct &anchor definitions).

Default: 50,000

§max_recorded_anchor_events: usize

Maximum cumulative number of event copies attempted for anchor retention.

An event copied into multiple simultaneously open anchored containers is charged once for every destination buffer. Scalar anchor buffers and events recorded while replaying aliases are charged by the same limit.

Default: 1_000_000 retained event copies.

§max_recorded_anchor_bytes: usize

Maximum cumulative bytes of owned string payload attempted for retained anchor events.

This counts owned scalar values and explicit tag spellings before each retained clone. Borrowed input text is excluded because cloning its std::borrow::Cow does not copy the referenced bytes. Budget::max_recorded_anchor_events separately limits the fixed-size event storage for both borrowed and owned input.

Default: 67_108_864 bytes (64 MiB).

§max_property_expansion_depth: usize

Maximum nested operator-text expansions in one property interpolation.

The root scalar is not included. This limit is used only when the properties feature is enabled and a property map is configured, or when PropertySyntax::DockerCompose or PropertySyntax::DockerComposeWithNulls is selected with an empty map.

Default: 64

§max_total_property_interpolation_work: usize

Maximum cumulative property-interpolation work across one deserialization stream.

Work is measured in attacker-controlled input bytes inspected while scanning property references and nested operator text. This limit is used only when the properties feature is enabled and a property map is configured, or when PropertySyntax::DockerCompose or PropertySyntax::DockerComposeWithNulls is selected with an empty map.

Default: 268,435,456 (256 MiB of byte inspections)

§max_depth: usize

Maximum structural nesting depth (sequences + mappings).

This also raises the parser’s block-collection nesting limit as needed. The separate Self::flow_nesting_limit remains an independent cap on flow collections.

Default: 64

§max_inclusion_depth: u32

Maximum allowed !include nesting depth.

This limits how many nested included parsers may be active below the root document at once. A value of 0 disables includes entirely.

Default: 24

§max_documents: usize

Maximum number of YAML documents in the stream.

Default: 1,024. If the budget scope is “per document”, this is ignored.

§max_nodes: usize

Maximum number of nodes (SequenceStart/MappingStart/Scalar).

Default: 250,000

§max_total_scalar_bytes: usize

Maximum total bytes of scalar contents plus explicit tag spellings.

Default: 67,108,864 (64 MiB)

§max_total_comment_bytes: usize

Maximum total bytes of comment contents.

Comment text may be copied and retained for crate::Commented support, so this limit is enforced before deserialization stores comment text.

Default: 67,108,864 (64 MiB)

§max_merge_keys: usize

Maximum number of merge keys (<<) allowed across the stream when merge-key expansion is enabled.

Default: 10,000

§enforce_alias_anchor_ratio: bool

If true, enforce the alias/anchor heuristic.

The heuristic flags inputs that use an excessive number of aliases relative to the number of defined anchors.

Default: true

§alias_anchor_min_aliases: usize

Minimum number of aliases required before the alias/anchor ratio heuristic is evaluated. This avoids tiny-input false positives.

Default: 100

§alias_anchor_ratio_multiplier: usize

Multiplier used for the alias/anchor ratio heuristic. A breach occurs when aliases > alias_anchor_ratio_multiplier * anchors (after scanning), once Budget::alias_anchor_min_aliases is met.

Default: 10

Trait Implementations§

Source§

impl Clone for Budget

Source§

fn clone(&self) -> Budget

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Budget

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Budget

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.