Skip to content

Avoid unchecked list indexing in JSON encoder - #9431

Merged
youknowone merged 1 commit into
RustPython:mainfrom
youknowdot:youknowdot/json-list-read-315-20261028
Oct 28, 2026
Merged

youknowone merged 1 commit into
RustPython:mainfrom
youknowdot:youknowdot/json-list-read-315-20261028

Conversation

@youknowdot

@youknowdot youknowdot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The native JSON list encoder checks the live length and fetches an item under separate list guards. A concurrent shrink can invalidate the index between those operations.

Use a checked, cloned item lookup under one read guard. If the item disappeared, stop before emitting a separator and finish through the existing marker-cleanup path. The guard is released before recursive encoding or Python callbacks. This preserves live callback-deletion semantics rather than taking a whole-list snapshot.

Only crates/stdlib/src/json.rs changes. No Lib assertions, skips, dependency pins, or pending free-threading-package files are changed.

Validation

  • Focused CLI/VM/stdlib cargo check and strict Clippy (-D warnings) passed.
  • Repository hooks passed, including rustfmt and cspell.
  • Bounded executable build passed; all five selected existing JSON tests passed (0 skips).

Local validation used main 3b0dd785; the encoder source is unchanged in current main, and current-main integration awaits CI.

The selected tests check the native encoder, ten-item callback deletion, small circular-reference/marker cleanup cases, and indentation. They are not a concurrent-race or general free-threading compatibility claim. Full workspace, C-API, concurrency stress, and GC/UAF-specific regressions were not run locally; hosted CI remains pending.

AI assistance

OpenAI Codex assisted with the implementation, CPython source comparison, validation, and this pull request description; the model version is unavailable.

Summary by CodeRabbit

  • Bug Fixes
    • JSON encoding now stops safely if a sequence changes size during encoding, instead of attempting to access an unavailable element.

Clone checked live-list items under one read guard before encoder callbacks. Stop cleanly if concurrent shrink removes the next item, preserving dynamic callback deletion and marker cleanup.

Assisted-by: OpenAI Codex: model version unavailable
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between f862b4b and 7ac7328.

Files selected for processing: 1
  • crates/stdlib/src/json.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Walkthrough

JSON list and tuple encoding now use bounds-checked element lookups. When a list lookup returns no element, encode_list stops encoding.

Changes: JSON sequence encoding

Layer / File(s) Summary
Handle optional sequence lookups
crates/stdlib/src/json.rs
List and tuple encoding use bounds-checked lookups. encode_list stops when a lookup returns no element. The comment now describes live sequence iteration as matching CPython’s behavior.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: youknowone

Merge Risk: Minimal · up to 7ac73

The change avoids unchecked indexing when lists shrink during JSON encoding while preserving normal output and cleanup paths. No actionable merge-blocking risk was identified; concurrency stress testing remains unverified.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "Avoid unchecked list indexing in JSON encoder" matches the main change. The PR changes JsonEncoder.encode_list in crates/stdlib/src/json.rs to use bounds-checked lookups that return None in…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "Avoid unchecked list indexing in JSON encoder" matches the main change. The PR changes JsonEncoder.encode_list in crates/stdlib/src/json.rs to use bounds-checked lookups that return None instead of direct indexing, so encoding stops when a list shrinks during iteration. The title is concise, specific, and does not use vague terms. It names the subsystem (JSON encoder) and the core change (checked indexing). It does not mention the race-condition motivation or the single-read-guard lookup, but the title does not need to cover every detail.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 1 files.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@youknowone
youknowone marked this pull request as ready for review October 28, 2026 14:20
@youknowone
youknowone enabled auto-merge (squash) October 28, 2026 14:20
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-28T14:21:43.339412Z
We couldn’t complete this review. Comment @codex review to try again.
7ac7328 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@codspeed

codspeed Bot commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 62 untouched benchmarks
⏩ 4 skipped benchmarks1


Comparing youknowdot:youknowdot/json-list-read-315-20261028 (7ac7328) with main (f862b4b)

Open in CodSpeed

Footnotes

  1. 4 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@youknowone
youknowone merged commit 8c6c94b into RustPython:main Oct 28, 2026
21 checks passed
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.

3 participants