[rubygems/rubygems] All rubies working with different time zones

Tested with:

`ruby -e 'trap("INT") { exit 1 }; TZ=%w[UTC +0000 -0000]; RUBY=%w[ruby-2.7 ruby-3.2.2 jruby-9.4 truffleruby-22 truffleruby-23]; TZ.product(RUBY).each { |t, r| puts ?**120, "TZ=#{t} RUBY=#{r}", "*"*120; system({"TZ"=>t,"RUBY"=>r}, *ARGV) }' zsh -lic 'chruby $RUBY; ruby -vw -Ilib test/rubygems/test_gem_safe_marshal.rb --verbose=progress'`

https://github.com/rubygems/rubygems/commit/6192005afb
This commit is contained in:
Samuel Giddins 2023-08-24 09:23:02 -07:00 коммит произвёл git
Родитель c65c88e65c
Коммит cadca9f67e
3 изменённых файлов: 30 добавлений и 9 удалений

Просмотреть файл

@ -42,7 +42,7 @@ module Gem
private_constant :PERMITTED_SYMBOLS
PERMITTED_IVARS = {
"String" => %w[E @taguri @debug_created_info],
"String" => %w[E encoding @taguri @debug_created_info],
"Time" => %w[
offset zone nano_num nano_den submicro
@_zone @marshal_with_utc_coercion

Просмотреть файл

@ -54,7 +54,6 @@ module Gem::SafeMarshal
end
def visit_Gem_SafeMarshal_Elements_WithIvars(e)
idx = 0
object_offset = @objects.size
@stack << "object"
object = visit(e.object)
@ -104,8 +103,9 @@ module Gem::SafeMarshal
if zone
require "time"
zone = "+0000" if zone == "UTC" && offset == 0
call_method(Time, :force_zone!, object, zone, offset)
transformed_zone = zone
transformed_zone = "+0000" if ["UTC", "Z"].include?(zone) && offset == 0
call_method(Time, :force_zone!, object, transformed_zone, offset)
elsif offset
object = object.localtime offset
end
@ -131,8 +131,10 @@ module Gem::SafeMarshal
when FalseClass
enc = "US-ASCII"
else
enc = v
raise FormatError, "Unexpected value for String :E #{v.inspect}"
end
when :encoding
enc = v
else
next false
end

Просмотреть файл

@ -36,8 +36,16 @@ class TestGemSafeMarshal < Gem::TestCase
end
def test_string_with_encoding
assert_safe_load_as String.new("abc", encoding: "US-ASCII")
assert_safe_load_as String.new("abc", encoding: "UTF-8")
[
String.new("abc", encoding: "US-ASCII"),
String.new("abc", encoding: "UTF-8"),
String.new("abc", encoding: "Windows-1256"),
String.new("abc", encoding: Encoding::BINARY),
String.new("abc", encoding: "UTF-32"),
].each do |s|
assert_safe_load_as s, additional_methods: [:encoding]
assert_safe_load_as [s, s], additional_methods: [->(a) { a.map(&:encoding) }]
end
end
def test_string_with_ivar
@ -75,7 +83,12 @@ class TestGemSafeMarshal < Gem::TestCase
Time.at(secs, 1.001, :nanosecond),
Time.at(secs, 1.00001, :nanosecond),
Time.at(secs, 1.00001, :nanosecond),
].each_with_index do |t, i|
].tap do |times|
times.concat [
Time.at(secs, in: "UTC"),
Time.at(secs, in: "Z"),
] unless RUBY_ENGINE == "truffleruby" && RUBY_ENGINE_VERSION < "23"
end.each_with_index do |t, i|
define_method("test_time_#{i} #{t.inspect}") do
pend "Marshal.load of Time with custom zone is broken before Truffleruby 23" if t.zone.nil? && RUBY_ENGINE == "truffleruby" && RUBY_ENGINE_VERSION < "23"
@ -167,7 +180,13 @@ class TestGemSafeMarshal < Gem::TestCase
assert_equal x.to_s, safe_loaded.to_s, "should have equal to_s"
assert_equal x.inspect, safe_loaded.inspect, "should have equal inspect"
additional_methods.each do |m|
assert_equal loaded.send(m), safe_loaded.send(m), "should have equal #{m}"
if m.is_a?(Proc)
call = m
else
call = ->(obj) { obj.__send__(m) }
end
assert_equal call[loaded], call[safe_loaded], "should have equal #{m}"
end
assert_equal Marshal.dump(loaded), Marshal.dump(safe_loaded), "should Marshal.dump the same"
end