ziperu 0.1.1-aarch64-linux
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +24 -0
- data/LICENSE-rubyzip.txt +24 -0
- data/LICENSE.txt +21 -0
- data/README.md +276 -0
- data/lib/rubyzip.rb +4 -0
- data/lib/zip/central_directory.rb +5 -0
- data/lib/zip/compressor.rb +5 -0
- data/lib/zip/constants.rb +5 -0
- data/lib/zip/crypto/aes_encryption.rb +5 -0
- data/lib/zip/crypto/decrypted_io.rb +5 -0
- data/lib/zip/crypto/encryption.rb +5 -0
- data/lib/zip/crypto/null_encryption.rb +5 -0
- data/lib/zip/crypto/traditional_encryption.rb +5 -0
- data/lib/zip/crypto.rb +5 -0
- data/lib/zip/decompressor.rb +5 -0
- data/lib/zip/deflater.rb +5 -0
- data/lib/zip/dirtyable.rb +5 -0
- data/lib/zip/dos_time.rb +5 -0
- data/lib/zip/entry.rb +5 -0
- data/lib/zip/entry_set.rb +5 -0
- data/lib/zip/errors.rb +5 -0
- data/lib/zip/extra_field/aes.rb +5 -0
- data/lib/zip/extra_field/generic.rb +5 -0
- data/lib/zip/extra_field/ntfs.rb +5 -0
- data/lib/zip/extra_field/old_unix.rb +5 -0
- data/lib/zip/extra_field/universal_time.rb +5 -0
- data/lib/zip/extra_field/unix.rb +5 -0
- data/lib/zip/extra_field/unknown.rb +5 -0
- data/lib/zip/extra_field/zip64.rb +5 -0
- data/lib/zip/extra_field.rb +5 -0
- data/lib/zip/file.rb +5 -0
- data/lib/zip/file_split.rb +5 -0
- data/lib/zip/filesystem/dir.rb +5 -0
- data/lib/zip/filesystem/directory_iterator.rb +5 -0
- data/lib/zip/filesystem/file.rb +5 -0
- data/lib/zip/filesystem/file_stat.rb +5 -0
- data/lib/zip/filesystem/zip_file_name_mapper.rb +5 -0
- data/lib/zip/filesystem.rb +5 -0
- data/lib/zip/inflater.rb +5 -0
- data/lib/zip/input_stream.rb +5 -0
- data/lib/zip/ioextras/abstract_input_stream.rb +5 -0
- data/lib/zip/ioextras/abstract_output_stream.rb +5 -0
- data/lib/zip/ioextras/fake_io.rb +5 -0
- data/lib/zip/ioextras.rb +5 -0
- data/lib/zip/null_compressor.rb +5 -0
- data/lib/zip/null_decompressor.rb +5 -0
- data/lib/zip/null_input_stream.rb +5 -0
- data/lib/zip/output_stream.rb +5 -0
- data/lib/zip/pass_thru_compressor.rb +5 -0
- data/lib/zip/pass_thru_decompressor.rb +5 -0
- data/lib/zip/streamable_directory.rb +5 -0
- data/lib/zip/streamable_stream.rb +5 -0
- data/lib/zip/version.rb +5 -0
- data/lib/zip.rb +19 -0
- data/lib/ziperu/3.1/ziperu.so +0 -0
- data/lib/ziperu/3.2/ziperu.so +0 -0
- data/lib/ziperu/3.3/ziperu.so +0 -0
- data/lib/ziperu/3.4/ziperu.so +0 -0
- data/lib/ziperu/4.0/ziperu.so +0 -0
- data/lib/ziperu/central_directory.rb +136 -0
- data/lib/ziperu/compressor.rb +14 -0
- data/lib/ziperu/constants.rb +148 -0
- data/lib/ziperu/crypto.rb +72 -0
- data/lib/ziperu/decompressor.rb +35 -0
- data/lib/ziperu/deflater.rb +41 -0
- data/lib/ziperu/dirtyable.rb +48 -0
- data/lib/ziperu/dos_time.rb +87 -0
- data/lib/ziperu/entry.rb +760 -0
- data/lib/ziperu/entry_set.rb +147 -0
- data/lib/ziperu/errors.rb +154 -0
- data/lib/ziperu/extra_field/aes.rb +52 -0
- data/lib/ziperu/extra_field/generic.rb +45 -0
- data/lib/ziperu/extra_field/ntfs.rb +98 -0
- data/lib/ziperu/extra_field/old_unix.rb +52 -0
- data/lib/ziperu/extra_field/universal_time.rb +81 -0
- data/lib/ziperu/extra_field/unix.rb +45 -0
- data/lib/ziperu/extra_field/unknown.rb +37 -0
- data/lib/ziperu/extra_field/zip64.rb +86 -0
- data/lib/ziperu/extra_field.rb +109 -0
- data/lib/ziperu/file.rb +614 -0
- data/lib/ziperu/file_split.rb +93 -0
- data/lib/ziperu/filesystem/dir.rb +88 -0
- data/lib/ziperu/filesystem/directory_iterator.rb +50 -0
- data/lib/ziperu/filesystem/file.rb +265 -0
- data/lib/ziperu/filesystem/file_stat.rb +112 -0
- data/lib/ziperu/filesystem/zip_file_name_mapper.rb +83 -0
- data/lib/ziperu/filesystem.rb +76 -0
- data/lib/ziperu/inflater.rb +60 -0
- data/lib/ziperu/input_stream.rb +296 -0
- data/lib/ziperu/ioextras/abstract_input_stream.rb +137 -0
- data/lib/ziperu/ioextras/abstract_output_stream.rb +57 -0
- data/lib/ziperu/ioextras/fake_io.rb +41 -0
- data/lib/ziperu/ioextras.rb +42 -0
- data/lib/ziperu/null_compressor.rb +20 -0
- data/lib/ziperu/null_decompressor.rb +25 -0
- data/lib/ziperu/null_input_stream.rb +55 -0
- data/lib/ziperu/output_stream.rb +223 -0
- data/lib/ziperu/pass_thru_compressor.rb +29 -0
- data/lib/ziperu/pass_thru_decompressor.rb +37 -0
- data/lib/ziperu/streamable_directory.rb +15 -0
- data/lib/ziperu/streamable_stream.rb +59 -0
- data/lib/ziperu/version.rb +7 -0
- data/lib/ziperu.rb +116 -0
- metadata +156 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ziperu
|
|
4
|
+
# What `get_input_stream` hands out for a directory entry: an IO-like
|
|
5
|
+
# object that is already at EOF. A module, as in rubyzip, so it is passed
|
|
6
|
+
# around by reference rather than instantiated.
|
|
7
|
+
module NullInputStream # :nodoc:all
|
|
8
|
+
extend ::Ziperu::IOExtras::FakeIO
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def read(maxlen = nil, _out_string = nil)
|
|
12
|
+
maxlen.nil? || maxlen.zero? ? '' : nil
|
|
13
|
+
end
|
|
14
|
+
alias sysread read
|
|
15
|
+
|
|
16
|
+
def gets(*_args, **_opts)
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def readline(*_args, **_opts)
|
|
21
|
+
raise EOFError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def readlines(*_args, **_opts)
|
|
25
|
+
[]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def each(*_args, **_opts)
|
|
29
|
+
return to_enum(:each) unless block_given?
|
|
30
|
+
end
|
|
31
|
+
alias each_line each
|
|
32
|
+
|
|
33
|
+
def eof?
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
alias eof eof?
|
|
37
|
+
|
|
38
|
+
def pos
|
|
39
|
+
0
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def lineno
|
|
43
|
+
0
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def rewind; end
|
|
47
|
+
|
|
48
|
+
def close; end
|
|
49
|
+
|
|
50
|
+
def size
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ziperu
|
|
4
|
+
# Writes zip archives entry by entry, with rubyzip's `Ziperu::OutputStream`
|
|
5
|
+
# API: `put_next_entry` opens an entry, then the IO-like methods (`<<`,
|
|
6
|
+
# `write`, `puts`, `print`) fill it.
|
|
7
|
+
#
|
|
8
|
+
# Ziperu::OutputStream.open("my.zip") do |io|
|
|
9
|
+
# io.put_next_entry("first_entry.txt")
|
|
10
|
+
# io.write "Hello world!"
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# `write_buffer` writes to an IO (a StringIO by default) instead of a file.
|
|
14
|
+
class OutputStream
|
|
15
|
+
include ::Ziperu::IOExtras::AbstractOutputStream
|
|
16
|
+
|
|
17
|
+
attr_accessor :comment
|
|
18
|
+
|
|
19
|
+
# Opens the indicated zip file. If a file with that name already exists
|
|
20
|
+
# it will be overwritten. With `stream: true`, `file_name` is an IO
|
|
21
|
+
# object that receives the archive from its start, entry by entry if it
|
|
22
|
+
# is seekable (a StringIO, File or Tempfile) and all at once on
|
|
23
|
+
# `close_buffer` if it is not (a pipe).
|
|
24
|
+
def initialize(file_name, stream: false, encrypter: nil, suppress_extra_fields: false, **opts)
|
|
25
|
+
super(**opts)
|
|
26
|
+
@file_name = file_name
|
|
27
|
+
@io = nil
|
|
28
|
+
if stream
|
|
29
|
+
@io = file_name
|
|
30
|
+
@io.binmode if @io.respond_to?(:binmode)
|
|
31
|
+
@writer =
|
|
32
|
+
if IOExtras.seekable?(@io)
|
|
33
|
+
@io.rewind if @io.respond_to?(:rewind)
|
|
34
|
+
Native::Writer.open_io(@io)
|
|
35
|
+
else
|
|
36
|
+
Native::Writer.open_memory
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
@writer = Native::Writer.open_path(file_name.to_s)
|
|
40
|
+
end
|
|
41
|
+
@encrypter = encrypter || ::Ziperu::NullEncrypter.new
|
|
42
|
+
@suppress_extra_fields = suppress_extra_fields
|
|
43
|
+
@comment = ''
|
|
44
|
+
@closed = false
|
|
45
|
+
@current_entry = nil
|
|
46
|
+
@written = []
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class << self
|
|
50
|
+
# Same as #initialize but if a block is passed the opened stream is
|
|
51
|
+
# passed to the block and closed when the block returns.
|
|
52
|
+
def open(file_name, encrypter: nil, suppress_extra_fields: false, **opts)
|
|
53
|
+
unless block_given?
|
|
54
|
+
return new(file_name, encrypter: encrypter,
|
|
55
|
+
suppress_extra_fields: suppress_extra_fields, **opts)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
zos = new(file_name, stream: false, encrypter: encrypter,
|
|
59
|
+
suppress_extra_fields: suppress_extra_fields, **opts)
|
|
60
|
+
yield zos
|
|
61
|
+
ensure
|
|
62
|
+
zos.close if zos
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Same as #open but writes to an IO instead; returns the IO.
|
|
66
|
+
def write_buffer(io = ::StringIO.new, encrypter: nil, suppress_extra_fields: false, **opts)
|
|
67
|
+
zos = new(io, stream: true, encrypter: encrypter,
|
|
68
|
+
suppress_extra_fields: suppress_extra_fields, **opts)
|
|
69
|
+
yield zos
|
|
70
|
+
zos.close_buffer
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Closes the stream and writes the central directory. A stream over an
|
|
75
|
+
# IO (`stream: true`) closes it too, as rubyzip does; `close_buffer` is
|
|
76
|
+
# the variant that leaves it open.
|
|
77
|
+
def close
|
|
78
|
+
return if @closed
|
|
79
|
+
|
|
80
|
+
finish_archive
|
|
81
|
+
@io.close if @io && @io.respond_to?(:close)
|
|
82
|
+
@closed = true
|
|
83
|
+
nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Closes the stream and completes the archive in the IO given to
|
|
87
|
+
# `write_buffer`; returns that IO.
|
|
88
|
+
def close_buffer
|
|
89
|
+
return @io if @closed
|
|
90
|
+
|
|
91
|
+
finish_archive
|
|
92
|
+
@closed = true
|
|
93
|
+
@io
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Closes the current entry and opens a new one for writing. `entry_name`
|
|
97
|
+
# can be a Ziperu::Entry or a string.
|
|
98
|
+
def put_next_entry(
|
|
99
|
+
entry_name, comment = '', extra = ExtraField.new,
|
|
100
|
+
compression_method = Entry::DEFLATED, level = Ziperu.default_compression
|
|
101
|
+
)
|
|
102
|
+
raise Error, 'zip stream is closed' if @closed
|
|
103
|
+
|
|
104
|
+
new_entry =
|
|
105
|
+
if entry_name.kind_of?(Entry) || entry_name.kind_of?(StreamableStream)
|
|
106
|
+
entry_name
|
|
107
|
+
else
|
|
108
|
+
Entry.new(
|
|
109
|
+
@file_name, entry_name.to_s, comment: comment, extra: extra,
|
|
110
|
+
compression_method: compression_method, compression_level: level
|
|
111
|
+
)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
init_next_entry(new_entry)
|
|
115
|
+
@written << new_entry
|
|
116
|
+
@current_entry = new_entry
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Copies an entry from another archive without recompressing it. With
|
|
120
|
+
# `touch: true` the entry's current permissions and mtime are written
|
|
121
|
+
# instead of the source's. The native writer can do that or a rename,
|
|
122
|
+
# not both, and carries nothing else over from the entry object;
|
|
123
|
+
# `Entry#write_to_zip_output_stream` re-streams edited entries instead.
|
|
124
|
+
def copy_raw_entry(entry, new_name = nil, touch: false) # :nodoc:
|
|
125
|
+
raise Error, 'zip stream is closed' if @closed
|
|
126
|
+
raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
|
|
127
|
+
raise Error, "entry '#{entry.name}' is not in an archive" if entry.archive.nil?
|
|
128
|
+
if entry.index.nil?
|
|
129
|
+
raise Error, "entry '#{entry.name}' shares its name with another record and cannot be copied raw"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
touch_opts =
|
|
133
|
+
if touch && new_name.nil?
|
|
134
|
+
time = DOSTime.from_time(entry.time)
|
|
135
|
+
{ dos_date: time.to_binary_dos_date, dos_time: time.to_binary_dos_time,
|
|
136
|
+
unix_perms: entry.unix_perms }
|
|
137
|
+
end
|
|
138
|
+
@writer.raw_copy(entry.archive, entry.index, new_name, touch_opts)
|
|
139
|
+
@written << entry
|
|
140
|
+
@current_entry = nil
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Modeled after IO.<<
|
|
144
|
+
def <<(data)
|
|
145
|
+
raise IOError, 'closed stream' if @closed || @current_entry.nil?
|
|
146
|
+
|
|
147
|
+
@writer.write(data.to_s.b)
|
|
148
|
+
self
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
def finish_archive
|
|
154
|
+
comment = @comment.to_s.b
|
|
155
|
+
raise ArgumentError, "archive comment is #{comment.bytesize} bytes; the limit is 65535" if comment.bytesize > 0xFFFF
|
|
156
|
+
|
|
157
|
+
@writer.comment = comment
|
|
158
|
+
@current_entry = nil
|
|
159
|
+
bytes, stats = @writer.finish
|
|
160
|
+
stats.each_with_index do |(offset, size, compressed_size, crc), i|
|
|
161
|
+
@written[i].written_as(offset, size, compressed_size, crc)
|
|
162
|
+
end
|
|
163
|
+
# A seekable IO already holds the archive; a pipe gets it now.
|
|
164
|
+
return unless bytes && @io
|
|
165
|
+
|
|
166
|
+
@io.write(bytes)
|
|
167
|
+
@io.flush if @io.respond_to?(:flush)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def init_next_entry(entry)
|
|
171
|
+
unless WRITABLE_COMPRESSION_METHODS.include?(entry.compression_method)
|
|
172
|
+
raise ::Ziperu::CompressionMethodError, entry.compression_method
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
opts = native_entry_options(entry)
|
|
176
|
+
if entry.directory?
|
|
177
|
+
@writer.add_directory(entry.name, opts)
|
|
178
|
+
elsif entry.symlink?
|
|
179
|
+
@writer.add_symlink(entry.name, entry.symlink_target, opts)
|
|
180
|
+
else
|
|
181
|
+
opts.merge!(@encrypter.native_options)
|
|
182
|
+
@writer.start_entry(entry.name.b, opts)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Translate a Ziperu::Entry into the Hash the native writer takes.
|
|
187
|
+
def native_entry_options(entry)
|
|
188
|
+
suppress = @suppress_extra_fields
|
|
189
|
+
zip64_suppressed = suppress == true || [*suppress].include?(:zip64)
|
|
190
|
+
extra = entry.extra.dup
|
|
191
|
+
extra.suppress_fields!(suppress) if suppress
|
|
192
|
+
extra.delete(:zip64) # the native writer emits its own
|
|
193
|
+
|
|
194
|
+
level = entry.compression_level
|
|
195
|
+
# An extra field may hand back a plain Time.
|
|
196
|
+
time = DOSTime.from_time(entry.time)
|
|
197
|
+
{
|
|
198
|
+
method: entry.compression_method,
|
|
199
|
+
level: (level if entry.compression_method != Entry::STORED && level &&
|
|
200
|
+
level != Zlib::DEFAULT_COMPRESSION),
|
|
201
|
+
dos_date: time.to_binary_dos_date,
|
|
202
|
+
dos_time: time.to_binary_dos_time,
|
|
203
|
+
unix_perms: entry.unix_perms,
|
|
204
|
+
fstype: entry.fstype,
|
|
205
|
+
large_file: zip64_needed?(entry, zip64_suppressed),
|
|
206
|
+
comment: entry.comment.to_s.b,
|
|
207
|
+
extra: extra.to_local_bin.b,
|
|
208
|
+
central_extra: extra.to_c_dir_bin.b
|
|
209
|
+
}
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# rubyzip writes a zip64 extra for a file entry only when it has to:
|
|
213
|
+
# the size is unknown up front (it may turn out huge) or is already
|
|
214
|
+
# over the 32-bit limit. The native writer does the same with
|
|
215
|
+
# `large_file`.
|
|
216
|
+
def zip64_needed?(entry, suppressed)
|
|
217
|
+
return true if entry.size >= 0xFFFFFFFF || entry.compressed_size >= 0xFFFFFFFF
|
|
218
|
+
return false if suppressed || !Ziperu.write_zip64_support || !entry.file?
|
|
219
|
+
|
|
220
|
+
entry.zip64? || !entry.size_known?
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
|
|
4
|
+
# Not on any ziperu code path: the Rust core compresses and decompresses.
|
|
5
|
+
# Kept so that code which references these classes keeps loading.
|
|
6
|
+
module Ziperu
|
|
7
|
+
class PassThruCompressor < Compressor # :nodoc:all
|
|
8
|
+
def initialize(output_stream, encrypter = NullEncrypter.new)
|
|
9
|
+
super()
|
|
10
|
+
@output_stream = output_stream
|
|
11
|
+
@encrypter = encrypter
|
|
12
|
+
@crc = Zlib.crc32
|
|
13
|
+
@size = 0
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def <<(data)
|
|
17
|
+
val = data.to_s
|
|
18
|
+
@crc = Zlib.crc32(val, @crc)
|
|
19
|
+
@size += val.bytesize
|
|
20
|
+
@output_stream << @encrypter.encrypt(val)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
attr_reader :size, :crc
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
28
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
29
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
|
|
4
|
+
# Not on any ziperu code path: the Rust core compresses and decompresses.
|
|
5
|
+
# Kept so that code which references these classes keeps loading.
|
|
6
|
+
module Ziperu
|
|
7
|
+
class PassThruDecompressor < Decompressor # :nodoc:all
|
|
8
|
+
def initialize(*args)
|
|
9
|
+
super
|
|
10
|
+
@read_so_far = 0
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def read(maxlen = nil)
|
|
14
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
15
|
+
|
|
16
|
+
if maxlen.nil? || (@read_so_far + maxlen) > decompressed_size
|
|
17
|
+
maxlen = decompressed_size - @read_so_far
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@read_so_far += maxlen
|
|
21
|
+
input_stream.read(maxlen)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def eof?
|
|
25
|
+
@read_so_far >= decompressed_size
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Alias for compatibility. Remove for version 4.
|
|
29
|
+
alias eof eof?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
::Ziperu::Decompressor.register(::Ziperu::COMPRESSION_METHOD_STORE, ::Ziperu::PassThruDecompressor)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
36
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
37
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Ported from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
|
|
4
|
+
|
|
5
|
+
module Ziperu
|
|
6
|
+
class StreamableDirectory < Entry # :nodoc:
|
|
7
|
+
def initialize(zipfile, entry, src_path = nil, permission = nil)
|
|
8
|
+
super(zipfile, entry)
|
|
9
|
+
|
|
10
|
+
@ftype = :directory
|
|
11
|
+
get_extra_attributes_from_path(src_path) if src_path
|
|
12
|
+
@unix_perms = permission if permission
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Ported from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
|
|
4
|
+
|
|
5
|
+
module Ziperu
|
|
6
|
+
# An entry whose contents are being written through `get_output_stream`:
|
|
7
|
+
# the data goes to a tempfile until the archive is committed.
|
|
8
|
+
class StreamableStream < DelegateClass(Entry) # :nodoc:all
|
|
9
|
+
def initialize(entry)
|
|
10
|
+
super
|
|
11
|
+
@temp_file = Tempfile.new(::File.basename(name))
|
|
12
|
+
@temp_file.binmode
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get_output_stream
|
|
16
|
+
if block_given?
|
|
17
|
+
begin
|
|
18
|
+
yield(@temp_file)
|
|
19
|
+
ensure
|
|
20
|
+
@temp_file.close
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
@temp_file
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def read_all # :nodoc:
|
|
28
|
+
get_input_stream(&:read)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def get_input_stream
|
|
32
|
+
unless @temp_file.closed?
|
|
33
|
+
raise StandardError, "cannot open entry for reading while its open for writing - #{name}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
@temp_file.open # reopens tempfile from top
|
|
37
|
+
@temp_file.binmode
|
|
38
|
+
if block_given?
|
|
39
|
+
begin
|
|
40
|
+
yield(@temp_file)
|
|
41
|
+
ensure
|
|
42
|
+
@temp_file.close
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
@temp_file
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def write_to_zip_output_stream(output_stream)
|
|
50
|
+
output_stream.put_next_entry(self)
|
|
51
|
+
get_input_stream { |is| ::Ziperu::IOExtras.copy_stream(output_stream, is) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def clean_up
|
|
55
|
+
super
|
|
56
|
+
@temp_file.unlink
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/ziperu.rb
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Same standard-library surface rubyzip loads, since code downstream tends
|
|
4
|
+
# to rely on it being there.
|
|
5
|
+
require 'English'
|
|
6
|
+
require 'delegate'
|
|
7
|
+
require 'digest'
|
|
8
|
+
require 'fileutils'
|
|
9
|
+
require 'forwardable'
|
|
10
|
+
require 'pathname'
|
|
11
|
+
require 'rbconfig'
|
|
12
|
+
require 'singleton'
|
|
13
|
+
require 'stringio'
|
|
14
|
+
require 'tempfile'
|
|
15
|
+
require 'zlib'
|
|
16
|
+
|
|
17
|
+
require_relative "ziperu/version"
|
|
18
|
+
require_relative "ziperu/errors"
|
|
19
|
+
|
|
20
|
+
# Prefer the precompiled, Ruby-version-specific binary shipped in native gems;
|
|
21
|
+
# fall back to the one rake-compiler builds for source installs.
|
|
22
|
+
begin
|
|
23
|
+
require "ziperu/#{RUBY_VERSION[/\d+\.\d+/]}/ziperu"
|
|
24
|
+
rescue LoadError
|
|
25
|
+
require "ziperu/ziperu"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
require_relative "ziperu/constants"
|
|
29
|
+
require_relative "ziperu/dos_time"
|
|
30
|
+
require_relative "ziperu/central_directory"
|
|
31
|
+
require_relative "ziperu/ioextras"
|
|
32
|
+
require_relative "ziperu/dirtyable"
|
|
33
|
+
require_relative "ziperu/extra_field"
|
|
34
|
+
require_relative "ziperu/crypto"
|
|
35
|
+
require_relative "ziperu/null_input_stream"
|
|
36
|
+
require_relative "ziperu/input_stream"
|
|
37
|
+
require_relative "ziperu/output_stream"
|
|
38
|
+
require_relative "ziperu/entry"
|
|
39
|
+
require_relative "ziperu/entry_set"
|
|
40
|
+
require_relative "ziperu/streamable_stream"
|
|
41
|
+
require_relative "ziperu/compressor"
|
|
42
|
+
require_relative "ziperu/decompressor"
|
|
43
|
+
require_relative "ziperu/null_compressor"
|
|
44
|
+
require_relative "ziperu/null_decompressor"
|
|
45
|
+
require_relative "ziperu/pass_thru_compressor"
|
|
46
|
+
require_relative "ziperu/pass_thru_decompressor"
|
|
47
|
+
require_relative "ziperu/inflater"
|
|
48
|
+
require_relative "ziperu/deflater"
|
|
49
|
+
require_relative "ziperu/streamable_directory"
|
|
50
|
+
require_relative "ziperu/file_split"
|
|
51
|
+
require_relative "ziperu/file"
|
|
52
|
+
|
|
53
|
+
# Drop-in replacement for rubyzip, backed by a Rust core.
|
|
54
|
+
#
|
|
55
|
+
# The main entry points are File, InputStream and OutputStream. Global
|
|
56
|
+
# behaviour is configured with Ziperu.setup, exactly as in rubyzip:
|
|
57
|
+
#
|
|
58
|
+
# Ziperu.setup do |c|
|
|
59
|
+
# c.on_exists_proc = true
|
|
60
|
+
# c.unicode_names = true
|
|
61
|
+
# end
|
|
62
|
+
module Ziperu
|
|
63
|
+
# Used by the ported Deflater only; kept because rubyzip exposes it.
|
|
64
|
+
ZLIB_FLUSHING_STRATEGY = defined?(JRUBY_VERSION) ? Zlib::SYNC_FLUSH : Zlib::NO_FLUSH
|
|
65
|
+
|
|
66
|
+
extend self
|
|
67
|
+
|
|
68
|
+
attr_accessor :unicode_names,
|
|
69
|
+
:on_exists_proc,
|
|
70
|
+
:continue_on_exists_proc,
|
|
71
|
+
:sort_entries,
|
|
72
|
+
:default_compression,
|
|
73
|
+
:write_zip64_support,
|
|
74
|
+
:warn_invalid_date,
|
|
75
|
+
:case_insensitive_match,
|
|
76
|
+
:force_entry_names_encoding,
|
|
77
|
+
:validate_entry_sizes,
|
|
78
|
+
:validate_declared_number_of_entries,
|
|
79
|
+
:max_entries,
|
|
80
|
+
:max_total_size
|
|
81
|
+
|
|
82
|
+
DEFAULT_RESTORE_OPTIONS = {
|
|
83
|
+
restore_ownership: false,
|
|
84
|
+
restore_permissions: true,
|
|
85
|
+
restore_times: true
|
|
86
|
+
}.freeze # :nodoc:
|
|
87
|
+
|
|
88
|
+
def reset! # :nodoc:
|
|
89
|
+
@_ran_once = false
|
|
90
|
+
@unicode_names = false
|
|
91
|
+
@on_exists_proc = false
|
|
92
|
+
@continue_on_exists_proc = false
|
|
93
|
+
@sort_entries = false
|
|
94
|
+
@default_compression = Zlib::DEFAULT_COMPRESSION
|
|
95
|
+
@write_zip64_support = true
|
|
96
|
+
@warn_invalid_date = true
|
|
97
|
+
@case_insensitive_match = false
|
|
98
|
+
@force_entry_names_encoding = nil
|
|
99
|
+
@validate_entry_sizes = true
|
|
100
|
+
@validate_declared_number_of_entries = false
|
|
101
|
+
# Opening an archive with more entries, or more declared uncompressed
|
|
102
|
+
# bytes, than these raises Ziperu::LimitError. Nil means no limit. With
|
|
103
|
+
# `validate_entry_sizes` on, no entry inflates past its declared size,
|
|
104
|
+
# so the total is a real bound on what can be extracted.
|
|
105
|
+
@max_entries = nil
|
|
106
|
+
@max_total_size = nil
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Set options in one block. The block runs only the first time.
|
|
110
|
+
def setup
|
|
111
|
+
yield self unless @_ran_once
|
|
112
|
+
@_ran_once = true
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
reset!
|
|
116
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ziperu
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: aarch64-linux
|
|
6
|
+
authors:
|
|
7
|
+
- Maor Caplan
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-11-09 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Zip reading and writing for Ruby with rubyzip's API under the Ziperu
|
|
14
|
+
namespace, implemented on the Rust `zip` crate via Magnus. `require "zip"` aliases
|
|
15
|
+
Zip = Ziperu so rubyzip code runs unchanged. Precompiled binaries, no C toolchain
|
|
16
|
+
needed.
|
|
17
|
+
email:
|
|
18
|
+
- caplanmaor@gmail.com
|
|
19
|
+
executables: []
|
|
20
|
+
extensions: []
|
|
21
|
+
extra_rdoc_files: []
|
|
22
|
+
files:
|
|
23
|
+
- CHANGELOG.md
|
|
24
|
+
- LICENSE-rubyzip.txt
|
|
25
|
+
- LICENSE.txt
|
|
26
|
+
- README.md
|
|
27
|
+
- lib/rubyzip.rb
|
|
28
|
+
- lib/zip.rb
|
|
29
|
+
- lib/zip/central_directory.rb
|
|
30
|
+
- lib/zip/compressor.rb
|
|
31
|
+
- lib/zip/constants.rb
|
|
32
|
+
- lib/zip/crypto.rb
|
|
33
|
+
- lib/zip/crypto/aes_encryption.rb
|
|
34
|
+
- lib/zip/crypto/decrypted_io.rb
|
|
35
|
+
- lib/zip/crypto/encryption.rb
|
|
36
|
+
- lib/zip/crypto/null_encryption.rb
|
|
37
|
+
- lib/zip/crypto/traditional_encryption.rb
|
|
38
|
+
- lib/zip/decompressor.rb
|
|
39
|
+
- lib/zip/deflater.rb
|
|
40
|
+
- lib/zip/dirtyable.rb
|
|
41
|
+
- lib/zip/dos_time.rb
|
|
42
|
+
- lib/zip/entry.rb
|
|
43
|
+
- lib/zip/entry_set.rb
|
|
44
|
+
- lib/zip/errors.rb
|
|
45
|
+
- lib/zip/extra_field.rb
|
|
46
|
+
- lib/zip/extra_field/aes.rb
|
|
47
|
+
- lib/zip/extra_field/generic.rb
|
|
48
|
+
- lib/zip/extra_field/ntfs.rb
|
|
49
|
+
- lib/zip/extra_field/old_unix.rb
|
|
50
|
+
- lib/zip/extra_field/universal_time.rb
|
|
51
|
+
- lib/zip/extra_field/unix.rb
|
|
52
|
+
- lib/zip/extra_field/unknown.rb
|
|
53
|
+
- lib/zip/extra_field/zip64.rb
|
|
54
|
+
- lib/zip/file.rb
|
|
55
|
+
- lib/zip/file_split.rb
|
|
56
|
+
- lib/zip/filesystem.rb
|
|
57
|
+
- lib/zip/filesystem/dir.rb
|
|
58
|
+
- lib/zip/filesystem/directory_iterator.rb
|
|
59
|
+
- lib/zip/filesystem/file.rb
|
|
60
|
+
- lib/zip/filesystem/file_stat.rb
|
|
61
|
+
- lib/zip/filesystem/zip_file_name_mapper.rb
|
|
62
|
+
- lib/zip/inflater.rb
|
|
63
|
+
- lib/zip/input_stream.rb
|
|
64
|
+
- lib/zip/ioextras.rb
|
|
65
|
+
- lib/zip/ioextras/abstract_input_stream.rb
|
|
66
|
+
- lib/zip/ioextras/abstract_output_stream.rb
|
|
67
|
+
- lib/zip/ioextras/fake_io.rb
|
|
68
|
+
- lib/zip/null_compressor.rb
|
|
69
|
+
- lib/zip/null_decompressor.rb
|
|
70
|
+
- lib/zip/null_input_stream.rb
|
|
71
|
+
- lib/zip/output_stream.rb
|
|
72
|
+
- lib/zip/pass_thru_compressor.rb
|
|
73
|
+
- lib/zip/pass_thru_decompressor.rb
|
|
74
|
+
- lib/zip/streamable_directory.rb
|
|
75
|
+
- lib/zip/streamable_stream.rb
|
|
76
|
+
- lib/zip/version.rb
|
|
77
|
+
- lib/ziperu.rb
|
|
78
|
+
- lib/ziperu/3.1/ziperu.so
|
|
79
|
+
- lib/ziperu/3.2/ziperu.so
|
|
80
|
+
- lib/ziperu/3.3/ziperu.so
|
|
81
|
+
- lib/ziperu/3.4/ziperu.so
|
|
82
|
+
- lib/ziperu/4.0/ziperu.so
|
|
83
|
+
- lib/ziperu/central_directory.rb
|
|
84
|
+
- lib/ziperu/compressor.rb
|
|
85
|
+
- lib/ziperu/constants.rb
|
|
86
|
+
- lib/ziperu/crypto.rb
|
|
87
|
+
- lib/ziperu/decompressor.rb
|
|
88
|
+
- lib/ziperu/deflater.rb
|
|
89
|
+
- lib/ziperu/dirtyable.rb
|
|
90
|
+
- lib/ziperu/dos_time.rb
|
|
91
|
+
- lib/ziperu/entry.rb
|
|
92
|
+
- lib/ziperu/entry_set.rb
|
|
93
|
+
- lib/ziperu/errors.rb
|
|
94
|
+
- lib/ziperu/extra_field.rb
|
|
95
|
+
- lib/ziperu/extra_field/aes.rb
|
|
96
|
+
- lib/ziperu/extra_field/generic.rb
|
|
97
|
+
- lib/ziperu/extra_field/ntfs.rb
|
|
98
|
+
- lib/ziperu/extra_field/old_unix.rb
|
|
99
|
+
- lib/ziperu/extra_field/universal_time.rb
|
|
100
|
+
- lib/ziperu/extra_field/unix.rb
|
|
101
|
+
- lib/ziperu/extra_field/unknown.rb
|
|
102
|
+
- lib/ziperu/extra_field/zip64.rb
|
|
103
|
+
- lib/ziperu/file.rb
|
|
104
|
+
- lib/ziperu/file_split.rb
|
|
105
|
+
- lib/ziperu/filesystem.rb
|
|
106
|
+
- lib/ziperu/filesystem/dir.rb
|
|
107
|
+
- lib/ziperu/filesystem/directory_iterator.rb
|
|
108
|
+
- lib/ziperu/filesystem/file.rb
|
|
109
|
+
- lib/ziperu/filesystem/file_stat.rb
|
|
110
|
+
- lib/ziperu/filesystem/zip_file_name_mapper.rb
|
|
111
|
+
- lib/ziperu/inflater.rb
|
|
112
|
+
- lib/ziperu/input_stream.rb
|
|
113
|
+
- lib/ziperu/ioextras.rb
|
|
114
|
+
- lib/ziperu/ioextras/abstract_input_stream.rb
|
|
115
|
+
- lib/ziperu/ioextras/abstract_output_stream.rb
|
|
116
|
+
- lib/ziperu/ioextras/fake_io.rb
|
|
117
|
+
- lib/ziperu/null_compressor.rb
|
|
118
|
+
- lib/ziperu/null_decompressor.rb
|
|
119
|
+
- lib/ziperu/null_input_stream.rb
|
|
120
|
+
- lib/ziperu/output_stream.rb
|
|
121
|
+
- lib/ziperu/pass_thru_compressor.rb
|
|
122
|
+
- lib/ziperu/pass_thru_decompressor.rb
|
|
123
|
+
- lib/ziperu/streamable_directory.rb
|
|
124
|
+
- lib/ziperu/streamable_stream.rb
|
|
125
|
+
- lib/ziperu/version.rb
|
|
126
|
+
homepage: https://github.com/caplanmaor/ziperu
|
|
127
|
+
licenses:
|
|
128
|
+
- MIT
|
|
129
|
+
metadata:
|
|
130
|
+
homepage_uri: https://github.com/caplanmaor/ziperu
|
|
131
|
+
source_code_uri: https://github.com/caplanmaor/ziperu
|
|
132
|
+
changelog_uri: https://github.com/caplanmaor/ziperu/blob/main/CHANGELOG.md
|
|
133
|
+
rubygems_mfa_required: 'true'
|
|
134
|
+
post_install_message:
|
|
135
|
+
rdoc_options: []
|
|
136
|
+
require_paths:
|
|
137
|
+
- lib
|
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
|
+
requirements:
|
|
140
|
+
- - ">="
|
|
141
|
+
- !ruby/object:Gem::Version
|
|
142
|
+
version: '3.1'
|
|
143
|
+
- - "<"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: 4.1.dev
|
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - ">="
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '0'
|
|
151
|
+
requirements: []
|
|
152
|
+
rubygems_version: 3.5.23
|
|
153
|
+
signing_key:
|
|
154
|
+
specification_version: 4
|
|
155
|
+
summary: A drop-in rubyzip replacement backed by Rust.
|
|
156
|
+
test_files: []
|