///|
pub(all) struct Limits {
max_units : Int
max_lines : Int
max_line_units : Int
} derive(Eq, Debug, ToJson)
///|
pub fn Limits::default() -> Limits {
{ max_units: 262144, max_lines: 20000, max_line_units: 8192, }
}
///|
pub fn parse(source : String) -> Document {
parse_with_limits(source, Limits::default())
}
///|
/// Limits may be tightened, not raised beyond hard safety ceilings. Refusal
/// returns original source and FNT900, with no misleading partial parse.
pub fn parse_with_limits(source : String, limits : Limits) -> Document {
let hard = Limits::default()
let mut reason = ""
let mut line = 1
if limits.max_units < 1 ||
limits.max_units > hard.max_units ||
limits.max_lines < 1 ||
limits.max_lines > hard.max_lines ||
limits.max_line_units < 1 ||
limits.max_line_units > hard.max_line_units {
reason = "Invalid limits: values must be positive and no greater than default ceilings"
} else if source.length() > limits.max_units {
reason = "Input exceeds UTF-16 unit budget"
} else {
let lines = source_lines(source)
if lines.length() > limits.max_lines {
reason = "Input exceeds line budget"
} else {
for item in lines {
if item.end - item.start > limits.max_line_units {
reason = "Input exceeds per-line UTF-16 unit budget"
line = item.number
break
}
}
}
}
if reason != "" {
return {
source,
elements: [],
annotations: [],
diagnostics: [{ code: "FNT900", line, message: reason, }],
}
}
parse_unchecked(source)
}