From 150e05f9062a4a6ec4c4b95db4f4a4112606589c Mon Sep 17 00:00:00 2001 From: otegami Date: Tue, 24 Dec 2024 18:29:45 +0900 Subject: [PATCH 1/2] support for forzen string literals Issue When running tests with Ruby 3.4.0rc1, the following warnings are displayed. ```console $ rake test Run options: --seed 46514 /work/ruby/json-stream/lib/json/stream/parser.rb:549: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information) /work/ruby/json-stream/lib/json/stream/parser.rb:555: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information) ``` Cuases According to https://bugs.ruby-lang.org/issues/20205, string literals may be frozen by default in future Ruby versions (potentially Ruby 4.0+). Starting from Ruby 3.4.0, warnings like `warning: literal string will be frozen in the future` are shown if string literals are mutable. Solution We explicitly make string literals mutable using `+"string literal"` Additionally, we add `# frozen_string_literal: true` at the top of the affected files and handle the warnings to ensure compatibility with Ruby versions before 3.4.0. --- lib/json/stream/buffer.rb | 4 +++- lib/json/stream/parser.rb | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/json/stream/buffer.rb b/lib/json/stream/buffer.rb index cbefd8b..56c531f 100644 --- a/lib/json/stream/buffer.rb +++ b/lib/json/stream/buffer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module JSON module Stream # A character buffer that expects a UTF-8 encoded stream of bytes. @@ -29,7 +31,7 @@ def initialize def <<(data) # Avoid state machine for complete UTF-8. if @buffer.empty? - data.force_encoding(Encoding::UTF_8) + (+data).force_encoding(Encoding::UTF_8) return data if data.valid_encoding? end diff --git a/lib/json/stream/parser.rb b/lib/json/stream/parser.rb index 33e7925..7e7e22b 100644 --- a/lib/json/stream/parser.rb +++ b/lib/json/stream/parser.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module JSON module Stream # Raised on any invalid JSON text. @@ -102,8 +104,8 @@ def initialize(&block) # Track parse stack. @stack = [] - @unicode = "" - @buf = "" + @unicode = +"" + @buf = +"" @pos = -1 # Register any observers in the block. @@ -178,7 +180,7 @@ def <<(data) @state = :end_key notify(:key, @buf) end - @buf = "" + @buf = +"" when BACKSLASH @state = :start_escape when CONTROL @@ -270,7 +272,7 @@ def <<(data) @buf << ch else end_value(@buf.to_i) - @buf = "" + @buf = +"" @pos -= 1 redo end @@ -291,7 +293,7 @@ def <<(data) @buf << ch else end_value(@buf.to_f) - @buf = "" + @buf = +"" @pos -= 1 redo end @@ -310,7 +312,7 @@ def <<(data) else error('Expected 0-9 digit') unless @buf =~ DIGIT_END end_value(@buf.to_f) - @buf = "" + @buf = +"" @pos -= 1 redo end @@ -326,7 +328,7 @@ def <<(data) @buf << ch else end_value(@buf.to_i) - @buf = "" + @buf = +"" @pos -= 1 redo end @@ -503,7 +505,7 @@ def keyword(word, value, re, ch) if @buf.size == word.size if @buf == word - @buf = "" + @buf = +"" end_value(value) else error("Expected #{word} keyword") From d97d4d243dc5e43566e93aedd3ff204c11a12828 Mon Sep 17 00:00:00 2001 From: otegami Date: Wed, 25 Dec 2024 16:18:07 +0900 Subject: [PATCH 2/2] use `dup` instead because the previous change doesn't release froze literals --- lib/json/stream/buffer.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/json/stream/buffer.rb b/lib/json/stream/buffer.rb index 56c531f..f139060 100644 --- a/lib/json/stream/buffer.rb +++ b/lib/json/stream/buffer.rb @@ -31,7 +31,8 @@ def initialize def <<(data) # Avoid state machine for complete UTF-8. if @buffer.empty? - (+data).force_encoding(Encoding::UTF_8) + data = data.dup + data.force_encoding(Encoding::UTF_8) return data if data.valid_encoding? end