Skip to content

Commit

Permalink
Merge 0235e76 into e5e3f97
Browse files Browse the repository at this point in the history
  • Loading branch information
hainesr committed Oct 3, 2020
2 parents e5e3f97 + 0235e76 commit e761c32
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 26 deletions.
29 changes: 28 additions & 1 deletion lib/zip/central_directory.rb
Expand Up @@ -124,10 +124,37 @@ def read_central_directory_entries(io) #:nodoc:
end
@entry_set = EntrySet.new
@size.times do
@entry_set << Entry.read_c_dir_entry(io)
entry = Entry.read_c_dir_entry(io)
next unless entry

offset = if entry.extra['Zip64']
entry.extra['Zip64'].relative_header_offset
else
entry.local_header_offset
end

unless offset.nil?
io_save = io.tell
io.seek(offset, IO::SEEK_SET)
entry.read_extra_field(read_local_extra_field(io))
io.seek(io_save, IO::SEEK_SET)
end

@entry_set << entry
end
end

def read_local_extra_field(io)
buf = io.read(::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH) || ''
return '' unless buf.bytesize == ::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH

head, _, _, _, _, _, _, _, _, _, n_len, e_len = buf.unpack('VCCvvvvVVVvv')
return '' unless head == ::Zip::LOCAL_ENTRY_SIGNATURE

io.seek(n_len, IO::SEEK_CUR) # Skip over the entry name.
io.read(e_len)
end

def read_from_stream(io) #:nodoc:
buf = start_buf(io)
if zip64_file?(buf)
Expand Down
15 changes: 5 additions & 10 deletions lib/zip/entry.rb
Expand Up @@ -271,12 +271,7 @@ def read_local_entry(io) #:nodoc:all
raise ::Zip::Error, 'Truncated local zip entry header'
end

if @extra.kind_of?(::Zip::ExtraField)
@extra.merge(extra) if extra
else
@extra = ::Zip::ExtraField.new(extra)
end

read_extra_field(extra)
parse_zip64_extra(true)
@local_header_size = calculate_local_header_size
end
Expand Down Expand Up @@ -379,11 +374,11 @@ def check_c_dir_entry_comment_size
raise ::Zip::Error, 'Truncated cdir zip entry header'
end

def read_c_dir_extra_field(io)
def read_extra_field(buf)
if @extra.kind_of?(::Zip::ExtraField)
@extra.merge(io.read(@extra_length))
@extra.merge(buf) if buf
else
@extra = ::Zip::ExtraField.new(io.read(@extra_length))
@extra = ::Zip::ExtraField.new(buf)
end
end

Expand All @@ -397,7 +392,7 @@ def read_c_dir_entry(io) #:nodoc:all
if ::Zip.force_entry_names_encoding
@name.force_encoding(::Zip.force_entry_names_encoding)
end
read_c_dir_extra_field(io)
read_extra_field(io.read(@extra_length))
@comment = io.read(@comment_length)
check_c_dir_entry_comment_size
set_ftype_from_c_dir_entry
Expand Down
9 changes: 0 additions & 9 deletions lib/zip/extra_field/generic.rb
Expand Up @@ -22,15 +22,6 @@ def initial_parse(binstr)
[binstr[2, 2].unpack1('v'), binstr[4..-1]]
end

def ==(other)
return false if self.class != other.class

each do |k, v|
return false if v != other[k]
end
true
end

def to_local_bin
s = pack_for_local
self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v') << s
Expand Down
4 changes: 2 additions & 2 deletions lib/zip/extra_field/unix.rb
Expand Up @@ -20,8 +20,8 @@ def merge(binstr)
return if !size || size == 0

uid, gid = content.unpack('vv')
@uid ||= uid
@gid ||= gid # rubocop:disable Naming/MemoizedInstanceVariableName
@uid = uid
@gid = gid
end

def ==(other)
Expand Down
Binary file added test/data/local_extra_field.zip
Binary file not shown.
24 changes: 24 additions & 0 deletions test/extra_field_test.rb
Expand Up @@ -17,6 +17,16 @@ def test_unknownfield
assert_equal(extra.to_s, 'fooabarbaz')
end

def test_bad_header_id
str = "ut\x5\0\x3\250$\r@"
ut = nil
assert_output('', /WARNING/) do
ut = ::Zip::ExtraField::UniversalTime.new(str)
end
assert_instance_of(::Zip::ExtraField::UniversalTime, ut)
assert_nil(ut.mtime)
end

def test_ntfs
str = "\x0A\x00 \x00\x00\x00\x00\x00\x01\x00\x18\x00\xC0\x81\x17\xE8B\xCE\xCF\x01\xC0\x81\x17\xE8B\xCE\xCF\x01\xC0\x81\x17\xE8B\xCE\xCF\x01"
extra = ::Zip::ExtraField.new(str)
Expand All @@ -25,6 +35,8 @@ def test_ntfs
assert_equal(t, extra['NTFS'].mtime)
assert_equal(t, extra['NTFS'].atime)
assert_equal(t, extra['NTFS'].ctime)

assert_equal(str.force_encoding('BINARY'), extra.to_local_bin)
end

def test_merge
Expand Down Expand Up @@ -73,4 +85,16 @@ def test_equality
extra1.create('IUnix')
assert_equal(extra1, extra3)
end

def test_read_local_extra_field
::Zip::File.open('test/data/local_extra_field.zip') do |zf|
['file1.txt', 'file2.txt'].each do |file|
entry = zf.get_entry(file)

assert_instance_of(::Zip::ExtraField, entry.extra)
assert_equal(1_000, entry.extra['IUnix'].uid)
assert_equal(1_000, entry.extra['IUnix'].gid)
end
end
end
end
6 changes: 4 additions & 2 deletions test/filesystem/file_nonmutating_test.rb
Expand Up @@ -295,8 +295,10 @@ def test_ctime
end

def test_atime
assert_nil(@zip_file.file.atime('file1'))
assert_nil(@zip_file.file.stat('file1').atime)
assert_equal(::Zip::DOSTime.at(1_027_694_306),
@zip_file.file.atime('file1'))
assert_equal(::Zip::DOSTime.at(1_027_694_306),
@zip_file.file.stat('file1').atime)
end

def test_ntfs_time
Expand Down
4 changes: 2 additions & 2 deletions test/filesystem/file_stat_test.rb
Expand Up @@ -19,11 +19,11 @@ def test_ino
end

def test_uid
assert_equal(0, @zip_file.file.stat('file1').uid)
assert_equal(500, @zip_file.file.stat('file1').uid)
end

def test_gid
assert_equal(0, @zip_file.file.stat('file1').gid)
assert_equal(500, @zip_file.file.stat('file1').gid)
end

def test_ftype
Expand Down

0 comments on commit e761c32

Please sign in to comment.