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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Centralized DoS / resource caps for individual builtins.
//!
//! These constants are referenced by the threat model (TM-DOS-*).
//! Keeping them in one place makes auditing easier: every adjustment
//! lands in a single file, so a reviewer can read all per-builtin
//! limits without grepping the tree.
//!
//! Tunable runtime limits that are part of a public config surface
//! (e.g. `PythonLimits`, `TypeScriptLimits`, `SqliteLimits`, ssh
//! defaults) live on their own config types and are intentionally
//! NOT mirrored here.
/// Max width/precision for printf-style format specifiers to prevent
/// memory exhaustion. Shared by `printf` and `awk`.
pub const MAX_FORMAT_WIDTH: usize = 10_000;
/// archive: cap on decompression expansion ratio (zip-bomb guard).
pub const ARCHIVE_MAX_DECOMPRESSION_RATIO: usize = 100;
/// awk: max parser recursion depth.
pub const AWK_MAX_PARSER_DEPTH: usize = 100;
/// awk: max comma-separated subscripts in one array key.
pub const AWK_MAX_MULTI_SUBSCRIPTS: usize = 100;
/// awk: max user-function call depth at runtime.
pub const AWK_MAX_CALL_DEPTH: usize = 64;
/// awk: total output byte cap per invocation.
pub const AWK_MAX_OUTPUT_BYTES: usize = 10_000_000;
/// awk: max distinct output redirection targets per invocation.
pub const AWK_MAX_OUTPUT_TARGETS: usize = 1_024;
/// awk: max distinct files held open by `getline < file`.
pub const AWK_MAX_GETLINE_CACHED_FILES: usize = 100;
/// awk: max bytes read from one `getline < file` input.
pub const AWK_MAX_GETLINE_FILE_BYTES: usize = 10_000_000;
/// awk: max total bytes retained by all `getline < file` inputs.
pub const AWK_MAX_GETLINE_CACHE_BYTES: usize = 10_000_000;
/// awk: max bytes in one string value (concat, sub/gsub/gensub, sprintf,
/// rebuilt `$0`). THREAT[TM-DOS-110].
pub const AWK_MAX_STRING_BYTES: usize = 16 * 1024 * 1024;
/// awk: max field index for `$N = ...`. THREAT[TM-DOS-110].
pub const AWK_MAX_FIELD_INDEX: usize = 100_000;
/// awk: accounted per-entry overhead for a variable or array element.
pub const AWK_VARIABLE_OVERHEAD_BYTES: usize = 48;
/// Max compiled runtime regexes retained by one evaluator.
pub const RUNTIME_REGEX_CACHE_ENTRIES: usize = 64;
/// curl: max number of HTTP redirects to follow.
pub const CURL_MAX_REDIRECTS: u32 = 10;
/// curl: max aggregate request bytes for all data variants and multipart assembly.
pub const CURL_MAX_REQUEST_BODY_BYTES: usize = 10_000_000;
/// expand/unexpand: max accepted tab stop width.
pub const EXPAND_MAX_TAB_STOP: usize = 10_000;
/// expand: max output bytes per invocation before interpreter-level truncation.
pub const EXPAND_MAX_OUTPUT_BYTES: usize = 1_048_576;
/// dirs/pushd/popd: max entries on the directory stack.
pub const DIRSTACK_MAX_SIZE: usize = 4096;
/// dirs/pushd/popd: max UTF-8 bytes per restored directory-stack entry.
pub const DIRSTACK_MAX_ENTRY_BYTES: usize = 4096;
/// find: total stdout cap for default and `-printf` output.
pub const FIND_MAX_OUTPUT_BYTES: usize = 1_048_576;
/// mktemp: max name-collision retries before giving up.
pub const MKTEMP_MAX_ATTEMPTS: usize = 64;
/// numfmt: total output / padding / precision cap.
pub const NUMFMT_MAX_OUTPUT_BYTES: usize = 1_048_576;
/// parallel: cap on Cartesian product expansion.
pub const PARALLEL_MAX_CARTESIAN_PRODUCT: usize = 100_000;
/// printf: max diagnostic message length.
pub const PRINTF_MAX_DIAG_CHARS: usize = 1_024;
/// retry: max retry attempts.
pub const RETRY_MAX_ATTEMPTS: u32 = 10_000;
/// sed: max group-nesting depth in `s` replacements.
pub const SED_MAX_GROUP_NESTING_DEPTH: usize = 128;
/// sed: max instructions executed for one input line, bounding `b`/`t` loops.
/// THREAT[TM-DOS]: sed scripts are untrusted text and `:a;ba` never terminates.
pub const SED_MAX_CYCLE_STEPS: usize = 1_000;
/// sleep: max sleep duration.
pub const SLEEP_MAX_SECONDS: f64 = 60.0;
/// template: max template-expansion recursion depth.
pub const TEMPLATE_MAX_DEPTH: usize = 100;
/// timeout: max timeout duration in seconds (5 minutes).
pub const TIMEOUT_MAX_SECONDS: u64 = 300;
/// yes: max lines and total output bytes per invocation.
pub const YES_MAX_LINES: usize = 10_000;
pub const YES_MAX_OUTPUT_BYTES: usize = 1_048_576;
/// seq: max lines per invocation.
pub const SEQ_MAX_LINES: usize = 100_000;
/// seq: max output bytes per invocation.
pub const SEQ_MAX_OUTPUT_BYTES: usize = 1_048_576;
/// dd: max bytes one invocation moves (THREAT[TM-DOS-003]: `/dev/zero`
/// and `/dev/urandom` are unbounded sources).
pub const DD_MAX_BYTES: usize = 64 * 1024 * 1024;
/// Result for a builtin that stopped early at one of the caps above.
///
/// Decision (#2446): reaching a cap is never silent. The output produced so
/// far is kept, stderr names the command and the cap, and the exit status is
/// 1, so scripts and agents cannot mistake a cut result for a complete one.
pub