Skip to content

Commit

Permalink
Merge pull request #109.
Browse files Browse the repository at this point in the history
Add `using UntaintExt` to ruby_data_source.rb. A call to Object#untaint
was added in commit eaa31c0.
  • Loading branch information
philr committed Dec 9, 2019
2 parents 56e2af6 + 20a890e commit 57f77de
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 21 deletions.
2 changes: 2 additions & 0 deletions lib/tzinfo.rb
Expand Up @@ -7,6 +7,8 @@ module TZInfo

require_relative 'tzinfo/version'

require_relative 'tzinfo/untaint_ext' if RUBY_VERSION >= '2.7'

require_relative 'tzinfo/string_deduper'

require_relative 'tzinfo/timestamp'
Expand Down
2 changes: 2 additions & 0 deletions lib/tzinfo/data_sources/ruby_data_source.rb
Expand Up @@ -2,6 +2,8 @@
# frozen_string_literal: true

module TZInfo
using UntaintExt if TZInfo.const_defined?(:UntaintExt)

module DataSources
# A {TZInfoDataNotFound} exception is raised if the tzinfo-data gem could
# not be found (i.e. `require 'tzinfo/data'` failed) when selecting the Ruby
Expand Down
2 changes: 2 additions & 0 deletions lib/tzinfo/data_sources/zoneinfo_data_source.rb
Expand Up @@ -2,6 +2,8 @@
# frozen_string_literal: true

module TZInfo
using UntaintExt if TZInfo.const_defined?(:UntaintExt)

module DataSources
# An {InvalidZoneinfoDirectory} exception is raised if {ZoneinfoDataSource}
# is initialized with a specific zoneinfo path that is not a valid zoneinfo
Expand Down
2 changes: 2 additions & 0 deletions lib/tzinfo/data_sources/zoneinfo_reader.rb
Expand Up @@ -2,6 +2,8 @@
# frozen_string_literal: true

module TZInfo
using UntaintExt if TZInfo.const_defined?(:UntaintExt)

module DataSources
# An {InvalidZoneinfoFile} exception is raised if an attempt is made to load
# an invalid zoneinfo file.
Expand Down
18 changes: 18 additions & 0 deletions lib/tzinfo/untaint_ext.rb
@@ -0,0 +1,18 @@
# encoding: UTF-8
# frozen_string_literal: true

module TZInfo
# Object#untaint is deprecated in Ruby >= 2.7 and will be removed in 3.0.
# UntaintExt adds a refinement to make Object#untaint a no-op and avoid the
# warning.
#
# @private
module UntaintExt # :nodoc:
refine Object do
def untaint
self
end
end
end
private_constant :UntaintExt
end
6 changes: 4 additions & 2 deletions test/data_sources/tc_ruby_data_source.rb
Expand Up @@ -3,6 +3,8 @@

require_relative '../test_utils'

using TestUtils::TaintExt if TestUtils.const_defined?(:TaintExt)

include TZInfo

module DataSources
Expand Down Expand Up @@ -118,7 +120,7 @@ def test_load_timezone_info_minus
end

def test_load_timezone_info_tainted
safe_test do
safe_test(unavailable: :skip) do
identifier = 'Europe/Amsterdam'.dup.taint
assert(identifier.tainted?)
info = @data_source.send(:load_timezone_info, identifier)
Expand Down Expand Up @@ -227,7 +229,7 @@ def test_load_country_info_case
end

def test_load_country_info_tainted
safe_test do
safe_test(unavailable: :skip) do
code = 'NL'.dup.taint
assert(code.tainted?)
info = @data_source.send(:load_country_info, code)
Expand Down
7 changes: 5 additions & 2 deletions test/data_sources/tc_zoneinfo_data_source.rb
Expand Up @@ -8,6 +8,9 @@

include TZInfo

using TestUtils::TaintExt if TestUtils.const_defined?(:TaintExt)
using UntaintExt if TZInfo.const_defined?(:UntaintExt)

module DataSources
class TCZoneinfoDataSource < Minitest::Test
ZONEINFO_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..', 'zoneinfo')).untaint
Expand Down Expand Up @@ -778,7 +781,7 @@ def test_load_timezone_info_linked_relative_parent_inside
end

def test_load_timezone_info_tainted
safe_test do
safe_test(unavailable: :skip) do
identifier = 'Europe/Amsterdam'.dup.taint
assert(identifier.tainted?)
info = @data_source.send(:load_timezone_info, identifier)
Expand Down Expand Up @@ -1120,7 +1123,7 @@ def test_load_country_info_case
end

def test_load_country_info_tainted
safe_test do
safe_test(unavailable: :skip) do
code = 'NL'.dup.taint
assert(code.tainted?)
info = @data_source.send(:load_country_info, code)
Expand Down
14 changes: 8 additions & 6 deletions test/data_sources/tc_zoneinfo_reader.rb
Expand Up @@ -6,6 +6,8 @@

include TZInfo

using UntaintExt if TZInfo.const_defined?(:UntaintExt)

module DataSources
class TCZoneinfoReader < Minitest::Test
MIN_FORMAT = 1
Expand Down Expand Up @@ -1216,10 +1218,10 @@ def test_read_untainted_in_safe_mode
o0 = TimezoneOffset.new(-12094, 0, 'LT')

tzif_test(offsets, []) do |path, format|
# Temp file path is tainted with Ruby >= 2.3.0. Untaint for this test.
path.untaint

safe_test do
# Temp file path is tainted with Ruby >= 2.3.0. Untaint for this test.
path.untaint

assert_equal(o0, @reader.read(path))
end
end
Expand All @@ -1229,10 +1231,10 @@ def test_read_tainted_in_safe_mode
offsets = [{gmtoff: -12094, isdst: false, abbrev: 'LT'}]

tzif_test(offsets, []) do |path, format|
# Temp file path is only tainted with Ruby >= 2.3.0. Taint for this test.
path.taint

safe_test(unavailable: :skip) do
# Temp file path is only tainted with Ruby >= 2.3.0. Taint for this test.
path.taint

assert_raises(SecurityError) { @reader.read(path) }
end
end
Expand Down
6 changes: 4 additions & 2 deletions test/tc_country.rb
Expand Up @@ -5,6 +5,8 @@

include TZInfo

using TestUtils::TaintExt if TestUtils.const_defined?(:TaintExt)

class TCCountry < Minitest::Test
def setup
@orig_data_source = DataSource.get
Expand Down Expand Up @@ -46,7 +48,7 @@ def test_get_nil
def test_get_tainted_loaded
Country.get('GB')

safe_test do
safe_test(unavailable: :skip) do
code = 'GB'.dup.taint
assert(code.tainted?)
country = Country.get(code)
Expand All @@ -65,7 +67,7 @@ def test_get_tainted_and_frozen_loaded
end

def test_get_tainted_not_previously_loaded
safe_test do
safe_test(unavailable: :skip) do
code = 'GB'.dup.taint
assert(code.tainted?)
country = Country.get(code)
Expand Down
6 changes: 4 additions & 2 deletions test/tc_timezone.rb
Expand Up @@ -5,6 +5,8 @@

include TZInfo

using TestUtils::TaintExt if TestUtils.const_defined?(:TaintExt)

class TCTimezone < Minitest::Test
class << self
private
Expand Down Expand Up @@ -258,7 +260,7 @@ def test_get_nil
def test_get_tainted_loaded
Timezone.get('Europe/Andorra')

safe_test do
safe_test(unavailable: :skip) do
identifier = 'Europe/Andorra'.dup.taint
assert(identifier.tainted?)
tz = Timezone.get(identifier)
Expand All @@ -277,7 +279,7 @@ def test_get_tainted_and_frozen_loaded
end

def test_get_tainted_not_previously_loaded
safe_test do
safe_test(unavailable: :skip) do
identifier = 'Europe/Andorra'.dup.taint
assert(identifier.tainted?)
tz = Timezone.get(identifier)
Expand Down
21 changes: 17 additions & 4 deletions test/test_utils.rb
Expand Up @@ -49,7 +49,9 @@
end
end

TESTS_DIR = File.expand_path(File.dirname(__FILE__)).untaint
tests_dir = File.expand_path(File.dirname(__FILE__))
tests_dir.untaint if RUBY_VERSION < '2.7'
TESTS_DIR = tests_dir
TZINFO_TEST_ZONEINFO_DIR = File.join(TESTS_DIR, 'zoneinfo')

unless defined? TZINFO_TEST_DATA_DIR
Expand Down Expand Up @@ -286,11 +288,11 @@ def without_warnings

# Runs a test with safe mode enabled ($SAFE = 1).
def safe_test(options = {})
# JRuby, Rubinius and TruffleRuby don't support SAFE levels.
available = !%w(jruby rbx truffleruby).include?(RUBY_ENGINE)
# Ruby >= 2.7, JRuby, Rubinius and TruffleRuby don't support SAFE levels.
available = RUBY_VERSION < '2.7' && !%w(jruby rbx truffleruby).include?(RUBY_ENGINE)

if !available && options[:unavailable] == :skip
skip('JRuby, Rubinius and TruffleRuby don\'t support SAFE levels')
skip('Ruby >= 2.7, JRuby, Rubinius and TruffleRuby don\'t support SAFE levels')
end

thread = Thread.new do
Expand Down Expand Up @@ -482,6 +484,17 @@ def assert_equal_with_offset_and_class(expected, actual)
assert_equal(expected.class, actual.class)
end
end

# Taint is deprecated in Ruby 2.7 and outputs a warning. Silence the warning.
if RUBY_VERSION >= '2.7'
module TaintExt
refine Object do
def taint
self
end
end
end
end
end

TestUtils.prepare_test_zoneinfo_dir
Expand Down
4 changes: 3 additions & 1 deletion test/ts_all_zoneinfo.rb
Expand Up @@ -7,6 +7,8 @@

# Use a zoneinfo directory containing files needed by the tests.
# The symlinks in this directory are set up in test_utils.rb.
TZInfo::DataSource.set(:zoneinfo, File.join(File.expand_path(File.dirname(__FILE__)), 'zoneinfo').untaint)
zoneinfo_path = File.join(File.expand_path(File.dirname(__FILE__)), 'zoneinfo')
zoneinfo_path.untaint if RUBY_VERSION < '2.7'
TZInfo::DataSource.set(:zoneinfo, zoneinfo_path)

require_relative 'ts_all'
5 changes: 4 additions & 1 deletion test/tzinfo-data2/tzinfo/data.rb
Expand Up @@ -4,8 +4,11 @@
module TZInfo
# Top level module for TZInfo::Data.
module Data
location = File.dirname(File.dirname(__FILE__))
location.untaint if RUBY_VERSION < '2.7'

# The directory containing the TZInfo::Data files.
LOCATION = File.dirname(File.dirname(__FILE__)).untaint.freeze
LOCATION = location.freeze
end
end

Expand Down
2 changes: 1 addition & 1 deletion tzinfo.gemspec
@@ -1,4 +1,4 @@
require File.join(File.expand_path(File.dirname(__FILE__)), 'lib', 'tzinfo', 'version').untaint
require File.join(File.expand_path(File.dirname(__FILE__)), 'lib', 'tzinfo', 'version')

Gem::Specification.new do |s|
s.name = 'tzinfo'
Expand Down

0 comments on commit 57f77de

Please sign in to comment.