Repository navigation
Settings::Limits: bounds on what one Load or Render may do (0262) - #601
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
…Load, output checked per step With every limit at its default a render takes no new per-step work: a render with limits makes CheckStack take its slow path, which counts the step and checks the output size. Parse limits live in a thread-local set for the Load. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
…nternal sequence cap Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
…9 loop in the defaults pass Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
…s uint64 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
…ds as uint64 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sRZrdyAGVT1hBgARAkNAE
…elector and the cycle collector); close 0262 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
|
@codex review @codex security review Generated by Claude Code |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f3b25cd6d9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…rce; parse limits in FindUndeclaredVariables Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh
|
@codex review Re-requesting after 4068f2f: the template-size check now runs before the source is copied or read, and parse limits now apply in FindUndeclaredVariables. Generated by Claude Code |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Merge train 29: Settings::Limits (#601)
One ResourceLimitError (src/engine_errors.h) serves Settings::Limits, named by its field, and the built-in caps, without one; CurrentExceptionToError reports both as ResourceLimitExceeded with the field as extraParams[1] when present, so Render's own catch for it is gone. The built-in sequence cap throws it instead of std::length_error. exception.h, engine_errors.h and error_boundary.h are wrapped in v2 by scripts/abi_namespace.py. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sRZrdyAGVT1hBgARAkNAE
#601 brought TemplateDict with defaulted noexcept moves over an OrderedMap, whose moves allocate on MSVC; a bad_alloc there in a dict literal's render terminated (jinja2cpp_alloc_tests, Windows static jobs). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sRZrdyAGVT1hBgARAkNAE
Requested by Ruslan · project thread
Before: a host that renders untrusted templates has no way to bound them. The only limits are fixed depth limits and an internal 2^26 cap on sequence size, and both are compiled in. A
{% for i in range(10**9) %}runs to completion. Nothing boundsrange(), output size, template size, template loads or render time.After:
Settings::Limitshas 11 fields, each enforced and tested:maxRange,maxSequenceSize,maxOutputSize,maxTemplateSize,maxTemplateLoads,maxRenderSteps,maxRenderTime,maxRenderDepth(256),maxExpressionDepth(64),maxExpressionOperators(400) andmaxBlockNesting(128). The presets areUntrustedLimits()andUntrustedSettings(); the second also turns autoescape on. A limit that trips reportsErrorCode::ResourceLimitExceeded(18), withextraParams[0]the message and[1]the field name. The depth limits still reportRecursionLimitExceeded. The defaults keep today's behaviour, and 0 means no limit.The design is in docs/api-2.0.md §2.1 and docs/tasks/0262, which this PR marks done. docs/api-2.0.md §3.3 gains a paragraph.
How. With limits off, nothing new runs on the render path.
CheckStack()takes its slow path. That path counts the step, checks the output size, and polls the clock every 16 steps, after host callables and at render end. Then it does the real stack check.Parse(), and around the re-parse inFindUndeclaredVariables, so the parser's layout is unchanged.range(), sequence size and template loads are checked where the old caps were.iffilter counts the items it skips.Settings::operator==runs on every Load and compares the limits word by word without branches. A static_assert checks that the struct has no padding.Perf. Measured with
bench/count.py, in instructions, limits off.UntrustedLimits().The performance track approved the numbers on f3b25cd. The final head only adds the size check before the copy, and its preflight gate is clean.
Deliberately not here:
maxSequenceSize. That is 0263; the header says the presets do not bound memory.maxBlockNesting = 0;Ordering with #597 (0253). Both PRs add
ResourceLimitExceeded = 18with the same meaning, so the merge conflict is one line.Files outside 0262's
touches: src/value_visitors.h (string repeat), src/internal_value., src/load_settings.h, src/expression_parser., src/template_parser.cpp, src/template.cpp (Load overloads), CMakeLists.txt (new test file).Roles and reviews:
max).FindUndeclaredVariablesre-parsed without the template's limits.🤖 Generated with Claude Code
https://claude.ai/code/session_01USAwpuAiFNpCMNpcRmwvsh