diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index c774c791..9a86cd58 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -2388,6 +2388,7 @@ static VALUE cResumableParser_feed(VALUE self, VALUE str) if (RB_OBJ_FROZEN_RAW(parser->buffer)) { VALUE new_buffer = rb_obj_hide(rb_str_buf_new(remaining + RSTRING_LEN(str))); + rb_enc_associate_index(new_buffer, utf8_encindex); char *old_ptr = RSTRING_PTR(parser->buffer); memcpy(RSTRING_PTR(new_buffer), old_ptr + consumed, remaining); diff --git a/test/json/resumable_parser_test.rb b/test/json/resumable_parser_test.rb index e93b2314..4cc6c085 100644 --- a/test/json/resumable_parser_test.rb +++ b/test/json/resumable_parser_test.rb @@ -205,6 +205,16 @@ def test_rest assert_equal '"unterminated string', @parser.rest end + def test_feed_frozen_multibyte_chunks + @parser << '{"message":"日本'.freeze + refute @parser.parse + @parser << '語のつづき"}'.freeze + assert @parser.parse + value = @parser.value + assert_equal({ "message" => "日本語のつづき" }, value) + assert_equal Encoding::UTF_8, value["message"].encoding + end + def test_eos assert_predicate @parser, :eos?