summaryrefslogtreecommitdiff
path: root/test/rubygems/test_gem_package_tar_reader_entry.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/rubygems/test_gem_package_tar_reader_entry.rb')
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb240
1 files changed, 223 insertions, 17 deletions
diff --git a/test/rubygems/test_gem_package_tar_reader_entry.rb b/test/rubygems/test_gem_package_tar_reader_entry.rb
index 031de06e09..67ab7922b5 100644
--- a/test/rubygems/test_gem_package_tar_reader_entry.rb
+++ b/test/rubygems/test_gem_package_tar_reader_entry.rb
@@ -1,17 +1,17 @@
# frozen_string_literal: true
-require 'rubygems/package/tar_test_case'
-require 'rubygems/package'
+
+require_relative "package/tar_test_case"
+require "rubygems/package"
class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
def setup
super
- @contents = ('a'..'z').to_a.join * 100
+ @contents = ("a".."z").to_a.join * 100
@tar = String.new
@tar << tar_file_header("lib/foo", "", 0, @contents.size, Time.now)
- @tar << @contents
- @tar << "\0" * (512 - (@tar.size % 512))
+ @tar << tar_file_contents(@contents)
@entry = util_entry @tar
end
@@ -21,8 +21,39 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
super
end
- def close_util_entry(entry)
- entry.instance_variable_get(:@io).close!
+ def test_open
+ io = TempIO.new @tar
+ header = Gem::Package::TarHeader.from io
+ retval = Gem::Package::TarReader::Entry.open header, io, &:getc
+ assert_equal "a", retval
+ assert_equal @tar.size, io.pos, "should have read to end of entry"
+ ensure
+ io&.close!
+ end
+
+ def test_open_closes_entry
+ io = TempIO.new @tar
+ header = Gem::Package::TarHeader.from io
+ entry = nil
+ Gem::Package::TarReader::Entry.open header, io do |e|
+ entry = e
+ end
+ assert entry.closed?
+ assert_raise(IOError) { entry.getc }
+ ensure
+ io&.close!
+ end
+
+ def test_open_returns_entry
+ io = TempIO.new @tar
+ header = Gem::Package::TarHeader.from io
+ entry = Gem::Package::TarReader::Entry.open header, io
+ refute entry.closed?
+ assert_equal "a", entry.getc
+ assert_nil entry.close
+ assert entry.closed?
+ ensure
+ io&.close!
end
def test_bytes_read
@@ -43,19 +74,19 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert @entry.bytes_read
e = assert_raise(IOError) { @entry.eof? }
- assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+ assert_equal "closed Gem::Package::TarReader::Entry", e.message
e = assert_raise(IOError) { @entry.getc }
- assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+ assert_equal "closed Gem::Package::TarReader::Entry", e.message
e = assert_raise(IOError) { @entry.pos }
- assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+ assert_equal "closed Gem::Package::TarReader::Entry", e.message
e = assert_raise(IOError) { @entry.read }
- assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+ assert_equal "closed Gem::Package::TarReader::Entry", e.message
e = assert_raise(IOError) { @entry.rewind }
- assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+ assert_equal "closed Gem::Package::TarReader::Entry", e.message
end
def test_closed_eh
@@ -71,22 +102,22 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
end
def test_full_name
- assert_equal 'lib/foo', @entry.full_name
+ assert_equal "lib/foo", @entry.full_name
end
def test_full_name_null
- skip "jruby strips the null byte and does not think it's corrupt" if Gem.java_platform?
+ pend "jruby strips the null byte and does not think it's corrupt" if Gem.java_platform?
@entry.header.prefix << "\000"
e = assert_raise Gem::Package::TarInvalidError do
@entry.full_name
end
- assert_equal 'tar is corrupt, name contains null byte', e.message
+ assert_equal "tar is corrupt, name contains null byte", e.message
end
def test_getc
- assert_equal ?a, @entry.getc
+ assert_equal "a", @entry.getc
end
def test_directory_eh
@@ -125,6 +156,18 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert_equal @contents, @entry.read
end
+ def test_consecutive_read
+ expected = StringIO.new(@contents)
+ assert_equal expected.read, @entry.read
+ assert_equal expected.read, @entry.read
+ end
+
+ def test_consecutive_read_bytes_past_eof
+ expected = StringIO.new(@contents)
+ assert_equal expected.read, @entry.read
+ assert_equal expected.read(1), @entry.read(1)
+ end
+
def test_read_big
assert_equal @contents, @entry.read(@contents.size * 2)
end
@@ -133,13 +176,64 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert_equal @contents[0...100], @entry.read(100)
end
+ def test_read_remaining
+ @entry.read(100)
+ assert_equal @contents[100..-1], @entry.read
+ end
+
def test_readpartial
+ assert_equal @contents[0...100], @entry.readpartial(100)
+ end
+
+ def test_readpartial_to_eof
+ assert_equal @contents, @entry.readpartial(4096)
+ assert @entry.eof?
+ end
+
+ def test_read_partial_buffer
+ buffer = "".b
+ @entry.readpartial(100, buffer)
+ assert_equal @contents[0...100], buffer
+ end
+
+ def test_readpartial_past_eof
+ @entry.readpartial(@contents.size)
+ assert @entry.eof?
assert_raise(EOFError) do
- @entry.read(@contents.size)
@entry.readpartial(1)
end
end
+ def test_read_corrupted_tar
+ corrupt_tar = String.new
+ corrupt_tar << tar_file_header("lib/foo", "", 0, 100, Time.now)
+ corrupt_tar << tar_file_contents("")
+ corrupt_entry = util_entry corrupt_tar
+
+ assert_equal "", corrupt_entry.read(0)
+ assert_equal "", corrupt_entry.read, "IO.read without len should return empty string (even though it's at an unpexpected EOF)"
+
+ corrupt_entry.rewind
+
+ assert_nil corrupt_entry.read(100), "IO.read with len should return nil as per IO.read docs"
+ ensure
+ close_util_entry(corrupt_entry) if corrupt_entry
+ end
+
+ def test_readpartial_corrupted_tar
+ corrupt_tar = String.new
+ corrupt_tar << tar_file_header("lib/foo", "", 0, 100, Time.now)
+ corrupt_tar << tar_file_contents("")
+
+ corrupt_entry = util_entry corrupt_tar
+
+ assert_raise EOFError do
+ corrupt_entry.readpartial(100)
+ end
+ ensure
+ close_util_entry(corrupt_entry) if corrupt_entry
+ end
+
def test_rewind
char = @entry.getc
@@ -149,4 +243,116 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert_equal char, @entry.getc
end
+
+ def test_seek
+ @entry.seek(50)
+ assert_equal 50, @entry.pos
+ assert_equal @contents[50..-1], @entry.read, "read remaining after seek"
+ @entry.seek(-50, IO::SEEK_CUR)
+ assert_equal @contents.size - 50, @entry.pos
+ assert_equal @contents[-50..-1], @entry.read, "read after stepping back 50 from the end"
+ @entry.seek(0, IO::SEEK_SET)
+ assert_equal 0, @entry.pos
+ assert_equal @contents, @entry.read, "read from beginning"
+ @entry.seek(-10, IO::SEEK_END)
+ assert_equal @contents.size - 10, @entry.pos
+ assert_equal @contents[-10..-1], @entry.read, "read from end"
+ end
+
+ def test_read_zero
+ expected = StringIO.new("")
+ assert_equal expected.read(0), @entry.read(0)
+ end
+
+ def test_readpartial_zero
+ expected = StringIO.new("")
+ assert_equal expected.readpartial(0), @entry.readpartial(0)
+ end
+
+ def test_zero_byte_file_read
+ zero_entry = util_entry(tar_file_header("foo", "", 0, 0, Time.now))
+ expected = StringIO.new("")
+ assert_equal expected.read, zero_entry.read
+ ensure
+ close_util_entry(zero_entry) if zero_entry
+ end
+
+ def test_zero_byte_file_readpartial
+ zero_entry = util_entry(tar_file_header("foo", "", 0, 0, Time.now))
+ expected = StringIO.new("")
+ assert_equal expected.readpartial(0), zero_entry.readpartial(0)
+ ensure
+ close_util_entry(zero_entry) if zero_entry
+ end
+
+ def test_read_from_gzip_io
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ entry = util_entry(gzio)
+ assert_equal @contents, entry.read
+ entry.rewind
+ assert_equal @contents, entry.read, "second read after rewind should read same contents"
+ end
+ end
+
+ def test_read_from_gzip_io_with_non_zero_offset
+ contents2 = ("0".."9").to_a.join * 100
+ @tar << tar_file_header("lib/bar", "", 0, contents2.size, Time.now)
+ @tar << tar_file_contents(contents2)
+
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ util_entry(gzio).close # skip the first entry so io.pos is not 0, preventing easy rewind
+ entry = util_entry(gzio)
+
+ assert_equal contents2, entry.read
+ entry.rewind
+ assert_equal contents2, entry.read, "second read after rewind should read same contents"
+ end
+ end
+
+ def test_seek_in_gzip_io_with_non_zero_offset
+ contents2 = ("0".."9").to_a.join * 100
+ @tar << tar_file_header("lib/bar", "", 0, contents2.size, Time.now)
+ @tar << tar_file_contents(contents2)
+
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ util_entry(gzio).close # skip the first entry so io.pos is not 0
+ entry = util_entry(gzio)
+
+ entry.seek(50)
+ assert_equal 50, entry.pos
+ assert_equal contents2[50..-1], entry.read, "read remaining after seek"
+ entry.seek(-50, IO::SEEK_CUR)
+ assert_equal contents2.size - 50, entry.pos
+ assert_equal contents2[-50..-1], entry.read, "read after stepping back 50 from the end"
+ entry.seek(0, IO::SEEK_SET)
+ assert_equal 0, entry.pos
+ assert_equal contents2, entry.read, "read from beginning"
+ entry.seek(-10, IO::SEEK_END)
+ assert_equal contents2.size - 10, entry.pos
+ assert_equal contents2[-10..-1], entry.read, "read from end"
+ assert_equal contents2.size, entry.pos
+ end
+ end
+
+ def test_seek_in_gzip_io_corrupted
+ @tar << tar_file_header("lib/bar", "", 0, 100, Time.now)
+ @tar << tar_file_contents("")
+
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ util_entry(gzio).close # skip the first entry so io.pos is not 0
+ entry = util_entry(gzio)
+
+ assert_raise EOFError do
+ entry.seek(50)
+ end
+ end
+ end
end