From 4471d4a3e53b8d4171d62db8c6d84c20f9964519 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 28 Nov 2018 14:08:35 +0000 Subject: [PATCH] time.c: rescue find_timezone when loading git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66080 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/ruby/test_time_tz.rb | 32 +++++++++++++++++++++++++++++++- time.c | 23 +++++++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb index ae655d98c0..8e60cf44c5 100644 --- a/test/ruby/test_time_tz.rb +++ b/test/ruby/test_time_tz.rb @@ -565,6 +565,26 @@ module TestTimeTZ::WithTZ assert_instance_of(t.zone.class, t2.zone) end + def test_invalid_zone + make_timezone("INVALID", "INV", 0) + rescue => e + assert_kind_of(StandardError, e) + else + assert false, "ArgumentError expected but nothing was raised." + end + + def nametest_marshal_compatibility(time_class, tzname, abbr, utc_offset) + data = [ + "\x04\x08Iu:".b, Marshal.dump(time_class)[3..-1], + "\x0d""\xEF\xA7\x1D\x80\x00\x00\x00\x00".b, + Marshal.dump({offset: utc_offset, zone: abbr})[3..-1], + ].join('') + t = Marshal.load(data) + assert_equal(utc_offset, t.utc_offset) + assert_equal(utc_offset, (t+1).utc_offset) + # t.zone may be a mere String or timezone object. + end + ZONES = { "Asia/Tokyo" => ["JST", +9*3600], "America/Los_Angeles" => ["PDT", -7*3600], @@ -586,6 +606,16 @@ module TestTimeTZ::WithTZ end end end + + instance_methods(false).grep(/\Aname(?=test_)/) do |subtest| + test = $' + ZONES.each_pair do |tzname, (abbr, utc_offset)| + define_method("#{test}@#{tzname}") do + time_class = self.class::TIME_CLASS + __send__(subtest, time_class, tzname, abbr, utc_offset) + end + end + end end class TestTimeTZ::DummyTZ < Test::Unit::TestCase @@ -632,7 +662,7 @@ else class TIME_CLASS < ::Time def self.find_timezone(name) - Timezone[name] + Timezone.fetch(name) end end diff --git a/time.c b/time.c index 9e0d541043..21b9fecf8c 100644 --- a/time.c +++ b/time.c @@ -4965,6 +4965,26 @@ time_dump(int argc, VALUE *argv, VALUE time) return str; } +static VALUE +mload_findzone(VALUE arg) +{ + VALUE *argp = (VALUE *)arg; + VALUE time = argp[0], zone = argp[1]; + return find_timezone(time, zone); +} + +static VALUE +mload_zone(VALUE time, VALUE zone) +{ + VALUE z, args[2]; + args[0] = time; + args[1] = zone; + z = rb_rescue(mload_findzone, (VALUE)args, (VALUE (*)(ANYARGS))NULL, Qnil); + if (NIL_P(z)) return rb_fstring(zone); + if (RB_TYPE_P(z, T_STRING)) return rb_fstring(z); + return z; +} + /* :nodoc: */ static VALUE time_mload(VALUE time, VALUE str) @@ -5079,8 +5099,7 @@ end_submicro: ; time_fixoff(time); } if (!NIL_P(zone)) { - VALUE z = find_timezone(time, zone); - zone = NIL_P(z) ? rb_fstring(zone) : RB_TYPE_P(z, T_STRING) ? rb_fstring(z) : z; + zone = mload_zone(time, zone); tobj->vtm.zone = zone; }