1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//! Budgets that bound the work and memory a reader spends on untrusted input.
/// Budgets for reading untrusted files.
///
/// Every reader checks its input against these before allocating for it. Section data,
/// symbol records, and relocation records are also bounded by the input itself (a
/// reader copies at most as many bytes of section data as the file holds, however its
/// headers overlap), so the budgets that matter most are the ones on names: a hostile
/// file can point many symbols at one long string, and only `max_name_bytes` stops that
/// from multiplying.
///
/// The defaults sit far above what compilers produce and far below what would exhaust
/// a machine. The struct is `#[non_exhaustive]`: start from [`Limits::default`] and
/// change fields.
///
/// | Field | Default | Bounds |
/// |---|---|---|
/// | `max_sections` | 1,048,576 | section headers |
/// | `max_symbols` | 16,777,216 | symbol table entries |
/// | `max_relocations` | 67,108,864 | relocation records, all sections together |
/// | `max_name_len` | 65,536 bytes | one section or symbol name |
/// | `max_name_bytes` | 268,435,456 bytes (256 MiB) | all names together, as copied out |
///
/// # Examples
///
/// ```
/// use object_lang::{Architecture, Limits, Object, ReadError, Section, SectionKind};
///
/// let mut obj = Object::relocatable(Architecture::X86_64);
/// obj.add_section(Section::new(".text", SectionKind::Text));
/// obj.add_section(Section::new(".data", SectionKind::Data));
/// let bytes = object_lang::elf::write(&obj)?;
///
/// let mut limits = Limits::default();
/// limits.max_sections = 3;
/// assert_eq!(
/// object_lang::elf::read_with_limits(&bytes, &limits),
/// Err(ReadError::LimitExceeded { limit: "max_sections" }),
/// );
/// # Ok::<(), object_lang::WriteError>(())
/// ```