Skip to content

Fix ResumableParser#partial_value SEGV on incomplete nested containers#1046

Open
tompng wants to merge 1 commit into
ruby:masterfrom
tompng:fix_incomplete_key_segv
Open

Fix ResumableParser#partial_value SEGV on incomplete nested containers#1046
tompng wants to merge 1 commit into
ruby:masterfrom
tompng:fix_incomplete_key_segv

Conversation

@tompng

@tompng tompng commented Jun 29, 2026

Copy link
Copy Markdown
Member

partial_value rebuilds the open containers on a scratch copy of the value stack. Folding an empty innermost container pops nothing and pushes its result, so head climbs one past the live size; the scratch buffer was sized to exactly the live size, so the push triggered rvalue_stack_grow which reallocated the ALLOCV buffer (a non-malloc pointer) and crashed.

A parent fold always reclaims its child's slot, so head exceeds the live size by at most one -- either for the missing-value placeholder or for an empty innermost fold, never both. Size the buffer to capa + 1.

SEGV reproduction code:

parser = JSON::ResumableParser.new
parser << '{"a":{"b'
parser.parse
parser.partial_value

partial_value rebuilds the open containers on a scratch copy of the value
stack. Folding an empty innermost container pops nothing and pushes its
result, so head climbs one past the live size; the scratch buffer was sized
to exactly the live size, so the push triggered rvalue_stack_grow which
reallocated the ALLOCV buffer (a non-malloc pointer) and crashed.

A parent fold always reclaims its child's slot, so head exceeds the live
size by at most one -- either for the missing-value placeholder or for an
empty innermost fold, never both. Size the buffer to capa + 1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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