From e7f8a88033a8f8f8d6d2606f24ea392de95fde61 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Wed, 30 Sep 2026 13:05:54 +0200 Subject: [PATCH] Fix Interoperability with Zlib::GzipReader GzipReader offers both a read and to_io method. The read method returns the uncompressed file as a string. The to_io method returns the compressed file. The JSON.load method first tests for the to_io method and uses it before testing for the read method. This results in reading the compressed file, which is invalid JSON. Instead, we now test for the read method first. --- lib/json/common.rb | 4 ++-- test/json/json_common_interface_test.rb | 14 ++++++++++++-- test/json/test_helper.rb | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index 3b5e3157a..a1603c06c 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -699,10 +699,10 @@ def load(source, proc = nil, allow_blank: true, **options) unless source.is_a?(String) if source.respond_to? :to_str source = source.to_str + elsif source.respond_to? :read + source = source.read elsif source.respond_to? :to_io source = source.to_io.read - elsif source.respond_to?(:read) - source = source.read end end diff --git a/test/json/json_common_interface_test.rb b/test/json/json_common_interface_test.rb index e4bf958d4..4fb161569 100644 --- a/test/json/json_common_interface_test.rb +++ b/test/json/json_common_interface_test.rb @@ -122,15 +122,25 @@ def o.to_s def test_load assert_equal @hash, JSON.load(@json) + assert_equal nil, JSON.load(nil) + assert_equal nil, JSON.load('') + tempfile = Tempfile.open('@json') tempfile.write @json tempfile.rewind assert_equal @hash, JSON.load(tempfile) + stringio = StringIO.new(@json) stringio.rewind assert_equal @hash, JSON.load(stringio) - assert_equal nil, JSON.load(nil) - assert_equal nil, JSON.load('') + + tempfile = Tempfile.open('@json.gzip') + gzw = Zlib::GzipWriter.new(tempfile) + gzw.write(@json) + gzw.close + tempfile.open + gzr = Zlib::GzipReader.new(tempfile) + assert_equal @hash, JSON.load(gzr) ensure tempfile.close! end diff --git a/test/json/test_helper.rb b/test/json/test_helper.rb index a30885c40..222ba86df 100644 --- a/test/json/test_helper.rb +++ b/test/json/test_helper.rb @@ -31,6 +31,7 @@ require 'test/unit' require 'stringio' require 'tempfile' +require 'zlib' begin require 'bigdecimal' rescue LoadError