Stack overflow on deeply nested LaTeX input
The parser and layout engine in affected versions of `latex-rust` recurse once per level of nesting with no limit. Deeply nested input, such as `\frac{1}{…}`, braces, `\sqrt{…}`, `\left(`, or superscripts nested hundreds or thousands of levels deep, exhausts the call stack. A stack overflow in Rust aborts the process. It is not a panic, so it cannot be caught with `catch_unwind`. A program that renders LaTeX from untrusted input can therefore be terminated by a short string. With a release build on an 8 MiB stack, 700 nested `\frac{1}{…}` (about 7 KB of input) abort version 1.0.4, and 10,000 nested braces (about 20 KB) abort it as well. The threshold is lower on smaller stacks and in debug builds; on a 2 MiB thread in a debug build, about 35 nested fractions are enough. ```rust let mut src = String::from("1"); for _ in 0..700 { src = format!("\\frac{{1}}{{{src}}}"); } let _ = latex_rust::parse(&src); // stack overflow, process aborts ``` The fixed versions count nesting depth in the parser and in `layout` and refuse input that nests more than 32 levels. `parse`, `parse_with_colors`, and the `latex_to_*` functions return `ParseError::Malformed("input nests deeper than 32 levels")`, and `layout` returns `Error::Unsupported { what: "tree nests deeper than 32 levels" }` for a tree built by hand. The count is of parser recursion levels, and a braced argument costs two, so the limit admits 15 nested `\frac`, `\sqrt`, or `x^{…}`, and 31 nested groups, `\left…\right` pairs, or enviro
RUSTSEC-2026-0311
Primary source · Revision 1
Imported from structured advisory data. Source references identify upstream records or fields; verify affected versions and your deployed configuration.
Security context
Source reference: osv:RUSTSEC-2026-0311
latex-rust
Source reference: /affected/0/package/name
- Affected versions
- Not stated in this record
- Fixed versions
- 1.0.5
Source reference:
/affected/0/ranges - Prerequisites
- Not stated in this record
Structured affected-version data
Original package identities and version rules from this source.
[
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0.0.0-0"
},
{
"fixed": "1.0.5"
}
]
}
],
"package": {
"name": "latex-rust",
"purl": "pkg:cargo/latex-rust",
"ecosystem": "crates.io"
},
"database_specific": {
"cvss": null,
"source": "https://github.com/rustsec/advisory-db/blob/osv/crates/RUSTSEC-2026-0311.json",
"categories": [
"denial-of-service"
],
"informational": null
},
"ecosystem_specific": {
"affects": {
"os": [],
"arch": [],
"functions": [
"latex_rust::latex_to_png",
"latex_rust::latex_to_shapes",
"latex_rust::latex_to_svg",
"latex_rust::layout",
"latex_rust::layout_with_numbering",
"latex_rust::parse",
"latex_rust::parse_with_colors"
]
},
"affected_functions": null
}
}
]Publisher severity
No explicit severity was provided.
- Event
- #21278 · Revision 1
- Added to Heist Feed
- Publisher date