rubyzip 1.1.7 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubyzip might be problematic. Click here for more details.

Files changed (106) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +87 -45
  3. data/Rakefile +3 -4
  4. data/lib/zip.rb +11 -5
  5. data/lib/zip/central_directory.rb +8 -8
  6. data/lib/zip/compressor.rb +1 -2
  7. data/lib/zip/constants.rb +5 -5
  8. data/lib/zip/crypto/null_encryption.rb +4 -6
  9. data/lib/zip/crypto/traditional_encryption.rb +5 -5
  10. data/lib/zip/decompressor.rb +3 -3
  11. data/lib/zip/deflater.rb +8 -6
  12. data/lib/zip/dos_time.rb +5 -6
  13. data/lib/zip/entry.rb +120 -128
  14. data/lib/zip/entry_set.rb +14 -14
  15. data/lib/zip/errors.rb +1 -0
  16. data/lib/zip/extra_field.rb +8 -8
  17. data/lib/zip/extra_field/generic.rb +8 -8
  18. data/lib/zip/extra_field/ntfs.rb +14 -16
  19. data/lib/zip/extra_field/old_unix.rb +9 -10
  20. data/lib/zip/extra_field/universal_time.rb +14 -14
  21. data/lib/zip/extra_field/unix.rb +8 -9
  22. data/lib/zip/extra_field/zip64.rb +12 -11
  23. data/lib/zip/extra_field/zip64_placeholder.rb +1 -2
  24. data/lib/zip/file.rb +81 -81
  25. data/lib/zip/filesystem.rb +144 -143
  26. data/lib/zip/inflater.rb +5 -5
  27. data/lib/zip/input_stream.rb +22 -13
  28. data/lib/zip/ioextras.rb +1 -3
  29. data/lib/zip/ioextras/abstract_input_stream.rb +6 -10
  30. data/lib/zip/ioextras/abstract_output_stream.rb +3 -5
  31. data/lib/zip/null_compressor.rb +2 -2
  32. data/lib/zip/null_decompressor.rb +3 -3
  33. data/lib/zip/null_input_stream.rb +0 -0
  34. data/lib/zip/output_stream.rb +13 -14
  35. data/lib/zip/pass_thru_compressor.rb +4 -4
  36. data/lib/zip/pass_thru_decompressor.rb +3 -4
  37. data/lib/zip/streamable_directory.rb +2 -2
  38. data/lib/zip/streamable_stream.rb +3 -3
  39. data/lib/zip/version.rb +1 -1
  40. data/samples/example.rb +29 -39
  41. data/samples/example_filesystem.rb +16 -18
  42. data/samples/example_recursive.rb +31 -25
  43. data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +23 -25
  44. data/samples/qtzip.rb +18 -27
  45. data/samples/write_simple.rb +12 -13
  46. data/samples/zipfind.rb +26 -34
  47. data/test/basic_zip_file_test.rb +11 -15
  48. data/test/case_sensitivity_test.rb +69 -0
  49. data/test/central_directory_entry_test.rb +32 -36
  50. data/test/central_directory_test.rb +46 -50
  51. data/test/crypto/null_encryption_test.rb +8 -4
  52. data/test/crypto/traditional_encryption_test.rb +5 -5
  53. data/test/data/gpbit3stored.zip +0 -0
  54. data/test/data/notzippedruby.rb +1 -1
  55. data/test/data/oddExtraField.zip +0 -0
  56. data/test/data/path_traversal/Makefile +10 -0
  57. data/test/data/path_traversal/jwilk/README.md +5 -0
  58. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  59. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  60. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  61. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  62. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  63. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  64. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  65. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  66. data/test/data/path_traversal/relative1.zip +0 -0
  67. data/test/data/path_traversal/tilde.zip +0 -0
  68. data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
  69. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  70. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  71. data/test/data/rubycode.zip +0 -0
  72. data/test/data/test.xls +0 -0
  73. data/test/deflater_test.rb +10 -12
  74. data/test/encryption_test.rb +2 -2
  75. data/test/entry_set_test.rb +50 -25
  76. data/test/entry_test.rb +76 -87
  77. data/test/errors_test.rb +1 -2
  78. data/test/extra_field_test.rb +19 -21
  79. data/test/file_extract_directory_test.rb +12 -14
  80. data/test/file_extract_test.rb +33 -40
  81. data/test/file_permissions_test.rb +65 -0
  82. data/test/file_split_test.rb +24 -27
  83. data/test/file_test.rb +266 -179
  84. data/test/filesystem/dir_iterator_test.rb +13 -17
  85. data/test/filesystem/directory_test.rb +101 -93
  86. data/test/filesystem/file_mutating_test.rb +52 -65
  87. data/test/filesystem/file_nonmutating_test.rb +223 -229
  88. data/test/filesystem/file_stat_test.rb +17 -19
  89. data/test/gentestfiles.rb +54 -62
  90. data/test/inflater_test.rb +1 -1
  91. data/test/input_stream_test.rb +52 -40
  92. data/test/ioextras/abstract_input_stream_test.rb +22 -23
  93. data/test/ioextras/abstract_output_stream_test.rb +33 -33
  94. data/test/ioextras/fake_io_test.rb +1 -1
  95. data/test/local_entry_test.rb +36 -38
  96. data/test/output_stream_test.rb +20 -21
  97. data/test/pass_thru_compressor_test.rb +5 -6
  98. data/test/pass_thru_decompressor_test.rb +0 -1
  99. data/test/path_traversal_test.rb +141 -0
  100. data/test/samples/example_recursive_test.rb +37 -0
  101. data/test/settings_test.rb +18 -15
  102. data/test/test_helper.rb +52 -46
  103. data/test/unicode_file_names_and_comments_test.rb +17 -7
  104. data/test/zip64_full_test.rb +10 -12
  105. data/test/zip64_support_test.rb +0 -1
  106. metadata +94 -65
@@ -5,7 +5,7 @@ module Zip
5
5
 
6
6
  def initialize(an_enumerable = [])
7
7
  super()
8
- @entry_set = {}
8
+ @entry_set = {}
9
9
  an_enumerable.each { |o| push(o) }
10
10
  end
11
11
 
@@ -18,28 +18,24 @@ module Zip
18
18
  end
19
19
 
20
20
  def <<(entry)
21
- @entry_set[to_key(entry)] = entry
21
+ @entry_set[to_key(entry)] = entry if entry
22
22
  end
23
23
 
24
- alias :push :<<
24
+ alias push <<
25
25
 
26
26
  def size
27
27
  @entry_set.size
28
28
  end
29
29
 
30
- alias :length :size
30
+ alias length size
31
31
 
32
32
  def delete(entry)
33
- if @entry_set.delete(to_key(entry))
34
- entry
35
- else
36
- nil
37
- end
33
+ entry if @entry_set.delete(to_key(entry))
38
34
  end
39
35
 
40
- def each(&block)
36
+ def each
41
37
  @entry_set = sorted_entries.dup.each do |_, value|
42
- block.call(value)
38
+ yield(value)
43
39
  end
44
40
  end
45
41
 
@@ -49,7 +45,7 @@ module Zip
49
45
 
50
46
  # deep clone
51
47
  def dup
52
- EntrySet.new(@entry_set.map { |key, value| value.dup })
48
+ EntrySet.new(@entry_set.values.map(&:dup))
53
49
  end
54
50
 
55
51
  def ==(other)
@@ -61,7 +57,7 @@ module Zip
61
57
  @entry_set[to_key(entry.parent_as_string)]
62
58
  end
63
59
 
64
- def glob(pattern, flags = ::File::FNM_PATHNAME|::File::FNM_DOTMATCH)
60
+ def glob(pattern, flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB)
65
61
  entries.map do |entry|
66
62
  next nil unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags)
67
63
  yield(entry) if block_given?
@@ -70,13 +66,17 @@ module Zip
70
66
  end
71
67
 
72
68
  protected
69
+
73
70
  def sorted_entries
74
71
  ::Zip.sort_entries ? Hash[@entry_set.sort] : @entry_set
75
72
  end
76
73
 
77
74
  private
75
+
78
76
  def to_key(entry)
79
- entry.to_s.chomp('/')
77
+ k = entry.to_s.chomp('/')
78
+ k.downcase! if ::Zip.case_insensitive_match
79
+ k
80
80
  end
81
81
  end
82
82
  end
@@ -5,6 +5,7 @@ module Zip
5
5
  class CompressionMethodError < Error; end
6
6
  class EntryNameError < Error; end
7
7
  class InternalError < Error; end
8
+ class GPFBit3Error < Error; end
8
9
 
9
10
  # Backwards compatibility with v1 (delete in v2)
10
11
  ZipError = Error
@@ -3,12 +3,12 @@ module Zip
3
3
  ID_MAP = {}
4
4
 
5
5
  def initialize(binstr = nil)
6
- binstr and merge(binstr)
6
+ merge(binstr) if binstr
7
7
  end
8
8
 
9
9
  def extra_field_type_exist(binstr, id, len, i)
10
10
  field_name = ID_MAP[id].name
11
- if self.member?(field_name)
11
+ if member?(field_name)
12
12
  self[field_name].merge(binstr[i, len + 4])
13
13
  else
14
14
  field_obj = ID_MAP[id].new(binstr[i, len + 4])
@@ -26,7 +26,7 @@ module Zip
26
26
  end
27
27
 
28
28
  def create_unknown_item
29
- s = ''
29
+ s = ''.dup
30
30
  class << s
31
31
  alias_method :to_c_dir_bin, :to_s
32
32
  alias_method :to_local_bin, :to_s
@@ -51,7 +51,7 @@ module Zip
51
51
  end
52
52
 
53
53
  def create(name)
54
- unless field_class = ID_MAP.values.find { |k| k.name == name }
54
+ unless (field_class = ID_MAP.values.find { |k| k.name == name })
55
55
  raise Error, "Unknown extra field '#{name}'"
56
56
  end
57
57
  self[name] = field_class.new
@@ -61,7 +61,7 @@ module Zip
61
61
  # does not prevent known fields from being read back in
62
62
  def ordered_values
63
63
  result = []
64
- self.each { |k,v| k == 'Unknown' ? result.push(v) : result.unshift(v) }
64
+ each { |k, v| k == 'Unknown' ? result.push(v) : result.unshift(v) }
65
65
  result
66
66
  end
67
67
 
@@ -69,7 +69,7 @@ module Zip
69
69
  ordered_values.map! { |v| v.to_local_bin.force_encoding('BINARY') }.join
70
70
  end
71
71
 
72
- alias :to_s :to_local_bin
72
+ alias to_s to_local_bin
73
73
 
74
74
  def to_c_dir_bin
75
75
  ordered_values.map! { |v| v.to_c_dir_bin.force_encoding('BINARY') }.join
@@ -83,8 +83,8 @@ module Zip
83
83
  to_local_bin.bytesize
84
84
  end
85
85
 
86
- alias :length :local_size
87
- alias :size :local_size
86
+ alias length local_size
87
+ alias size local_size
88
88
  end
89
89
  end
90
90
 
@@ -1,13 +1,13 @@
1
1
  module Zip
2
2
  class ExtraField::Generic
3
3
  def self.register_map
4
- if self.const_defined?(:HEADER_ID)
5
- ::Zip::ExtraField::ID_MAP[self.const_get(:HEADER_ID)] = self
4
+ if const_defined?(:HEADER_ID)
5
+ ::Zip::ExtraField::ID_MAP[const_get(:HEADER_ID)] = self
6
6
  end
7
7
  end
8
8
 
9
9
  def self.name
10
- @name ||= self.to_s.split("::")[-1]
10
+ @name ||= to_s.split('::')[-1]
11
11
  end
12
12
 
13
13
  # return field [size, content] or false
@@ -16,28 +16,28 @@ module Zip
16
16
  # If nil, start with empty.
17
17
  return false
18
18
  elsif binstr[0, 2] != self.class.const_get(:HEADER_ID)
19
- $stderr.puts "Warning: weired extra feild header ID. skip parsing"
19
+ $stderr.puts 'Warning: weired extra feild header ID. skip parsing'
20
20
  return false
21
21
  end
22
- [binstr[2, 2].unpack("v")[0], binstr[4..-1]]
22
+ [binstr[2, 2].unpack('v')[0], binstr[4..-1]]
23
23
  end
24
24
 
25
25
  def ==(other)
26
26
  return false if self.class != other.class
27
27
  each do |k, v|
28
- v != other[k] and return false
28
+ return false if v != other[k]
29
29
  end
30
30
  true
31
31
  end
32
32
 
33
33
  def to_local_bin
34
34
  s = pack_for_local
35
- self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") << s
35
+ self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v') << s
36
36
  end
37
37
 
38
38
  def to_c_dir_bin
39
39
  s = pack_for_c_dir
40
- self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") << s
40
+ self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v') << s
41
41
  end
42
42
  end
43
43
  end
@@ -5,14 +5,14 @@ module Zip
5
5
  HEADER_ID = [0x000A].pack('v')
6
6
  register_map
7
7
 
8
- WINDOWS_TICK = 10000000.0
9
- SEC_TO_UNIX_EPOCH = 11644473600
8
+ WINDOWS_TICK = 10_000_000.0
9
+ SEC_TO_UNIX_EPOCH = 11_644_473_600
10
10
 
11
11
  def initialize(binstr = nil)
12
12
  @ctime = nil
13
13
  @mtime = nil
14
14
  @atime = nil
15
- binstr and merge(binstr)
15
+ binstr && merge(binstr)
16
16
  end
17
17
 
18
18
  attr_accessor :atime, :ctime, :mtime
@@ -20,18 +20,17 @@ module Zip
20
20
  def merge(binstr)
21
21
  return if binstr.empty?
22
22
  size, content = initial_parse(binstr)
23
- (size && content) or return
23
+ (size && content) || return
24
24
 
25
25
  content = content[4..-1]
26
26
  tags = parse_tags(content)
27
27
 
28
28
  tag1 = tags[1]
29
- if tag1
30
- ntfs_mtime, ntfs_atime, ntfs_ctime = tag1.unpack("Q<Q<Q<")
31
- ntfs_mtime and @mtime ||= from_ntfs_time(ntfs_mtime)
32
- ntfs_atime and @atime ||= from_ntfs_time(ntfs_atime)
33
- ntfs_ctime and @ctime ||= from_ntfs_time(ntfs_ctime)
34
- end
29
+ return unless tag1
30
+ ntfs_mtime, ntfs_atime, ntfs_ctime = tag1.unpack('Q<Q<Q<')
31
+ ntfs_mtime && @mtime ||= from_ntfs_time(ntfs_mtime)
32
+ ntfs_atime && @atime ||= from_ntfs_time(ntfs_atime)
33
+ ntfs_ctime && @ctime ||= from_ntfs_time(ntfs_ctime)
35
34
  end
36
35
 
37
36
  def ==(other)
@@ -48,16 +47,14 @@ module Zip
48
47
  # But 7-zip for Windows only stores at central dir
49
48
  def pack_for_c_dir
50
49
  # reserved 0 and tag 1
51
- s = [0, 1].pack("Vv")
50
+ s = [0, 1].pack('Vv')
52
51
 
53
52
  tag1 = ''.force_encoding(Encoding::BINARY)
54
53
  if @mtime
55
54
  tag1 << [to_ntfs_time(@mtime)].pack('Q<')
56
55
  if @atime
57
56
  tag1 << [to_ntfs_time(@atime)].pack('Q<')
58
- if @ctime
59
- tag1 << [to_ntfs_time(@ctime)].pack('Q<')
60
- end
57
+ tag1 << [to_ntfs_time(@ctime)].pack('Q<') if @ctime
61
58
  end
62
59
  end
63
60
  s << [tag1.bytesize].pack('v') << tag1
@@ -65,11 +62,12 @@ module Zip
65
62
  end
66
63
 
67
64
  private
65
+
68
66
  def parse_tags(content)
69
67
  return {} if content.nil?
70
68
  tags = {}
71
69
  i = 0
72
- while i < content.bytesize do
70
+ while i < content.bytesize
73
71
  tag, size = content[i, 4].unpack('vv')
74
72
  i += 4
75
73
  break unless tag && size
@@ -89,4 +87,4 @@ module Zip
89
87
  ((time.to_f + SEC_TO_UNIX_EPOCH) * WINDOWS_TICK).to_i
90
88
  end
91
89
  end
92
- end
90
+ end
@@ -1,7 +1,7 @@
1
1
  module Zip
2
2
  # Olf Info-ZIP Extra for UNIX uid/gid and file timestampes
3
3
  class ExtraField::OldUnix < ExtraField::Generic
4
- HEADER_ID = "UX"
4
+ HEADER_ID = 'UX'
5
5
  register_map
6
6
 
7
7
  def initialize(binstr = nil)
@@ -9,7 +9,7 @@ module Zip
9
9
  @gid = 0
10
10
  @atime = nil
11
11
  @mtime = nil
12
- binstr and merge(binstr)
12
+ binstr && merge(binstr)
13
13
  end
14
14
 
15
15
  attr_accessor :uid, :gid, :atime, :mtime
@@ -18,8 +18,8 @@ module Zip
18
18
  return if binstr.empty?
19
19
  size, content = initial_parse(binstr)
20
20
  # size: 0 for central directory. 4 for local header
21
- return if (!size || size == 0)
22
- atime, mtime, uid, gid = content.unpack("VVvv")
21
+ return if !size || size == 0
22
+ atime, mtime, uid, gid = content.unpack('VVvv')
23
23
  @uid ||= uid
24
24
  @gid ||= gid
25
25
  @atime ||= atime
@@ -29,17 +29,16 @@ module Zip
29
29
  def ==(other)
30
30
  @uid == other.uid &&
31
31
  @gid == other.gid &&
32
- @atime == other.atime &&
33
- @mtime == other.mtime
32
+ @atime == other.atime &&
33
+ @mtime == other.mtime
34
34
  end
35
35
 
36
36
  def pack_for_local
37
- [@atime, @mtime, @uid, @gid].pack("VVvv")
37
+ [@atime, @mtime, @uid, @gid].pack('VVvv')
38
38
  end
39
39
 
40
40
  def pack_for_c_dir
41
- [@atime, @mtime].pack("VV")
41
+ [@atime, @mtime].pack('VV')
42
42
  end
43
43
  end
44
-
45
- end
44
+ end
@@ -1,7 +1,7 @@
1
1
  module Zip
2
2
  # Info-ZIP Additional timestamp field
3
3
  class ExtraField::UniversalTime < ExtraField::Generic
4
- HEADER_ID = "UT"
4
+ HEADER_ID = 'UT'
5
5
  register_map
6
6
 
7
7
  def initialize(binstr = nil)
@@ -9,7 +9,7 @@ module Zip
9
9
  @mtime = nil
10
10
  @atime = nil
11
11
  @flag = nil
12
- binstr and merge(binstr)
12
+ binstr && merge(binstr)
13
13
  end
14
14
 
15
15
  attr_accessor :atime, :ctime, :mtime, :flag
@@ -17,11 +17,11 @@ module Zip
17
17
  def merge(binstr)
18
18
  return if binstr.empty?
19
19
  size, content = initial_parse(binstr)
20
- size or return
21
- @flag, mtime, atime, ctime = content.unpack("CVVV")
22
- mtime and @mtime ||= ::Zip::DOSTime.at(mtime)
23
- atime and @atime ||= ::Zip::DOSTime.at(atime)
24
- ctime and @ctime ||= ::Zip::DOSTime.at(ctime)
20
+ size || return
21
+ @flag, mtime, atime, ctime = content.unpack('CVVV')
22
+ mtime && @mtime ||= ::Zip::DOSTime.at(mtime)
23
+ atime && @atime ||= ::Zip::DOSTime.at(atime)
24
+ ctime && @ctime ||= ::Zip::DOSTime.at(ctime)
25
25
  end
26
26
 
27
27
  def ==(other)
@@ -31,17 +31,17 @@ module Zip
31
31
  end
32
32
 
33
33
  def pack_for_local
34
- s = [@flag].pack("C")
35
- @flag & 1 != 0 and s << [@mtime.to_i].pack("V")
36
- @flag & 2 != 0 and s << [@atime.to_i].pack("V")
37
- @flag & 4 != 0 and s << [@ctime.to_i].pack("V")
34
+ s = [@flag].pack('C')
35
+ @flag & 1 != 0 && s << [@mtime.to_i].pack('V')
36
+ @flag & 2 != 0 && s << [@atime.to_i].pack('V')
37
+ @flag & 4 != 0 && s << [@ctime.to_i].pack('V')
38
38
  s
39
39
  end
40
40
 
41
41
  def pack_for_c_dir
42
- s = [@flag].pack("C")
43
- @flag & 1 == 1 and s << [@mtime.to_i].pack("V")
42
+ s = [@flag].pack('C')
43
+ @flag & 1 == 1 && s << [@mtime.to_i].pack('V')
44
44
  s
45
45
  end
46
46
  end
47
- end
47
+ end
@@ -1,13 +1,13 @@
1
1
  module Zip
2
2
  # Info-ZIP Extra for UNIX uid/gid
3
3
  class ExtraField::IUnix < ExtraField::Generic
4
- HEADER_ID = "Ux"
4
+ HEADER_ID = 'Ux'
5
5
  register_map
6
6
 
7
7
  def initialize(binstr = nil)
8
8
  @uid = 0
9
9
  @gid = 0
10
- binstr and merge(binstr)
10
+ binstr && merge(binstr)
11
11
  end
12
12
 
13
13
  attr_accessor :uid, :gid
@@ -16,10 +16,10 @@ module Zip
16
16
  return if binstr.empty?
17
17
  size, content = initial_parse(binstr)
18
18
  # size: 0 for central directory. 4 for local header
19
- return if (!size || size == 0)
20
- uid, gid = content.unpack("vv")
21
- @uid ||= uid
22
- @gid ||= gid
19
+ return if !size || size == 0
20
+ uid, gid = content.unpack('vv')
21
+ @uid ||= uid
22
+ @gid ||= gid
23
23
  end
24
24
 
25
25
  def ==(other)
@@ -27,12 +27,11 @@ module Zip
27
27
  end
28
28
 
29
29
  def pack_for_local
30
- [@uid, @gid].pack("vv")
30
+ [@uid, @gid].pack('vv')
31
31
  end
32
32
 
33
33
  def pack_for_c_dir
34
34
  ''
35
35
  end
36
36
  end
37
-
38
- end
37
+ end
@@ -6,21 +6,22 @@ module Zip
6
6
  register_map
7
7
 
8
8
  def initialize(binstr = nil)
9
- @content = nil # unparsed binary; we don't actually know what this contains
10
- # without looking for FFs in the associated file header
11
- # call parse after initializing with a binary string
9
+ # unparsed binary; we don't actually know what this contains
10
+ # without looking for FFs in the associated file header
11
+ # call parse after initializing with a binary string
12
+ @content = nil
12
13
  @original_size = nil
13
14
  @compressed_size = nil
14
15
  @relative_header_offset = nil
15
16
  @disk_start_number = nil
16
- binstr and merge(binstr)
17
+ binstr && merge(binstr)
17
18
  end
18
19
 
19
20
  def ==(other)
20
21
  other.original_size == @original_size &&
21
22
  other.compressed_size == @compressed_size &&
22
- other.relative_header_offset == @relative_header_offset &&
23
- other.disk_start_number == @disk_start_number
23
+ other.relative_header_offset == @relative_header_offset &&
24
+ other.disk_start_number == @disk_start_number
24
25
  end
25
26
 
26
27
  def merge(binstr)
@@ -51,16 +52,16 @@ module Zip
51
52
  def pack_for_local
52
53
  # local header entries must contain original size and compressed size; other fields do not apply
53
54
  return '' unless @original_size && @compressed_size
54
- [@original_size, @compressed_size].pack("Q<Q<")
55
+ [@original_size, @compressed_size].pack('Q<Q<')
55
56
  end
56
57
 
57
58
  def pack_for_c_dir
58
59
  # central directory entries contain only fields that didn't fit in the main entry part
59
60
  packed = ''.force_encoding('BINARY')
60
- packed << [@original_size].pack("Q<") if @original_size
61
- packed << [@compressed_size].pack("Q<") if @compressed_size
62
- packed << [@relative_header_offset].pack("Q<") if @relative_header_offset
63
- packed << [@disk_start_number].pack("V") if @disk_start_number
61
+ packed << [@original_size].pack('Q<') if @original_size
62
+ packed << [@compressed_size].pack('Q<') if @compressed_size
63
+ packed << [@relative_header_offset].pack('Q<') if @relative_header_offset
64
+ packed << [@disk_start_number].pack('V') if @disk_start_number
64
65
  packed
65
66
  end
66
67
  end