diff --git a/CHANGES.md b/CHANGES.md index f40572e8..f64384ca 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,7 @@ # Changes +* `JSON.load_file` explictly read the file as UTF-8. + ### 2024-11-06 (2.8.1) * Fix the java packages to include the extension. diff --git a/lib/json/common.rb b/lib/json/common.rb index 2269896b..03aaaa6e 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -1,4 +1,5 @@ -#frozen_string_literal: true +# frozen_string_literal: true + require 'json/version' module JSON @@ -230,8 +231,8 @@ def parse!(source, opts = {}) # parse(File.read(path), opts) # # See method #parse. - def load_file(filespec, opts = {}) - parse(File.read(filespec), opts) + def load_file(filespec, opts = nil) + parse(File.read(filespec, encoding: Encoding::UTF_8), opts) end # :call-seq: @@ -242,7 +243,7 @@ def load_file(filespec, opts = {}) # # See method #parse! def load_file!(filespec, opts = {}) - parse!(File.read(filespec), opts) + parse!(File.read(filespec, encoding: Encoding::UTF_8), opts) end # :call-seq: diff --git a/test/json/json_common_interface_test.rb b/test/json/json_common_interface_test.rb index 6165cc04..643d3e92 100644 --- a/test/json/json_common_interface_test.rb +++ b/test/json/json_common_interface_test.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'test_helper' require 'stringio' require 'tempfile' @@ -189,8 +190,30 @@ def test_load_file_with_option! test_load_file_with_option_shared(:load_file!) end + def test_load_file_with_bad_default_external_encoding + data = { "key" => "€" } + temp_file_containing(JSON.dump(data)) do |path| + loaded_data = with_external_encoding(Encoding::US_ASCII) do + JSON.load_file(path) + end + assert_equal data, loaded_data + end + end + private + def with_external_encoding(encoding) + verbose = $VERBOSE + $VERBOSE = nil + previous_encoding = Encoding.default_external + Encoding.default_external = encoding + yield + ensure + verbose = $VERBOSE + Encoding.default_external = previous_encoding + $VERBOSE = verbose + end + def test_load_shared(method_name) temp_file_containing(@json) do |filespec| assert_equal JSON.public_send(method_name, filespec), @hash