diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb index 410cf2e0b3..25f9b2f945 100644 --- a/lib/rubygems/package/tar_reader.rb +++ b/lib/rubygems/package/tar_reader.rb @@ -52,7 +52,14 @@ class Gem::Package::TarReader return enum_for __method__ unless block_given? until @io.eof? do - header = Gem::Package::TarHeader.from @io + begin + header = Gem::Package::TarHeader.from @io + rescue ArgumentError => e + # Specialize only exceptions from Gem::Package::TarHeader.strict_oct + raise e unless e.message.match?(/ is not an octal string$/) + raise Gem::Package::TarInvalidError, e.message + end + return if header.empty? entry = Gem::Package::TarReader::Entry.new header, @io yield entry diff --git a/lib/rubygems/source/local.rb b/lib/rubygems/source/local.rb index 533b0a4d06..d81d8343a8 100644 --- a/lib/rubygems/source/local.rb +++ b/lib/rubygems/source/local.rb @@ -40,10 +40,11 @@ class Gem::Source::Local < Gem::Source Dir["*.gem"].each do |file| pkg = Gem::Package.new(file) + spec = pkg.spec rescue SystemCallError, Gem::Package::FormatError # ignore else - tup = pkg.spec.name_tuple + tup = spec.name_tuple @specs[tup] = [File.expand_path(file), pkg] case type diff --git a/test/rubygems/test_gem_package_tar_reader.rb b/test/rubygems/test_gem_package_tar_reader.rb index 178e29c3d0..b2f7cc2d5c 100644 --- a/test/rubygems/test_gem_package_tar_reader.rb +++ b/test/rubygems/test_gem_package_tar_reader.rb @@ -25,6 +25,21 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase io.close! end + def test_each_with_not_a_tar + text = "Hello, world!!?\n" * 256 # 4 KiB + io = TempIO.new text + + Gem::Package::TarReader.new io do |tar| + assert_raise Gem::Package::TarInvalidError do + tar.each do + flunk "TarInvalidError was expected to occur, but an entry was found" + end + end + end + ensure + io.close! + end + def test_rewind content = ("a".."z").to_a.join(" ")