dash_runtime/limits.rs
1//! Hostile-input bounds for MPD parsing and segment expansion.
2//!
3//! An MPD is fetched from a server the player does not control, so every
4//! dimension of it that costs memory or CPU has a named ceiling and a typed
5//! error ([`crate::error::MpdError::TooLarge`]) instead of an allocation.
6
7/// Largest MPD document accepted, in bytes.
8pub const MAX_MPD_BYTES: usize = broadcast_common::xml_chars::MAX_XML_BYTES;
9/// Deepest element nesting accepted.
10pub const MAX_XML_DEPTH: usize = broadcast_common::xml_chars::MAX_XML_DEPTH;
11/// Most elements (of any namespace) accepted in one document.
12pub const MAX_XML_ELEMENTS: usize = broadcast_common::xml_chars::MAX_XML_ELEMENTS;
13/// Longest single attribute value accepted, in bytes.
14pub const MAX_ATTRIBUTE_BYTES: usize = broadcast_common::xml_chars::MAX_XML_ATTRIBUTE_BYTES;
15/// Most attributes accepted on one element.
16pub const MAX_ATTRIBUTES_PER_ELEMENT: usize = broadcast_common::xml_chars::MAX_XML_ATTRIBUTES;
17/// Most `Period` elements accepted.
18pub const MAX_PERIODS: usize = 1_000;
19/// Most `AdaptationSet` elements accepted in one `Period`.
20pub const MAX_ADAPTATION_SETS_PER_PERIOD: usize = 1_000;
21/// Most `Representation` elements accepted in one `AdaptationSet`.
22pub const MAX_REPRESENTATIONS_PER_SET: usize = 1_000;
23/// Most `S` entries accepted in one `SegmentTimeline`.
24pub const MAX_TIMELINE_ENTRIES: usize = 100_000;
25/// Most `BaseURL` alternates accepted on one level.
26pub const MAX_BASE_URLS_PER_LEVEL: usize = 64;
27/// Most `SegmentURL` entries accepted in one `SegmentList`.
28pub const MAX_SEGMENT_URLS: usize = 100_000;
29/// Most Media Segments one `SegmentTimeline` may describe once `@r` is
30/// expanded. The expansion is lazy (run table, never one entry per segment),
31/// so this bounds the arithmetic, not the memory.
32pub const MAX_TIMELINE_SEGMENTS: u64 = 1_000_000;
33/// Most candidate base locations kept when `BaseURL` alternates are combined
34/// across levels.
35pub const MAX_BASE_CANDIDATES: usize = 64;
36
37/// The bounds applied by [`crate::mpd::Mpd::parse_with`]; `Default` is the
38/// `MAX_*` constants above.
39#[derive(Debug, Clone, PartialEq, Eq)]
40#[non_exhaustive]
41pub struct Limits {
42 /// See [`MAX_MPD_BYTES`].
43 pub max_bytes: usize,
44 /// See [`MAX_XML_DEPTH`].
45 pub max_depth: usize,
46 /// See [`MAX_XML_ELEMENTS`].
47 pub max_elements: usize,
48 /// See [`MAX_ATTRIBUTE_BYTES`].
49 pub max_attribute_bytes: usize,
50 /// See [`MAX_ATTRIBUTES_PER_ELEMENT`].
51 pub max_attributes: usize,
52 /// See [`MAX_PERIODS`].
53 pub max_periods: usize,
54 /// See [`MAX_ADAPTATION_SETS_PER_PERIOD`].
55 pub max_adaptation_sets: usize,
56 /// See [`MAX_REPRESENTATIONS_PER_SET`].
57 pub max_representations: usize,
58 /// See [`MAX_TIMELINE_ENTRIES`].
59 pub max_timeline_entries: usize,
60 /// See [`MAX_BASE_URLS_PER_LEVEL`].
61 pub max_base_urls: usize,
62 /// See [`MAX_SEGMENT_URLS`].
63 pub max_segment_urls: usize,
64}
65
66impl Limits {
67 /// The XML-level subset of these bounds as the shared
68 /// [`XmlLimits`](broadcast_common::xml_chars::XmlLimits) the MPD reader
69 /// enforces through an [`XmlBudget`](broadcast_common::xml_chars::XmlBudget).
70 #[must_use]
71 pub fn xml_limits(&self) -> broadcast_common::xml_chars::XmlLimits {
72 let mut xml = broadcast_common::xml_chars::XmlLimits::default();
73 xml.max_bytes = self.max_bytes;
74 xml.max_depth = self.max_depth;
75 xml.max_elements = self.max_elements;
76 xml.max_attribute_bytes = self.max_attribute_bytes;
77 xml.max_attributes = self.max_attributes;
78 xml
79 }
80}
81
82impl Default for Limits {
83 fn default() -> Self {
84 Self {
85 max_bytes: MAX_MPD_BYTES,
86 max_depth: MAX_XML_DEPTH,
87 max_elements: MAX_XML_ELEMENTS,
88 max_attribute_bytes: MAX_ATTRIBUTE_BYTES,
89 max_attributes: MAX_ATTRIBUTES_PER_ELEMENT,
90 max_periods: MAX_PERIODS,
91 max_adaptation_sets: MAX_ADAPTATION_SETS_PER_PERIOD,
92 max_representations: MAX_REPRESENTATIONS_PER_SET,
93 max_timeline_entries: MAX_TIMELINE_ENTRIES,
94 max_base_urls: MAX_BASE_URLS_PER_LEVEL,
95 max_segment_urls: MAX_SEGMENT_URLS,
96 }
97 }
98}