Repository navigation
Cap LaTeX math conversion depth so nested frac/scripts cannot overflow the stack - #357
Merged
Merged
Conversation
…w the stack latex_math_to_plain recursed through convert() for every nested \frac, ^, _, \sqrt, and \text with no depth limit. Model or user markdown with a few hundred nested groups can blow an 8 MiB TUI/API thread stack. Stop converting after 64 levels and emit the remaining raw fragment, matching json.cpp. Co-authored-by: Tyler Reckart <tylerreckart@users.noreply.github.com>
This was referenced Sep 19, 2026
…ion-depth # Conflicts: # CHANGELOG.md
tylerreckart
marked this pull request as ready for review
September 21, 2026 12:58
tylerreckart
enabled auto-merge (squash)
September 21, 2026 12:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
latex_math_to_plainrecursed throughconvert()for every nested\frac,^,_,\sqrt, and\textwith no depth limit. TUI and HTTP markdown both call this on model and user text. A few hundred nested groups — easy to emit from a model or paste — can overflow an 8 MiB worker thread stack and kill the process. The JSON parser already caps nesting for the same reason (json.cpp::kMaxDepth).Fix
Thread a depth counter through
convert/convert_script. After 64 levels, emit the remaining raw fragment instead of recursing. 64 is deeper than any legitimate equation and far below the stack limit. Shallow nested fractions and scripts still convert as before.Tests
unit_markdown_diff:\frac{\frac{a}{b}}{c}anda^{b^{2}}still convert.\fracgroups return a finite string (slash form on the converted prefix, raw\fracpast the cap) instead of overflowing.\[...\]display-math path also survive.Suite 50/50 locally (281 assertions) + ASan + UBSan.
arbitercompiles.Independently mergeable against
main(0456350). Does not touch files owned by #321–#356 except CHANGELOG[Unreleased], which sibling-conflicts after the first of those merges, same as the rest of the series.Note
Low Risk
Localized defensive change to LaTeX-to-plain conversion with a documented depth cap; normal equations unchanged, only extreme nesting degrades to raw fragments instead of crashing.
Overview
Fixes a stack-overflow risk when the TUI/API render LaTeX in markdown:
latex_math_to_plainnow tracks recursion depth and stops converting after 64 nested\frac,^,_,\sqrt, or\textgroups, emitting the rest as raw TeX instead of recursing further.Depth is threaded through internal
convert/convert_scriptcalls (same entry point as before for callers). Shallow math still converts to Unicode as today; pathological model/user input no longer blows the worker thread stack. Header and[Unreleased]changelog document the cap.Tests add modest nested fraction/script cases, 400-level
\fracand superscript nests (finite output with raw\fracpast the cap), and aMarkdownRenderer\[...\]path over deeply nested math.Reviewed by Cursor Bugbot for commit 6e41648. Bugbot is set up for automated code reviews on this repo. Configure here.