From 303bff7361f7478d0bfef5b7a450c5a9f99387ed Mon Sep 17 00:00:00 2001 From: Ufuk Kayserilioglu <ufuk.kayserilioglu@shopify.com> Date: Tue, 29 Apr 2025 21:45:52 +0300 Subject: [PATCH] Revert the removal of UTF-8 force encoding in JSON loading I think the removal of the force encoding in https://github.com/rails/spring/pull/719 was a mistake. For example, my shell prompt includes multi-byte UTF-8 characters, and when `Spring::Client::Run#run_command` collects the environment variables using `ENV.to_hash`, the resulting JSON string becomes ASCII-8BIT. This causes issues when the `Spring::Application#serve` tries to load the JSON string and passes it to `JSON.load`. Since `OkJson` expects UTF-8 encoded strings, it raises an error when it encounters the ASCII-8BIT string. I've added a test case that replicates this issue to ensure that the encoding is handled correctly. The test case creates a JSON string with multi-byte UTF-8 characters as an ASCII-8BIT string and verifies that it can be loaded without raising an error. --- lib/spring/json.rb | 1 + test/unit/json_test.rb | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/spring/json.rb b/lib/spring/json.rb index 00f0dca3..c90c251d 100644 --- a/lib/spring/json.rb +++ b/lib/spring/json.rb @@ -13,6 +13,7 @@ module Spring module JSON def self.load(string) + string = string.dup.force_encoding("utf-8") unless string.encoding == Encoding::UTF_8 OkJson.decode(string) end diff --git a/test/unit/json_test.rb b/test/unit/json_test.rb index b9eecc05..3b5eb0ec 100644 --- a/test/unit/json_test.rb +++ b/test/unit/json_test.rb @@ -6,7 +6,12 @@ class JsonTest < ActiveSupport::TestCase assert_equal({"unicode_example"=>"©"}, Spring::JSON.load('{"unicode_example": "\u00A9"}')) end + test 'can decode binary strings with valid UTF8 characters' do + string = "{\"PS1\":\"\xEF\x90\x98 main \xEE\x9E\x91 v3.4.2\"}".b + assert_equal({"PS1"=>" main v3.4.2"}, Spring::JSON.load(string)) + end + test 'can encode' do assert_equal('{}', Spring::JSON.dump({})) - end + end end