// Defensive resource limits for untrusted security.txt input.
//
// RFC 9116 warns that malicious or misconfigured files may be excessively large; the
// defaults below are conservative project-defined choices, not protocol limits.
// See docs/limitations.md.
///|
/// Resource limits applied while parsing.
pub struct Limits {
max_input_bytes : Int
max_lines : Int
max_line_bytes : Int
max_fields : Int
max_field_value_bytes : Int
} derive(Eq, Debug)
///|
/// Conservative defaults suitable for untrusted input.
pub fn Limits::default() -> Limits {
{
max_input_bytes: 32 * 1024,
max_lines: 1000,
max_line_bytes: 4096,
max_fields: 1000,
max_field_value_bytes: 2048,
}
}
///|
/// Tighter limits for constrained or high-risk callers.
pub fn Limits::strict() -> Limits {
{
max_input_bytes: 16 * 1024,
max_lines: 512,
max_line_bytes: 1024,
max_fields: 256,
max_field_value_bytes: 1024,
}
}
///|
/// Relaxed limits for controlled environments.
pub fn Limits::permissive() -> Limits {
{
max_input_bytes: 8 * 1024 * 1024,
max_lines: 131072,
max_line_bytes: 65536,
max_fields: 32768,
max_field_value_bytes: 65536,
}
}
///|
/// Build custom limits. Negative values fall back to the default.
pub fn Limits::custom(
max_input_bytes : Int,
max_lines : Int,
max_line_bytes : Int,
max_fields : Int,
max_field_value_bytes : Int,
) -> Limits {
let d = Limits::default()
let pick = fn(v : Int, fallback : Int) { if v > 0 { v } else { fallback } }
{
max_input_bytes: pick(max_input_bytes, d.max_input_bytes),
max_lines: pick(max_lines, d.max_lines),
max_line_bytes: pick(max_line_bytes, d.max_line_bytes),
max_fields: pick(max_fields, d.max_fields),
max_field_value_bytes: pick(max_field_value_bytes, d.max_field_value_bytes),
}
}
///|
/// Maximum input size in bytes.
pub fn Limits::max_input_bytes(self : Limits) -> Int {
self.max_input_bytes
}
///|
/// Maximum number of physical lines.
pub fn Limits::max_lines(self : Limits) -> Int {
self.max_lines
}
///|
/// Maximum length of one physical line in bytes (excluding the line break).
pub fn Limits::max_line_bytes(self : Limits) -> Int {
self.max_line_bytes
}
///|
/// Maximum number of field lines (standard and extension combined).
pub fn Limits::max_fields(self : Limits) -> Int {
self.max_fields
}
///|
/// Maximum length of one field value in bytes.
pub fn Limits::max_field_value_bytes(self : Limits) -> Int {
self.max_field_value_bytes
}