rubyzip 0.9.9 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +284 -41
  3. data/Rakefile +11 -6
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +208 -0
  6. data/lib/zip/compressor.rb +1 -2
  7. data/lib/zip/constants.rb +59 -7
  8. data/lib/zip/crypto/encryption.rb +11 -0
  9. data/lib/zip/crypto/null_encryption.rb +43 -0
  10. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  11. data/lib/zip/decompressor.rb +4 -4
  12. data/lib/zip/deflater.rb +17 -13
  13. data/lib/zip/dos_time.rb +13 -14
  14. data/lib/zip/entry.rb +700 -0
  15. data/lib/zip/entry_set.rb +86 -0
  16. data/lib/zip/errors.rb +18 -0
  17. data/lib/zip/extra_field/generic.rb +43 -0
  18. data/lib/zip/extra_field/ntfs.rb +90 -0
  19. data/lib/zip/extra_field/old_unix.rb +44 -0
  20. data/lib/zip/extra_field/universal_time.rb +47 -0
  21. data/lib/zip/extra_field/unix.rb +37 -0
  22. data/lib/zip/extra_field/zip64.rb +68 -0
  23. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  24. data/lib/zip/extra_field.rb +101 -0
  25. data/lib/zip/file.rb +443 -0
  26. data/lib/zip/{zipfilesystem.rb → filesystem.rb} +162 -157
  27. data/lib/zip/inflater.rb +29 -28
  28. data/lib/zip/input_stream.rb +173 -0
  29. data/lib/zip/ioextras/abstract_input_stream.rb +111 -0
  30. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  31. data/lib/zip/ioextras.rb +21 -149
  32. data/lib/zip/null_compressor.rb +2 -2
  33. data/lib/zip/null_decompressor.rb +8 -6
  34. data/lib/zip/null_input_stream.rb +3 -2
  35. data/lib/zip/output_stream.rb +189 -0
  36. data/lib/zip/pass_thru_compressor.rb +6 -6
  37. data/lib/zip/pass_thru_decompressor.rb +19 -19
  38. data/lib/zip/{zip_streamable_directory.rb → streamable_directory.rb} +3 -3
  39. data/lib/zip/streamable_stream.rb +56 -0
  40. data/lib/zip/version.rb +3 -0
  41. data/lib/zip.rb +71 -0
  42. data/samples/example.rb +44 -32
  43. data/samples/example_filesystem.rb +16 -18
  44. data/samples/example_recursive.rb +33 -28
  45. data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +26 -28
  46. data/samples/qtzip.rb +22 -31
  47. data/samples/write_simple.rb +12 -13
  48. data/samples/zipfind.rb +31 -39
  49. data/test/basic_zip_file_test.rb +60 -0
  50. data/test/case_sensitivity_test.rb +69 -0
  51. data/test/central_directory_entry_test.rb +69 -0
  52. data/test/central_directory_test.rb +100 -0
  53. data/test/crypto/null_encryption_test.rb +57 -0
  54. data/test/crypto/traditional_encryption_test.rb +80 -0
  55. data/test/data/WarnInvalidDate.zip +0 -0
  56. data/test/data/file1.txt +46 -0
  57. data/test/data/file1.txt.deflatedData +0 -0
  58. data/test/data/file2.txt +1504 -0
  59. data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
  60. data/test/data/globTest/foo.txt +0 -0
  61. data/test/data/globTest/food.txt +0 -0
  62. data/test/data/globTest.zip +0 -0
  63. data/test/data/gpbit3stored.zip +0 -0
  64. data/test/data/mimetype +1 -0
  65. data/test/data/notzippedruby.rb +7 -0
  66. data/test/data/ntfs.zip +0 -0
  67. data/test/data/oddExtraField.zip +0 -0
  68. data/test/data/path_traversal/Makefile +10 -0
  69. data/test/data/path_traversal/jwilk/README.md +5 -0
  70. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  71. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  72. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  73. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  74. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  75. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  76. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  77. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  78. data/test/data/path_traversal/relative1.zip +0 -0
  79. data/test/data/path_traversal/tilde.zip +0 -0
  80. data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
  81. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  82. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  83. data/test/data/rubycode.zip +0 -0
  84. data/test/data/rubycode2.zip +0 -0
  85. data/test/data/test.xls +0 -0
  86. data/test/data/testDirectory.bin +0 -0
  87. data/test/data/zip64-sample.zip +0 -0
  88. data/test/data/zipWithDirs.zip +0 -0
  89. data/test/data/zipWithEncryption.zip +0 -0
  90. data/test/deflater_test.rb +65 -0
  91. data/test/encryption_test.rb +42 -0
  92. data/test/entry_set_test.rb +163 -0
  93. data/test/entry_test.rb +154 -0
  94. data/test/errors_test.rb +35 -0
  95. data/test/extra_field_test.rb +76 -0
  96. data/test/file_extract_directory_test.rb +54 -0
  97. data/test/file_extract_test.rb +145 -0
  98. data/test/file_permissions_test.rb +65 -0
  99. data/test/file_split_test.rb +57 -0
  100. data/test/file_test.rb +666 -0
  101. data/test/filesystem/dir_iterator_test.rb +58 -0
  102. data/test/filesystem/directory_test.rb +139 -0
  103. data/test/filesystem/file_mutating_test.rb +87 -0
  104. data/test/filesystem/file_nonmutating_test.rb +508 -0
  105. data/test/filesystem/file_stat_test.rb +64 -0
  106. data/test/gentestfiles.rb +126 -0
  107. data/test/inflater_test.rb +14 -0
  108. data/test/input_stream_test.rb +182 -0
  109. data/test/ioextras/abstract_input_stream_test.rb +102 -0
  110. data/test/ioextras/abstract_output_stream_test.rb +106 -0
  111. data/test/ioextras/fake_io_test.rb +18 -0
  112. data/test/local_entry_test.rb +154 -0
  113. data/test/output_stream_test.rb +128 -0
  114. data/test/pass_thru_compressor_test.rb +30 -0
  115. data/test/pass_thru_decompressor_test.rb +14 -0
  116. data/test/path_traversal_test.rb +141 -0
  117. data/test/samples/example_recursive_test.rb +37 -0
  118. data/test/settings_test.rb +95 -0
  119. data/test/test_helper.rb +234 -0
  120. data/test/unicode_file_names_and_comments_test.rb +62 -0
  121. data/test/zip64_full_test.rb +51 -0
  122. data/test/zip64_support_test.rb +14 -0
  123. metadata +274 -41
  124. data/NEWS +0 -172
  125. data/lib/zip/settings.rb +0 -10
  126. data/lib/zip/tempfile_bugfixed.rb +0 -195
  127. data/lib/zip/zip.rb +0 -56
  128. data/lib/zip/zip_central_directory.rb +0 -135
  129. data/lib/zip/zip_entry.rb +0 -638
  130. data/lib/zip/zip_entry_set.rb +0 -77
  131. data/lib/zip/zip_extra_field.rb +0 -213
  132. data/lib/zip/zip_file.rb +0 -340
  133. data/lib/zip/zip_input_stream.rb +0 -144
  134. data/lib/zip/zip_output_stream.rb +0 -173
  135. data/lib/zip/zip_streamable_stream.rb +0 -47
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << "../lib"
3
+ $: << '../lib'
4
4
 
5
5
  $VERBOSE = true
6
6
 
7
7
  require 'gtk'
8
- require 'zip/zip'
8
+ require 'zip'
9
9
 
10
10
  class MainApp < Gtk::Window
11
11
  def initialize
12
12
  super()
13
13
  set_usize(400, 256)
14
- set_title("rubyzip")
14
+ set_title('rubyzip')
15
15
  signal_connect(Gtk::Window::SIGNAL_DESTROY) { Gtk.main_quit }
16
16
 
17
17
  box = Gtk::VBox.new(false, 0)
@@ -19,26 +19,25 @@ class MainApp < Gtk::Window
19
19
 
20
20
  @zipfile = nil
21
21
  @buttonPanel = ButtonPanel.new
22
- @buttonPanel.openButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
22
+ @buttonPanel.openButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) do
23
23
  show_file_selector
24
- }
25
- @buttonPanel.extractButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
26
- puts "Not implemented!"
27
- }
24
+ end
25
+ @buttonPanel.extractButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) do
26
+ puts 'Not implemented!'
27
+ end
28
28
  box.pack_start(@buttonPanel, false, false, 0)
29
-
29
+
30
30
  sw = Gtk::ScrolledWindow.new
31
31
  sw.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
32
32
  box.pack_start(sw, true, true, 0)
33
33
 
34
- @clist = Gtk::CList.new(["Name", "Size", "Compression"])
34
+ @clist = Gtk::CList.new(%w[Name Size Compression])
35
35
  @clist.set_selection_mode(Gtk::SELECTION_BROWSE)
36
36
  @clist.set_column_width(0, 120)
37
37
  @clist.set_column_width(1, 120)
38
- @clist.signal_connect(Gtk::CList::SIGNAL_SELECT_ROW) {
39
- |w, row, column, event|
38
+ @clist.signal_connect(Gtk::CList::SIGNAL_SELECT_ROW) do |_w, row, _column, _event|
40
39
  @selected_row = row
41
- }
40
+ end
42
41
  sw.add(@clist)
43
42
  end
44
43
 
@@ -48,38 +47,37 @@ class MainApp < Gtk::Window
48
47
  super
49
48
  set_layout(Gtk::BUTTONBOX_START)
50
49
  set_spacing(0)
51
- @openButton = Gtk::Button.new("Open archive")
52
- @extractButton = Gtk::Button.new("Extract entry")
50
+ @openButton = Gtk::Button.new('Open archive')
51
+ @extractButton = Gtk::Button.new('Extract entry')
53
52
  pack_start(@openButton)
54
53
  pack_start(@extractButton)
55
54
  end
56
55
  end
57
56
 
58
57
  def show_file_selector
59
- @fileSelector = Gtk::FileSelection.new("Open zip file")
58
+ @fileSelector = Gtk::FileSelection.new('Open zip file')
60
59
  @fileSelector.show
61
- @fileSelector.ok_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
60
+ @fileSelector.ok_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do
62
61
  open_zip(@fileSelector.filename)
63
62
  @fileSelector.destroy
64
- }
65
- @fileSelector.cancel_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
63
+ end
64
+ @fileSelector.cancel_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do
66
65
  @fileSelector.destroy
67
- }
66
+ end
68
67
  end
69
68
 
70
69
  def open_zip(filename)
71
- @zipfile = Zip::ZipFile.open(filename)
70
+ @zipfile = Zip::File.open(filename)
72
71
  @clist.clear
73
- @zipfile.each {
74
- |entry|
75
- @clist.append([ entry.name,
76
- entry.size.to_s,
77
- (100.0*entry.compressedSize/entry.size).to_s+"%" ])
78
- }
72
+ @zipfile.each do |entry|
73
+ @clist.append([entry.name,
74
+ entry.size.to_s,
75
+ (100.0 * entry.compressedSize / entry.size).to_s + '%'])
76
+ end
79
77
  end
80
78
  end
81
79
 
82
- mainApp = MainApp.new()
80
+ mainApp = MainApp.new
83
81
 
84
82
  mainApp.show_all
85
83
 
data/samples/qtzip.rb CHANGED
@@ -1,22 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $VERBOSE=true
3
+ $VERBOSE = true
4
4
 
5
- $: << "../lib"
5
+ $: << '../lib'
6
6
 
7
7
  require 'Qt'
8
8
  system('rbuic -o zipdialogui.rb zipdialogui.ui')
9
9
  require 'zipdialogui.rb'
10
- require 'zip/zip'
11
-
12
-
10
+ require 'zip'
13
11
 
14
12
  a = Qt::Application.new(ARGV)
15
13
 
16
14
  class ZipDialog < ZipDialogUI
17
-
18
-
19
- def initialize()
15
+ def initialize
20
16
  super()
21
17
  connect(child('add_button'), SIGNAL('clicked()'),
22
18
  self, SLOT('add_files()'))
@@ -25,23 +21,21 @@ class ZipDialog < ZipDialogUI
25
21
  end
26
22
 
27
23
  def zipfile(&proc)
28
- Zip::ZipFile.open(@zip_filename, &proc)
24
+ Zip::File.open(@zip_filename, &proc)
29
25
  end
30
26
 
31
27
  def each(&proc)
32
- Zip::ZipFile.foreach(@zip_filename, &proc)
28
+ Zip::File.foreach(@zip_filename, &proc)
33
29
  end
34
-
35
- def refresh()
36
- lv = child("entry_list_view")
30
+
31
+ def refresh
32
+ lv = child('entry_list_view')
37
33
  lv.clear
38
- each {
39
- |e|
34
+ each do |e|
40
35
  lv.insert_item(Qt::ListViewItem.new(lv, e.name, e.size.to_s))
41
- }
36
+ end
42
37
  end
43
38
 
44
-
45
39
  def load(zipfile)
46
40
  @zip_filename = zipfile
47
41
  refresh
@@ -49,13 +43,11 @@ class ZipDialog < ZipDialogUI
49
43
 
50
44
  def add_files
51
45
  l = Qt::FileDialog.getOpenFileNames(nil, nil, self)
52
- zipfile {
53
- |zf|
54
- l.each {
55
- |path|
46
+ zipfile do |zf|
47
+ l.each do |path|
56
48
  zf.add(File.basename(path), path)
57
- }
58
- }
49
+ end
50
+ end
59
51
  refresh
60
52
  end
61
53
 
@@ -63,7 +55,7 @@ class ZipDialog < ZipDialogUI
63
55
  selected_items = []
64
56
  unselected_items = []
65
57
  lv_item = entry_list_view.first_child
66
- while (lv_item)
58
+ while lv_item
67
59
  if entry_list_view.is_selected(lv_item)
68
60
  selected_items << lv_item.text(0)
69
61
  else
@@ -73,22 +65,21 @@ class ZipDialog < ZipDialogUI
73
65
  end
74
66
  puts "selected_items.size = #{selected_items.size}"
75
67
  puts "unselected_items.size = #{unselected_items.size}"
76
- items = selected_items.size > 0 ? selected_items : unselected_items
68
+ items = !selected_items.empty? ? selected_items : unselected_items
77
69
  puts "items.size = #{items.size}"
78
70
 
79
71
  d = Qt::FileDialog.get_existing_directory(nil, self)
80
- if (!d)
81
- puts "No directory chosen"
72
+ if !d
73
+ puts 'No directory chosen'
82
74
  else
83
75
  zipfile { |zf| items.each { |e| zf.extract(e, File.join(d, e)) } }
84
76
  end
85
-
86
77
  end
87
78
 
88
79
  slots 'add_files()', 'extract_files()'
89
80
  end
90
81
 
91
- if !ARGV[0]
82
+ unless ARGV[0]
92
83
  puts "usage: #{$0} zipname"
93
84
  exit
94
85
  end
@@ -97,5 +88,5 @@ zd = ZipDialog.new
97
88
  zd.load(ARGV[0])
98
89
 
99
90
  a.mainWidget = zd
100
- zd.show()
101
- a.exec()
91
+ zd.show
92
+ a.exec
@@ -1,13 +1,12 @@
1
- #!/usr/bin/env ruby
2
-
3
- $: << "../lib"
4
-
5
- require 'zip/zip'
6
-
7
- include Zip
8
-
9
- ZipOutputStream.open('simple.zip') {
10
- |zos|
11
- ze = zos.put_next_entry 'entry.txt'
12
- zos.puts "Hello world"
13
- }
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << '../lib'
4
+
5
+ require 'zip'
6
+
7
+ include Zip
8
+
9
+ OutputStream.open('simple.zip') do |zos|
10
+ zos.put_next_entry 'entry.txt'
11
+ zos.puts 'Hello world'
12
+ end
data/samples/zipfind.rb CHANGED
@@ -2,72 +2,64 @@
2
2
 
3
3
  $VERBOSE = true
4
4
 
5
- $: << "../lib"
5
+ $: << '../lib'
6
6
 
7
- require 'zip/zip'
7
+ require 'zip'
8
8
  require 'find'
9
9
 
10
10
  module Zip
11
11
  module ZipFind
12
12
  def self.find(path, zipFilePattern = /\.zip$/i)
13
- Find.find(path) {
14
- |fileName|
15
- yield(fileName)
16
- if zipFilePattern.match(fileName) && File.file?(fileName)
17
- begin
18
- Zip::ZipFile.foreach(fileName) {
19
- |zipEntry|
20
- yield(fileName + File::SEPARATOR + zipEntry.to_s)
21
- }
22
- rescue Errno::EACCES => ex
23
- puts ex
24
- end
25
- end
26
- }
13
+ Find.find(path) do |fileName|
14
+ yield(fileName)
15
+ next unless zipFilePattern.match(fileName) && File.file?(fileName)
16
+ begin
17
+ Zip::File.foreach(fileName) do |zipEntry|
18
+ yield(fileName + File::SEPARATOR + zipEntry.to_s)
19
+ end
20
+ rescue Errno::EACCES => ex
21
+ puts ex
22
+ end
23
+ end
27
24
  end
28
25
 
29
26
  def self.find_file(path, fileNamePattern, zipFilePattern = /\.zip$/i)
30
- self.find(path, zipFilePattern) {
31
- |fileName|
32
- yield(fileName) if fileNamePattern.match(fileName)
33
- }
27
+ find(path, zipFilePattern) do |fileName|
28
+ yield(fileName) if fileNamePattern.match(fileName)
29
+ end
34
30
  end
35
-
36
31
  end
37
32
  end
38
33
 
39
- if __FILE__ == $0
34
+ if $0 == __FILE__
40
35
  module ZipFindConsoleRunner
41
-
42
- PATH_ARG_INDEX = 0;
43
- FILENAME_PATTERN_ARG_INDEX = 1;
44
- ZIPFILE_PATTERN_ARG_INDEX = 2;
45
-
36
+ PATH_ARG_INDEX = 0
37
+ FILENAME_PATTERN_ARG_INDEX = 1
38
+ ZIPFILE_PATTERN_ARG_INDEX = 2
39
+
46
40
  def self.run(args)
47
41
  check_args(args)
48
- Zip::ZipFind.find_file(args[PATH_ARG_INDEX],
49
- args[FILENAME_PATTERN_ARG_INDEX],
50
- args[ZIPFILE_PATTERN_ARG_INDEX]) {
51
- |fileName|
52
- report_entry_found fileName
53
- }
42
+ Zip::ZipFind.find_file(args[PATH_ARG_INDEX],
43
+ args[FILENAME_PATTERN_ARG_INDEX],
44
+ args[ZIPFILE_PATTERN_ARG_INDEX]) do |fileName|
45
+ report_entry_found fileName
46
+ end
54
47
  end
55
-
48
+
56
49
  def self.check_args(args)
57
- if (args.size != 3)
58
- usage
59
- exit
50
+ if args.size != 3
51
+ usage
52
+ exit
60
53
  end
61
54
  end
62
55
 
63
56
  def self.usage
64
57
  puts "Usage: #{$0} PATH ZIPFILENAME_PATTERN FILNAME_PATTERN"
65
58
  end
66
-
59
+
67
60
  def self.report_entry_found(fileName)
68
61
  puts fileName
69
62
  end
70
-
71
63
  end
72
64
 
73
65
  ZipFindConsoleRunner.run(ARGV)
@@ -0,0 +1,60 @@
1
+ require 'test_helper'
2
+
3
+ class BasicZipFileTest < MiniTest::Test
4
+ include AssertEntry
5
+
6
+ def setup
7
+ @zip_file = ::Zip::File.new(TestZipFile::TEST_ZIP2.zip_name)
8
+ @testEntryNameIndex = 0
9
+ end
10
+
11
+ def test_entries
12
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
13
+ @zip_file.entries.entries.sort.map { |e| e.name })
14
+ end
15
+
16
+ def test_each
17
+ count = 0
18
+ visited = {}
19
+ @zip_file.each do |entry|
20
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
21
+ assert(!visited.include?(entry.name))
22
+ visited[entry.name] = nil
23
+ count = count.succ
24
+ end
25
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
26
+ end
27
+
28
+ def test_foreach
29
+ count = 0
30
+ visited = {}
31
+ ::Zip::File.foreach(TestZipFile::TEST_ZIP2.zip_name) do |entry|
32
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
33
+ assert(!visited.include?(entry.name))
34
+ visited[entry.name] = nil
35
+ count = count.succ
36
+ end
37
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
38
+ end
39
+
40
+ def test_get_input_stream
41
+ count = 0
42
+ visited = {}
43
+ @zip_file.each do |entry|
44
+ assert_entry(entry.name, @zip_file.get_input_stream(entry), entry.name)
45
+ assert(!visited.include?(entry.name))
46
+ visited[entry.name] = nil
47
+ count = count.succ
48
+ end
49
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
50
+ end
51
+
52
+ def test_get_input_stream_block
53
+ fileAndEntryName = @zip_file.entries.first.name
54
+ @zip_file.get_input_stream(fileAndEntryName) do |zis|
55
+ assert_entry_contents_for_stream(fileAndEntryName,
56
+ zis,
57
+ fileAndEntryName)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,69 @@
1
+ require 'test_helper'
2
+
3
+ class ZipCaseSensitivityTest < MiniTest::Test
4
+ include CommonZipFileFixture
5
+
6
+ SRC_FILES = [['test/data/file1.txt', 'testfile.rb'],
7
+ ['test/data/file2.txt', 'testFILE.rb']]
8
+
9
+ def teardown
10
+ ::Zip.case_insensitive_match = false
11
+ end
12
+
13
+ # Ensure that everything functions normally when +case_insensitive_match = false+
14
+ def test_add_case_sensitive
15
+ ::Zip.case_insensitive_match = false
16
+
17
+ SRC_FILES.each { |fn, _en| assert(::File.exist?(fn)) }
18
+ zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE)
19
+
20
+ SRC_FILES.each { |fn, en| zf.add(en, fn) }
21
+ zf.close
22
+
23
+ zfRead = ::Zip::File.new(EMPTY_FILENAME)
24
+ assert_equal(SRC_FILES.size, zfRead.entries.length)
25
+ SRC_FILES.each_with_index { |a, i|
26
+ assert_equal(a.last, zfRead.entries[i].name)
27
+ AssertEntry.assert_contents(a.first,
28
+ zfRead.get_input_stream(a.last) { |zis| zis.read })
29
+ }
30
+ end
31
+
32
+ # Ensure that names are treated case insensitively when adding files and +case_insensitive_match = false+
33
+ def test_add_case_insensitive
34
+ ::Zip.case_insensitive_match = true
35
+
36
+ SRC_FILES.each { |fn, _en| assert(::File.exist?(fn)) }
37
+ zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE)
38
+
39
+ assert_raises Zip::EntryExistsError do
40
+ SRC_FILES.each { |fn, en| zf.add(en, fn) }
41
+ end
42
+ end
43
+
44
+ # Ensure that names are treated case insensitively when reading files and +case_insensitive_match = true+
45
+ def test_add_case_sensitive_read_case_insensitive
46
+ ::Zip.case_insensitive_match = false
47
+
48
+ SRC_FILES.each { |fn, _en| assert(::File.exist?(fn)) }
49
+ zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE)
50
+
51
+ SRC_FILES.each { |fn, en| zf.add(en, fn) }
52
+ zf.close
53
+
54
+ ::Zip.case_insensitive_match = true
55
+
56
+ zfRead = ::Zip::File.new(EMPTY_FILENAME)
57
+ assert_equal(SRC_FILES.collect { |_fn, en| en.downcase }.uniq.size, zfRead.entries.length)
58
+ assert_equal(SRC_FILES.last.last.downcase, zfRead.entries.first.name.downcase)
59
+ AssertEntry.assert_contents(SRC_FILES.last.first,
60
+ zfRead.get_input_stream(SRC_FILES.last.last) { |zis| zis.read })
61
+ end
62
+
63
+ private
64
+
65
+ def assert_contains(zf, entryName, filename = entryName)
66
+ assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
67
+ assert_entry_contents(zf, entryName, filename) if File.exist?(filename)
68
+ end
69
+ end
@@ -0,0 +1,69 @@
1
+ require 'test_helper'
2
+
3
+ class ZipCentralDirectoryEntryTest < MiniTest::Test
4
+ def test_read_from_stream
5
+ File.open('test/data/testDirectory.bin', 'rb') do |file|
6
+ entry = ::Zip::Entry.read_c_dir_entry(file)
7
+
8
+ assert_equal('longAscii.txt', entry.name)
9
+ assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
10
+ assert_equal(106_490, entry.size)
11
+ assert_equal(3784, entry.compressed_size)
12
+ assert_equal(0xfcd1799c, entry.crc)
13
+ assert_equal('', entry.comment)
14
+
15
+ entry = ::Zip::Entry.read_c_dir_entry(file)
16
+ assert_equal('empty.txt', entry.name)
17
+ assert_equal(::Zip::Entry::STORED, entry.compression_method)
18
+ assert_equal(0, entry.size)
19
+ assert_equal(0, entry.compressed_size)
20
+ assert_equal(0x0, entry.crc)
21
+ assert_equal('', entry.comment)
22
+
23
+ entry = ::Zip::Entry.read_c_dir_entry(file)
24
+ assert_equal('short.txt', entry.name)
25
+ assert_equal(::Zip::Entry::STORED, entry.compression_method)
26
+ assert_equal(6, entry.size)
27
+ assert_equal(6, entry.compressed_size)
28
+ assert_equal(0xbb76fe69, entry.crc)
29
+ assert_equal('', entry.comment)
30
+
31
+ entry = ::Zip::Entry.read_c_dir_entry(file)
32
+ assert_equal('longBinary.bin', entry.name)
33
+ assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
34
+ assert_equal(1_000_024, entry.size)
35
+ assert_equal(70_847, entry.compressed_size)
36
+ assert_equal(0x10da7d59, entry.crc)
37
+ assert_equal('', entry.comment)
38
+
39
+ entry = ::Zip::Entry.read_c_dir_entry(file)
40
+ assert_nil(entry)
41
+ # Fields that are not check by this test:
42
+ # version made by 2 bytes
43
+ # version needed to extract 2 bytes
44
+ # general purpose bit flag 2 bytes
45
+ # last mod file time 2 bytes
46
+ # last mod file date 2 bytes
47
+ # compressed size 4 bytes
48
+ # uncompressed size 4 bytes
49
+ # disk number start 2 bytes
50
+ # internal file attributes 2 bytes
51
+ # external file attributes 4 bytes
52
+ # relative offset of local header 4 bytes
53
+
54
+ # file name (variable size)
55
+ # extra field (variable size)
56
+ # file comment (variable size)
57
+ end
58
+ end
59
+
60
+ def test_read_entry_from_truncated_zip_file
61
+ fragment = ''
62
+ File.open('test/data/testDirectory.bin') { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
63
+ fragment.extend(IOizeString)
64
+ entry = ::Zip::Entry.new
65
+ entry.read_c_dir_entry(fragment)
66
+ fail 'ZipError expected'
67
+ rescue ::Zip::Error
68
+ end
69
+ end
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ class ZipCentralDirectoryTest < MiniTest::Test
4
+ def teardown
5
+ ::Zip.reset!
6
+ end
7
+
8
+ def test_read_from_stream
9
+ ::File.open(TestZipFile::TEST_ZIP2.zip_name, 'rb') do |zipFile|
10
+ cdir = ::Zip::CentralDirectory.read_from_stream(zipFile)
11
+
12
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
13
+ assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) do |cdirEntry, testEntryName|
14
+ cdirEntry.name == testEntryName
15
+ end)
16
+ assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
17
+ end
18
+ end
19
+
20
+ def test_read_from_invalid_stream
21
+ File.open('test/data/file2.txt', 'rb') do |zipFile|
22
+ cdir = ::Zip::CentralDirectory.new
23
+ cdir.read_from_stream(zipFile)
24
+ end
25
+ fail 'ZipError expected!'
26
+ rescue ::Zip::Error
27
+ end
28
+
29
+ def test_read_from_truncated_zip_file
30
+ fragment = ''
31
+ File.open('test/data/testDirectory.bin', 'rb') { |f| fragment = f.read }
32
+ fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
33
+ fragment.extend(IOizeString)
34
+ entry = ::Zip::CentralDirectory.new
35
+ entry.read_from_stream(fragment)
36
+ fail 'ZipError expected'
37
+ rescue ::Zip::Error
38
+ end
39
+
40
+ def test_write_to_stream
41
+ entries = [::Zip::Entry.new('file.zip', 'flimse', 'myComment', 'somethingExtra'),
42
+ ::Zip::Entry.new('file.zip', 'secondEntryName'),
43
+ ::Zip::Entry.new('file.zip', 'lastEntry.txt', 'Has a comment too')]
44
+ cdir = ::Zip::CentralDirectory.new(entries, 'my zip comment')
45
+ File.open('test/data/generated/cdirtest.bin', 'wb') { |f| cdir.write_to_stream(f) }
46
+ cdirReadback = ::Zip::CentralDirectory.new
47
+ File.open('test/data/generated/cdirtest.bin', 'rb') { |f| cdirReadback.read_from_stream(f) }
48
+
49
+ assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
50
+ end
51
+
52
+ def test_write64_to_stream
53
+ ::Zip.write_zip64_support = true
54
+ entries = [::Zip::Entry.new('file.zip', 'file1-little', 'comment1', '', 200, 101, ::Zip::Entry::STORED, 200),
55
+ ::Zip::Entry.new('file.zip', 'file2-big', 'comment2', '', 18_000_000_000, 102, ::Zip::Entry::DEFLATED, 20_000_000_000),
56
+ ::Zip::Entry.new('file.zip', 'file3-alsobig', 'comment3', '', 15_000_000_000, 103, ::Zip::Entry::DEFLATED, 21_000_000_000),
57
+ ::Zip::Entry.new('file.zip', 'file4-little', 'comment4', '', 100, 104, ::Zip::Entry::DEFLATED, 121)]
58
+ [0, 250, 18_000_000_300, 33_000_000_350].each_with_index do |offset, index|
59
+ entries[index].local_header_offset = offset
60
+ end
61
+ cdir = ::Zip::CentralDirectory.new(entries, 'zip comment')
62
+ File.open('test/data/generated/cdir64test.bin', 'wb') { |f| cdir.write_to_stream(f) }
63
+ cdirReadback = ::Zip::CentralDirectory.new
64
+ File.open('test/data/generated/cdir64test.bin', 'rb') { |f| cdirReadback.read_from_stream(f) }
65
+
66
+ assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
67
+ assert_equal(::Zip::VERSION_NEEDED_TO_EXTRACT_ZIP64, cdirReadback.instance_variable_get(:@version_needed_for_extract))
68
+ end
69
+
70
+ def test_equality
71
+ cdir1 = ::Zip::CentralDirectory.new([::Zip::Entry.new('file.zip', 'flimse', nil,
72
+ 'somethingExtra'),
73
+ ::Zip::Entry.new('file.zip', 'secondEntryName'),
74
+ ::Zip::Entry.new('file.zip', 'lastEntry.txt')],
75
+ 'my zip comment')
76
+ cdir2 = ::Zip::CentralDirectory.new([::Zip::Entry.new('file.zip', 'flimse', nil,
77
+ 'somethingExtra'),
78
+ ::Zip::Entry.new('file.zip', 'secondEntryName'),
79
+ ::Zip::Entry.new('file.zip', 'lastEntry.txt')],
80
+ 'my zip comment')
81
+ cdir3 = ::Zip::CentralDirectory.new([::Zip::Entry.new('file.zip', 'flimse', nil,
82
+ 'somethingExtra'),
83
+ ::Zip::Entry.new('file.zip', 'secondEntryName'),
84
+ ::Zip::Entry.new('file.zip', 'lastEntry.txt')],
85
+ 'comment?')
86
+ cdir4 = ::Zip::CentralDirectory.new([::Zip::Entry.new('file.zip', 'flimse', nil,
87
+ 'somethingExtra'),
88
+ ::Zip::Entry.new('file.zip', 'lastEntry.txt')],
89
+ 'comment?')
90
+ assert_equal(cdir1, cdir1)
91
+ assert_equal(cdir1, cdir2)
92
+
93
+ assert(cdir1 != cdir3)
94
+ assert(cdir2 != cdir3)
95
+ assert(cdir2 != cdir3)
96
+ assert(cdir3 != cdir4)
97
+
98
+ assert(cdir3 != 'hello')
99
+ end
100
+ end