From 888d8c4a2d18ce8a04562183cd3236917e11b655 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Fri, 19 Jun 2026 00:11:05 +0900 Subject: [PATCH] Fix JSON::ResumableParser#parse leaking the in_use lock on an empty buffer Co-Authored-By: Claude Opus 4.8 (1M context) --- ext/json/ext/parser/parser.c | 1 + test/json/resumable_parser_test.rb | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 136aab6a..79591d9d 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -2377,6 +2377,7 @@ static VALUE cResumableParser_parse(VALUE self) { JSON_ResumableParser *parser = ResumableParser_acquire(self, true); if (!parser->buffer) { + parser->in_use = false; return Qfalse; } diff --git a/test/json/resumable_parser_test.rb b/test/json/resumable_parser_test.rb index 52f1356a..6c412035 100644 --- a/test/json/resumable_parser_test.rb +++ b/test/json/resumable_parser_test.rb @@ -48,6 +48,21 @@ def test_clear refute_predicate @parser, :value? end + def test_parse_with_empty_buffer_keeps_parser_usable + # parse before any feed must not leak the in_use lock + refute @parser.parse + @parser << '[1, 2, 3]' + assert @parser.parse + assert_equal [1, 2, 3], @parser.value + + # same after a clear with no following feed + @parser.clear + refute @parser.parse + @parser << '[4]' + assert @parser.parse + assert_equal [4], @parser.value + end + def test_parse_document_direct @parser << '[true]' assert_equal true, @parser.parse