Skip to content

fix: bound jinja scalar range render probes - #1553

Merged
mldangelo-oai merged 6 commits into
mainfrom
mdangelo/codex/fix-jinja-render-limits
Jun 9, 2026
Merged

mldangelo-oai merged 6 commits into
mainfrom
mdangelo/codex/fix-jinja-render-limits

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Jun 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • fail closed when statically reachable sandbox range work exceeds Jinja's MAX_RANGE and the render worker is unavailable
  • preserve execution order and binding state across branches, loops, macros, caller blocks, namespaces, assignment blocks, aliases, varargs, kwargs, and bounded literal unpacking
  • resolve range, integer, scalar, and macro values through nested literal containers while respecting dict method-vs-item lookup semantics
  • carry possibly-undefined branch bindings into default / d and .get() fallback analysis
  • bound static traversal, range projection, container paths, destructuring, macro candidates, formal argument cleanup, and unpacked argument projection

Critical review fixes

  • closed false negatives in branch-only bindings, macro fallbacks, nested containers, typed keys, scalar conversions, and special macro arguments
  • closed false positives in filtered loops, definitely-defined defaults, namespace/assignment-block values, and dict method collisions
  • added fail-closed limits for exponential container aliases and wide or repeated macro argument binding

Validation

  • exact published head: 73bf639e0da7fb6d0933df0ad01da62e1c9fb918
  • exact published tree: 54637b4b959f61346dea50acbaf48a1fcac611a2
  • merged current main: 838f25046fb94fe018b18a5a2a84e4aef3ed969e
  • associated Jinja scanner suite: 410 passed, 1 skipped (expected optional gguf dependency unavailable)
  • adversarial differential matrix: 25/25 expected outcomes
  • scoped Ruff check and format check: clean
  • scoped mypy: clean
  • git diff --check: clean

All reviewed inline threads were resolved before publication.

@github-actions

github-actions Bot commented Jun 8, 2026 •

Copy link
Copy Markdown
Contributor

Workflow run and artifacts

Performance Benchmarks

Compared 12 shared benchmarks with a regression threshold of 15%.
Status: 0 regressions, 0 improved, 12 stable, 0 new, 0 missing.
Aggregate shared-benchmark median: 1.381s -> 1.378s (-0.2%).

Workload Benchmark Target Size Files Baseline Current Change Status
padded-multi-stream-upload tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_padded_multi_stream_upload multi_stream_padded 4.1 KiB 1 523.3us 542.3us +3.6% stable
suspicious-pickle-intake tests/benchmarks/test_scan_benchmarks.py::test_scan_suspicious_pickle_intake suspicious-intake 183.8 KiB 4 125.75ms 122.16ms -2.9% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_base64] nested_base64 98 B 1 461.8us 468.8us +1.5% stable
clean-training-checkpoint tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_clean_training_checkpoint safe_large 278.2 KiB 1 109.89ms 111.04ms +1.1% stable
direct-malicious-upload tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_direct_malicious_upload malicious_reduce 52 B 1 431.3us 434.9us +0.8% stable
duplicate-heavy-registry tests/benchmarks/test_scan_benchmarks.py::test_scan_duplicate_registry_snapshot registry-snapshot 915.2 KiB 13 393.01ms 390.42ms -0.7% stable
chunked-upload-stream tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_chunked_upload_stream chunked_stream 278.2 KiB 1 113.12ms 113.85ms +0.7% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_raw] nested_raw 78 B 1 466.7us 463.8us -0.6% stable
warm-cache-rescan tests/benchmarks/test_scan_benchmarks.py::test_scan_warm_cached_repository_rescan release-candidate 547.3 KiB 32 93.57ms 94.02ms +0.5% stable
single-checkpoint-preflight tests/benchmarks/test_scan_benchmarks.py::test_scan_single_checkpoint_before_load single_checkpoint.pkl 183.0 KiB 1 72.04ms 71.88ms -0.2% stable
mixed-model-repository tests/benchmarks/test_scan_benchmarks.py::test_scan_release_candidate_repository release-candidate 547.3 KiB 32 470.90ms 471.84ms +0.2% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_hex] nested_hex 130 B 1 492.3us 493.2us +0.2% stable

Copy link
Copy Markdown
Contributor Author

Critical review found additional worker-unavailable false negatives, so this is not merge-ready yet.

The eager filter list now covers direct min / max / sum, but full-range work can still hide behind lazy chains:

  • range(...)|slice(...)|first materializes the entire range before yielding the first slice
  • range(...)|select(...)|first and reject(...)|first may scan the entire range before producing no item
  • range(...)|map(...)|reverse and range(...)|reverse|reverse materialize a non-reversible iterator

I prepared and validated a context-sensitive fix that preserves cheap direct first, reverse|first, and map|first cases. Focused result: 172 passed, 1 optional gguf skip; scoped Ruff, format, mypy, and diff checks are clean. Local follow-up commit: e9123d95 (after merging current main).

Publication is currently blocked because shell GitHub credentials are unavailable and the connector has no patch-based write endpoint for these large files. Do not merge the current remote head.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review June 8, 2026 21:13

Copy link
Copy Markdown
Contributor Author

Critical review complete and the branch is synchronized with current main.

The original one-line filter expansion coupled scalar CPU work to the output-character budget, causing both false positives and false negatives. The revised implementation follows Jinja's actual sandbox invariant (MAX_RANGE=100000), detects oversized range construction before consumption, resolves common aliases and namespaces, and avoids flagging templates that shadow range.

Adversarial coverage includes direct reductions, lazy/default wrappers, assigned values, function alias chains, tuple and conditional bindings, namespaces, higher-order consumers, exact-boundary benign cases, macro shadowing, and overwritten aliases.

Focused QA: 178 passed, 1 skipped; scoped Ruff and mypy are clean. Exact tree 7679aee5b9b29cdb033c07c833b226d028fcb93e was verified before publishing.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9c55361ba

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 72adba986c

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread tests/scanners/test_jinja2_template_scanner.py Fixed

Copy link
Copy Markdown
Contributor Author

Critical review follow-up published at 941f096 (exact tree de2822c2310161efb7159481253606f2b03762e6) after merging current main.

Addressed all remaining feedback:

  • preserved assigned deltas for saturated range bounds, including clean 100000 / failing 100001 boundaries
  • propagated range, integer, namespace, default, keyword, and macro-alias arguments into macro bodies with recursion protection
  • merged feasible if/elif/else alias state back into Jinja's enclosing assignment scope
  • split the accidentally concatenated test inputs called out by code quality

QA:

  • 227 passed, 1 skipped in tests/scanners/test_jinja2_template_scanner.py (optional gguf unavailable)
  • 2,000 randomized saturated-bound cases: 0 mismatches
  • 500 randomized macro propagation cases: 0 mismatches
  • macro-heavy scaling checked through 2,000 definitions (roughly linear)
  • Ruff format/check clean across mandated paths
  • mypy clean across 464 source files
  • git diff --check clean

All review threads are resolved. CI is running on the exact published head; moving to the next PR now and will revisit this one later.

Comment thread tests/scanners/test_jinja2_template_scanner.py Fixed
Comment thread tests/scanners/test_jinja2_template_scanner.py Fixed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 941f0968a2

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
@mldangelo-oai
mldangelo-oai marked this pull request as draft June 9, 2026 08:16

Copy link
Copy Markdown
Contributor Author

Addressed all five outstanding Jinja fallback findings in 6626749e and refreshed onto current main in d2ad2eb0:

  • defer macro-body analysis until a reachable macro call
  • preserve macro bindings through tuple unpacking
  • recognize one-iteration saturated-step ranges
  • compare opposite-signed saturated power magnitudes
  • track NSRef aliases only for confirmed namespace() objects
  • make the two intentional test-string concatenations explicit

Validation after the main refresh: 232 passed, 1 skipped in the Jinja scanner suite; scoped Ruff, format, mypy, and diff checks are clean. The required broad lane reached 3,384 passed, 2 skipped before stopping on five unrelated current-main cache/compressed/optional-native failures; full mypy has only the five known macOS os.*xattr stub errors.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review June 9, 2026 08:50
@mldangelo-oai
mldangelo-oai enabled auto-merge (squash) June 9, 2026 08:50
@mldangelo-oai
mldangelo-oai requested a review from mldangelo June 9, 2026 08:50

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2ad2eb096

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py
@mldangelo-oai
mldangelo-oai marked this pull request as draft June 9, 2026 08:55
auto-merge was automatically disabled June 9, 2026 08:55

Pull request was converted to draft

Copy link
Copy Markdown
Contributor Author

Addressed the three reachability findings in a29a7889 and refreshed onto current main in 1af248bc.

  • Literal list/tuple loop items now bind loop targets per possible iteration and merge those states, so for r in [range] carries the callable alias.
  • Statically empty ranges and literal iterables skip the unreachable loop body and inspect only the else arm.
  • Omitted macro defaults are scanned before binding, so an oversized range(...) default cannot bypass the worker-unavailable fallback.

The Jinja suite passes 235 tests with one unrelated optional-GGUF skip after the main refresh. Scoped Ruff, format, mypy, and diff checks are clean. The required broad lane reached 3,500 passed, 7 skipped before five unrelated cache/compressed/optional-native failures; full mypy only has the five known macOS os.*xattr stub errors.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review June 9, 2026 09:12
@mldangelo-oai
mldangelo-oai enabled auto-merge (squash) June 9, 2026 09:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1af248bc5c

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py
Comment thread modelaudit/scanners/jinja2_template_scanner.py
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
@mldangelo-oai
mldangelo-oai marked this pull request as draft June 9, 2026 09:24
auto-merge was automatically disabled June 9, 2026 09:24

Pull request was converted to draft

Copy link
Copy Markdown
Contributor Author

Addressed the third review wave in 64bed1ea and refreshed onto current main in cb8ea7ff.

  • Namespace attribute mutations on pre-existing namespace objects now propagate out of loops; definite non-empty loops use the final state and possibly-empty loops conservatively merge it.
  • Constant inline conditionals inspect only the selected expression.
  • Tuple aliases are propagated only when target and value arities match.
  • Static macro expansion stops when a keyword duplicates a positionally supplied argument, matching Jinja's pre-body call failure.

The Jinja suite passes 239 tests with one unrelated optional-GGUF skip after refresh. Scoped Ruff, format, mypy, and diff checks are clean. The required broad lane reached 3,603 passed, 3 skipped before four unrelated cache/compressed/optional-native failures; full mypy only has the five known macOS os.*xattr stub errors.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review June 9, 2026 09:40
@mldangelo-oai
mldangelo-oai enabled auto-merge (squash) June 9, 2026 09:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb8ea7ffbf

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
@mldangelo-oai
mldangelo-oai marked this pull request as draft June 9, 2026 09:46
auto-merge was automatically disabled June 9, 2026 09:46

Pull request was converted to draft

Copy link
Copy Markdown
Contributor Author

Addressed the latest review wave in f8dd006b: namespace-stored and aliased macros are now replayed at reachable Getattr call sites, and unknown macro keywords stop expansion unless the macro intentionally consumes Jinja kwargs. The valid kwargs path retains range/macro bindings. Jinja suite: 245 passed, 1 skipped; full lane reached 3,631 passed, 7 skipped before the four known unrelated local baseline failures.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review June 9, 2026 10:04
@mldangelo-oai
mldangelo-oai enabled auto-merge (squash) June 9, 2026 10:04

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f8dd006b5d

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py
@mldangelo-oai
mldangelo-oai marked this pull request as draft June 9, 2026 10:10
auto-merge was automatically disabled June 9, 2026 10:10

Pull request was converted to draft

@mldangelo-oai
mldangelo-oai force-pushed the mdangelo/codex/fix-jinja-render-limits branch from ec6f993 to f5d11c2 Compare June 9, 2026 10:53
@mldangelo-oai
mldangelo-oai marked this pull request as ready for review June 9, 2026 10:53
@mldangelo-oai
mldangelo-oai marked this pull request as draft June 9, 2026 10:54

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f5d11c21e9

ℹ️ 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".

Comment thread modelaudit/scanners/jinja2_template_scanner.py
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated
Comment thread modelaudit/scanners/jinja2_template_scanner.py Outdated

Copy link
Copy Markdown
Contributor Author

Review follow-up published at 677e65b0610949e3f49d9e1fa412cef6bce5e600. This closes the shadowed-range, recursive/exponential macro, container lookup/unpacking, saturated arithmetic, modular power, and long numeric-string false-positive/false-negative gaps found during adversarial QA. The associated Jinja scanner suite is 319 passed with one expected optional-gguf skip; scoped Ruff, format, mypy, and diff checks are clean. Keeping the PR draft only because it still depends on the shared baseline in #1597.

Copy link
Copy Markdown
Contributor Author

Critical review and QA are complete on exact head 18d8681a112468ce2a47e7eb07bad3ff2fb1ab02 (tree 732d8f25eb82541c170dfa81898d6aa8b11dfd59).

The review found and fixed both false-negative and false-positive classes around branch-only bindings, default/d, .get(), nested dict method collisions, namespace and assignment-block definitions, loop comparisons, typed keys, scalar conversions, macro arguments, and kwargs/varargs shadowing. It also closed main-process CPU amplification in nested container paths and wide/repeated macro argument projection, including omitted formal-argument cleanup.

Focused validation: 410 passed, 1 skipped (optional gguf), scoped Ruff/format/mypy clean, git diff --check clean, adversarial matrix 25/25. All live inline threads were resolved before this publication.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review June 9, 2026 13:54

Copy link
Copy Markdown
Contributor Author

main advanced during the merge attempt, so I refreshed the exact reviewed tree onto 838f25046fb94fe018b18a5a2a84e4aef3ed969e. New exact head: 73bf639e0da7fb6d0933df0ad01da62e1c9fb918; tree: 54637b4b959f61346dea50acbaf48a1fcac611a2. The associated Jinja suite remains 410 passed, 1 skipped; scoped Ruff, format, mypy, and diff checks remain clean.

@mldangelo-oai
mldangelo-oai merged commit c00542e into main Jun 9, 2026
2 checks passed
@mldangelo-oai
mldangelo-oai deleted the mdangelo/codex/fix-jinja-render-limits branch June 9, 2026 13:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 73bf639e0d

ℹ️ 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".

active_macros,
):
return True
condition = self._constant_condition_value(node.test)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass bindings when folding inline conditions

Earlier {% set %} constants are ignored when choosing an inline-if branch. With worker unavailable, {% set c=false %}{{ range(100001)|min if c else 0 }} renders 0, but the static pass treats c as unknown and scans the oversized branch, causing a false failure. guidance

Useful? React with 👍 / 👎.

if boolean_value is None:
return True
boolean_mode = boolean_value
known, value = cls._constant_condition_scalar(node.node)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass bindings into default fallback checks

This evaluates default input without current bindings, so earlier truthy values look unknown. With worker unavailable, {% set v=1 %}{{ (v|default(range,true))(100001)|min }} never uses range, but the fallback treats the default as possible and reports a budget failure. guidance

Useful? React with 👍 / 👎.

Comment on lines +3168 to +3169
for child in macro.body
for candidate in child.find_all(jinja2.nodes.Name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip nested macros when detecting special macro args

This recursive find_all counts kwargs/varargs loads inside nested macro definitions as if the outer macro consumed them. With worker unavailable, {% macro m() %}{% macro inner() %}{{ kwargs }}{% endmacro %}{{ range(100001)|min }}{% endmacro %}{{ m(foo=1) }} is expanded and flagged, but Jinja rejects the unknown keyword before m runs. guidance

Useful? React with 👍 / 👎.

@github-actions github-actions Bot mentioned this pull request Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant