minitar 0.7 → 0.8
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 +4 -4
- data/Contributing.md +2 -0
- data/History.md +18 -0
- data/lib/archive/tar/minitar.rb +17 -2
- data/lib/archive/tar/minitar/posix_header.rb +4 -2
- data/lib/archive/tar/minitar/reader.rb +19 -4
- data/lib/archive/tar/minitar/writer.rb +16 -10
- data/lib/minitar.rb +1 -1
- data/test/support/tar_test_helpers.rb +19 -7
- data/test/test_tar_header.rb +24 -0
- data/test/test_tar_input.rb +43 -0
- data/test/test_tar_reader.rb +18 -15
- data/test/test_tar_writer.rb +30 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1440e1c57cdd811497e6717a6f81791816bfb2ec5dce0981d9208c41bcd6f09d
|
4
|
+
data.tar.gz: e36cf70bd9acc32d73c95a48c1e67f494853f47603032cac05a84bd366417655
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b615673d6e6626606e6e858d453af056870f4b8c88dade5641595b35733491e6dfe2ec32e90d28f7585308a4229f2ace63b47224c0b2877b44c5b028ee3c1031
|
7
|
+
data.tar.gz: ea2adda3fdcf9314c325cfa69f7ae5bbf6bc02732c8b131acef7406c45c4c53906a5612940fdc6d026d2fcda809b3a095abbe90bcf96a19f4082a653dcf8cbc3
|
data/Contributing.md
CHANGED
@@ -82,6 +82,8 @@ Thanks to everyone who has contributed to minitar:
|
|
82
82
|
* Kazuyoshi Kato
|
83
83
|
* dearblue
|
84
84
|
* Kevin McDermott
|
85
|
+
* inkstak
|
86
|
+
* Akinori MUSHA (knu)
|
85
87
|
|
86
88
|
[Minitest]: https://github.com/seattlerb/minitest
|
87
89
|
[quality commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
data/History.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.8 / 2019-01-05
|
2
|
+
|
3
|
+
* inkstak resolved an issue introduced in the fix for [#31][] by allowing
|
4
|
+
spaces to be considered valid characters in strict octal handling. Octal
|
5
|
+
conversion ignores leading spaces. Merged from a slightly modified version
|
6
|
+
of PR [#35][].
|
7
|
+
|
8
|
+
* dearblue contributed PR [#32][] providing an explicit call to #bytesize for
|
9
|
+
strings that include multibyte characters. The PR has been modified to be
|
10
|
+
compatible with older versions of Ruby and extend tests.
|
11
|
+
|
12
|
+
* Akinori MUSHA (knu) contributed PR [#36][] that treats certain badly
|
13
|
+
encoded regular files (with names ending in `/`) as if they were
|
14
|
+
directories on decode.
|
15
|
+
|
1
16
|
## 0.7 / 2018-02-19
|
2
17
|
|
3
18
|
* Fixed issue [#28][] with a modified version of PR [#29][] covering the
|
@@ -142,4 +157,7 @@
|
|
142
157
|
[#28]: https://github.com/halostatue/minitar/issues/28
|
143
158
|
[#29]: https://github.com/halostatue/minitar/issues/29
|
144
159
|
[#30]: https://github.com/halostatue/minitar/issues/30
|
160
|
+
[#32]: https://github.com/halostatue/minitar/issues/32
|
145
161
|
[#33]: https://github.com/halostatue/minitar/issues/33
|
162
|
+
[#35]: https://github.com/halostatue/minitar/issues/35
|
163
|
+
[#36]: https://github.com/halostatue/minitar/issues/36
|
data/lib/archive/tar/minitar.rb
CHANGED
@@ -73,7 +73,7 @@ end
|
|
73
73
|
# tar.close
|
74
74
|
# end
|
75
75
|
module Archive::Tar::Minitar
|
76
|
-
VERSION = '0.
|
76
|
+
VERSION = '0.8'.freeze # :nodoc:
|
77
77
|
|
78
78
|
# The base class for any minitar error.
|
79
79
|
Error = Class.new(::StandardError)
|
@@ -279,7 +279,7 @@ module Archive::Tar::Minitar
|
|
279
279
|
|
280
280
|
def included(mod)
|
281
281
|
return if modules.include?(mod)
|
282
|
-
warn "Including #{self} has been deprecated."
|
282
|
+
warn "Including #{self} has been deprecated (Minitar will become a class)."
|
283
283
|
modules << mod
|
284
284
|
end
|
285
285
|
|
@@ -288,6 +288,21 @@ module Archive::Tar::Minitar
|
|
288
288
|
@modules ||= Set.new
|
289
289
|
end
|
290
290
|
end
|
291
|
+
|
292
|
+
# This exists to make bytesize implementations work across Ruby versions.
|
293
|
+
module ByteSize # :nodoc:
|
294
|
+
private
|
295
|
+
|
296
|
+
if ''.respond_to?(:bytesize)
|
297
|
+
def bytesize(item)
|
298
|
+
item.bytesize
|
299
|
+
end
|
300
|
+
else
|
301
|
+
def bytesize(item)
|
302
|
+
item.size
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
291
306
|
end
|
292
307
|
|
293
308
|
require 'archive/tar/minitar/posix_header'
|
@@ -123,7 +123,7 @@ class Archive::Tar::Minitar::PosixHeader
|
|
123
123
|
private
|
124
124
|
|
125
125
|
def strict_oct(string)
|
126
|
-
return string.oct if string =~ /\A[0-7]*\z/
|
126
|
+
return string.oct if string =~ /\A[0-7 ]*\z/
|
127
127
|
raise ArgumentError, "#{string.inspect} is not a valid octal string"
|
128
128
|
end
|
129
129
|
end
|
@@ -179,6 +179,8 @@ class Archive::Tar::Minitar::PosixHeader
|
|
179
179
|
|
180
180
|
private
|
181
181
|
|
182
|
+
include Archive::Tar::Minitar::ByteSize
|
183
|
+
|
182
184
|
def oct(num, len)
|
183
185
|
if num.nil?
|
184
186
|
"\0" * (len + 1)
|
@@ -196,7 +198,7 @@ class Archive::Tar::Minitar::PosixHeader
|
|
196
198
|
oct(mtime, 11), chksum, ' ', typeflag, linkname, magic, version,
|
197
199
|
uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix]
|
198
200
|
str = arr.pack(HEADER_PACK_FORMAT)
|
199
|
-
str + "\0" * ((BLOCK_SIZE - str
|
201
|
+
str + "\0" * ((BLOCK_SIZE - bytesize(str)) % BLOCK_SIZE)
|
200
202
|
end
|
201
203
|
|
202
204
|
##
|
@@ -6,6 +6,8 @@ module Archive::Tar::Minitar
|
|
6
6
|
# with random access data streams.
|
7
7
|
class Reader
|
8
8
|
include Enumerable
|
9
|
+
include Archive::Tar::Minitar::ByteSize
|
10
|
+
|
9
11
|
# This marks the EntryStream closed for reading without closing the
|
10
12
|
# actual data stream.
|
11
13
|
module InvalidEntryStream
|
@@ -21,6 +23,8 @@ module Archive::Tar::Minitar
|
|
21
23
|
|
22
24
|
# EntryStreams are pseudo-streams on top of the main data stream.
|
23
25
|
class EntryStream
|
26
|
+
include Archive::Tar::Minitar::ByteSize
|
27
|
+
|
24
28
|
Archive::Tar::Minitar::PosixHeader::FIELDS.each do |field|
|
25
29
|
attr_reader field.to_sym
|
26
30
|
end
|
@@ -59,7 +63,7 @@ module Archive::Tar::Minitar
|
|
59
63
|
len ||= @size - @read
|
60
64
|
max_read = [len, @size - @read].min
|
61
65
|
ret = @io.read(max_read)
|
62
|
-
@read += ret
|
66
|
+
@read += bytesize(ret)
|
63
67
|
ret
|
64
68
|
end
|
65
69
|
|
@@ -74,13 +78,24 @@ module Archive::Tar::Minitar
|
|
74
78
|
|
75
79
|
# Returns +true+ if the entry represents a directory.
|
76
80
|
def directory?
|
77
|
-
@typeflag
|
81
|
+
case @typeflag
|
82
|
+
when '5'
|
83
|
+
true
|
84
|
+
when '0', "\0"
|
85
|
+
# If the name ends with a slash, treat it as a directory.
|
86
|
+
# This is what other major tar implementations do for
|
87
|
+
# interoperability and compatibility with older tar variants
|
88
|
+
# and some new ones.
|
89
|
+
@name.end_with?('/')
|
90
|
+
else
|
91
|
+
false
|
92
|
+
end
|
78
93
|
end
|
79
94
|
alias directory directory?
|
80
95
|
|
81
96
|
# Returns +true+ if the entry represents a plain file.
|
82
97
|
def file?
|
83
|
-
@typeflag == '0' || @typeflag == "\0"
|
98
|
+
(@typeflag == '0' || @typeflag == "\0") && !@name.end_with?('/')
|
84
99
|
end
|
85
100
|
alias file file?
|
86
101
|
|
@@ -233,7 +248,7 @@ module Archive::Tar::Minitar
|
|
233
248
|
else
|
234
249
|
pending = size - entry.bytes_read
|
235
250
|
while pending > 0
|
236
|
-
bread = @io.read([pending, 4096].min)
|
251
|
+
bread = bytesize(@io.read([pending, 4096].min))
|
237
252
|
raise UnexpectedEOF if @io.eof?
|
238
253
|
pending -= bread
|
239
254
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module Archive::Tar::Minitar
|
4
4
|
# The class that writes a tar format archive to a data stream.
|
5
5
|
class Writer
|
6
|
+
include Archive::Tar::Minitar::ByteSize
|
7
|
+
|
6
8
|
# The exception raised when the user attempts to write more data to a
|
7
9
|
# BoundedWriteStream than has been allocated.
|
8
10
|
WriteBoundaryOverflow = Class.new(StandardError)
|
@@ -23,6 +25,8 @@ module Archive::Tar::Minitar
|
|
23
25
|
|
24
26
|
# A WriteOnlyStream that also has a size limit.
|
25
27
|
class BoundedWriteStream < WriteOnlyStream
|
28
|
+
include Archive::Tar::Minitar::ByteSize
|
29
|
+
|
26
30
|
def self.const_missing(c)
|
27
31
|
case c
|
28
32
|
when :FileOverflow
|
@@ -48,10 +52,11 @@ module Archive::Tar::Minitar
|
|
48
52
|
end
|
49
53
|
|
50
54
|
def write(data)
|
51
|
-
|
55
|
+
size = bytesize(data)
|
56
|
+
raise WriteBoundaryOverflow if (size + @written) > @limit
|
52
57
|
@io.write(data)
|
53
|
-
@written +=
|
54
|
-
|
58
|
+
@written += size
|
59
|
+
size
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
@@ -153,23 +158,24 @@ module Archive::Tar::Minitar
|
|
153
158
|
else
|
154
159
|
raise ArgumentError, 'No data provided' unless data
|
155
160
|
|
156
|
-
|
161
|
+
bytes = bytesize(data)
|
162
|
+
size = bytes if size.nil? || size < bytes
|
157
163
|
end
|
158
164
|
|
159
165
|
header[:size] = size
|
160
166
|
|
161
167
|
write_header(name, header)
|
162
168
|
|
163
|
-
os = BoundedWriteStream.new(@io,
|
169
|
+
os = BoundedWriteStream.new(@io, size)
|
164
170
|
if block_given?
|
165
171
|
yield os
|
166
172
|
else
|
167
173
|
os.write(data)
|
168
174
|
end
|
169
175
|
|
170
|
-
min_padding =
|
176
|
+
min_padding = size - os.written
|
171
177
|
@io.write("\0" * min_padding)
|
172
|
-
remainder = (512 - (
|
178
|
+
remainder = (512 - (size % 512)) % 512
|
173
179
|
@io.write("\0" * remainder)
|
174
180
|
end
|
175
181
|
|
@@ -286,7 +292,7 @@ module Archive::Tar::Minitar
|
|
286
292
|
end
|
287
293
|
|
288
294
|
def split_name(name)
|
289
|
-
if name
|
295
|
+
if bytesize(name) <= 100
|
290
296
|
prefix = ''
|
291
297
|
else
|
292
298
|
parts = name.split(/\//)
|
@@ -296,7 +302,7 @@ module Archive::Tar::Minitar
|
|
296
302
|
|
297
303
|
loop do
|
298
304
|
nxt = parts.pop || ''
|
299
|
-
break if newname
|
305
|
+
break if bytesize(newname) + 1 + bytesize(nxt) >= 100
|
300
306
|
newname = "#{nxt}/#{newname}"
|
301
307
|
end
|
302
308
|
|
@@ -305,7 +311,7 @@ module Archive::Tar::Minitar
|
|
305
311
|
name = newname
|
306
312
|
end
|
307
313
|
|
308
|
-
[ name, prefix, (name
|
314
|
+
[ name, prefix, (bytesize(name) > 100 || bytesize(prefix) > 155) ]
|
309
315
|
end
|
310
316
|
end
|
311
317
|
end
|
data/lib/minitar.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module TarTestHelpers
|
4
|
+
include Archive::Tar::Minitar::ByteSize
|
5
|
+
|
4
6
|
Field = Struct.new(:name, :offset, :length)
|
5
7
|
def self.Field(name, length) # rubocop:disable Style/MethodName
|
6
8
|
@offset ||= 0
|
@@ -72,15 +74,25 @@ module TarTestHelpers
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def header(type, fname, dname, length, mode)
|
77
|
+
raw_header(type,
|
78
|
+
asciiz(fname, 100),
|
79
|
+
asciiz(dname, 155),
|
80
|
+
z(to_oct(length, 11)),
|
81
|
+
z(to_oct(mode, 7))
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def raw_header(type, fname, dname, length, mode)
|
75
86
|
arr = [
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
87
|
+
fname, mode, z(to_oct(nil, 7)), z(to_oct(nil, 7)),
|
88
|
+
length, z(to_oct(0, 11)), BLANK_CHECKSUM, type,
|
89
|
+
NULL_100, USTAR, DOUBLE_ZERO, asciiz('', 32), asciiz('', 32),
|
90
|
+
z(to_oct(nil, 7)), z(to_oct(nil, 7)), dname
|
80
91
|
]
|
92
|
+
|
81
93
|
h = arr.join.bytes.to_a.pack('C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155')
|
82
|
-
ret = h + "\0" * (512 - h
|
83
|
-
assert_equal(512, ret
|
94
|
+
ret = h + "\0" * (512 - bytesize(h))
|
95
|
+
assert_equal(512, bytesize(ret))
|
84
96
|
ret
|
85
97
|
end
|
86
98
|
|
@@ -100,7 +112,7 @@ module TarTestHelpers
|
|
100
112
|
end
|
101
113
|
|
102
114
|
def asciiz(str, length)
|
103
|
-
str + "\0" * (length - str
|
115
|
+
str + "\0" * (length - bytesize(str))
|
104
116
|
end
|
105
117
|
|
106
118
|
def sp(s)
|
data/test/test_tar_header.rb
CHANGED
@@ -80,6 +80,30 @@ class TestTarHeader < Minitest::Test
|
|
80
80
|
assert(h.valid?)
|
81
81
|
end
|
82
82
|
|
83
|
+
def test_from_stream_with_no_strict_octal
|
84
|
+
header = tar_file_header('a' * 100, '', 0o12345, -1213)
|
85
|
+
io = StringIO.new(header)
|
86
|
+
|
87
|
+
assert_raises(ArgumentError) do
|
88
|
+
Archive::Tar::Minitar::PosixHeader.from_stream(io)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_from_stream_with_octal_wrapped_by_spaces
|
93
|
+
header = raw_header(0,
|
94
|
+
asciiz('a' * 100, 100),
|
95
|
+
asciiz('', 155),
|
96
|
+
" 1213\0",
|
97
|
+
z(to_oct(0o12345, 7))
|
98
|
+
)
|
99
|
+
|
100
|
+
header = update_checksum(header)
|
101
|
+
io = StringIO.new(header)
|
102
|
+
header = Archive::Tar::Minitar::PosixHeader.from_stream(io)
|
103
|
+
|
104
|
+
assert_equal(651, header.size)
|
105
|
+
end
|
106
|
+
|
83
107
|
def test_valid_with_invalid_header
|
84
108
|
header = StringIO.new("testing")
|
85
109
|
h = Archive::Tar::Minitar::PosixHeader.from_stream header
|
data/test/test_tar_input.rb
CHANGED
@@ -173,4 +173,47 @@ MDUzVDAwNDY0N2VQMGCgAygtLkksAjolEcjIzMOtDqgsLQ2/J0H+gNOjYBSMglEwyAEA2LchrwAGAAA=
|
|
173
173
|
end
|
174
174
|
end
|
175
175
|
end
|
176
|
+
|
177
|
+
NON_STRICT_OCTAL_TGZ = Base64.decode64(<<-EOS).freeze
|
178
|
+
H4sIAEk55FsAA0tJLEnUK0ks0kuvYqAVMDAwMDMxUQDR5mbmYNrACMjX0zMH
|
179
|
+
AzMDUwUDIG1iZmZoYmCgYGBobGpuxqBgQDMXIYHSYqDvgU5KBDIy83CrAypL
|
180
|
+
S8NjjgEYKMDpIQLkuzkYZmdOC2Fgfnv5PleTgcjxwvXVXbaOZ3fa61/6KzHD
|
181
|
+
pENvy739mUkiKiJnJuyTbzEOuHPxvp+sXmL4E9WlJcc6FkaZh6z8srevpeRc
|
182
|
+
Zrb33fXeS3u1Wk7euf7gVqzT7CjOTMHz7+d795uePVN97P2MV15Xav/du77x
|
183
|
+
q911yx829XPfTf4v1PZndoXVlJ/fPP4fzrKdvL/q7P5VazRbzly/dHj+8/32
|
184
|
+
x/yWrLZnWnQnr+4u/zTTs/tPbT8e/jl/5n9Vm7P7k/4xwr2RsDZv7c+eGgaN
|
185
|
+
AQzKIQnSMnNSjWlsByjfm5pi5n8DGDAyQsv/RiZmxqP5nx4gJCOzWAGIQOlA
|
186
|
+
wVhPgZdroF00CkbBKBgFo2AUjIJRMApGwSgYBaNgFIyCUTAKRsEoGAWjYBSM
|
187
|
+
glEwCkbBKBgFo2AUjIJRMApIAQD0DyzXACgAAA==
|
188
|
+
EOS
|
189
|
+
|
190
|
+
def test_extract_with_non_strict_octal
|
191
|
+
reader = Zlib::GzipReader.new(StringIO.new(NON_STRICT_OCTAL_TGZ))
|
192
|
+
|
193
|
+
assert_raises(ArgumentError) do
|
194
|
+
Minitar.unpack(reader, 'data__')
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
OCTAL_WRAPPED_BY_SPACE_TGZ = Base64.decode64(<<-EOS).freeze
|
199
|
+
H4sIAOQg5FsAA0tJLEnUK0ks0kuvYqAVMDAwMDMxUQDR5mbmYNrACMhXgAJj
|
200
|
+
IyMFA3NzcxMzM0MTAwMFA0NjU3MzBgUDmrkICZQWA30PdFIikJGZh1sdUFla
|
201
|
+
Gh5zDMBAAU4PESDfzcEwO3NaCAPz28v3uZoMRI4Xrq/usnU8u9Ne/9JfiRkm
|
202
|
+
HXpb7u3PTBJRETkzYZ98i3HAnYv3/WT1EsOfqC4tOdaxMMo8ZOWXvX0tJecy
|
203
|
+
s73vrvde2qvVcvLO9Qe3Yp1mR3FmCp5/P9+73/Tsmepj72e88rpS++/e9Y1f
|
204
|
+
7a5b/rCpn/tu8n+htj+zK6ym/Pzm8f9wlu3k/VVn969ao9ly5vqlw/Of77c/
|
205
|
+
5rdktT3Tojt5dXf5p5me3X9q+/Hwz/kz/6vanN2f9I8R7o2EtXlrf/bUMGgM
|
206
|
+
YFAOSZCWmZNqTGM7QPne1BQz/xvAAEb+NzIxMx7N//QAIRmZxQpABEoHCsZ6
|
207
|
+
CrxcA+2iUTAKRsEoGAWjYBSMglEwCkbBKBgFo2AUjIJRMApGwSgYBaNgFIyC
|
208
|
+
UTAKRsEoGAWjYBSMglFACgAAuUHUvwAoAAA=
|
209
|
+
EOS
|
210
|
+
|
211
|
+
def test_extract_octal_wrapped_by_space
|
212
|
+
reader = Zlib::GzipReader.new(StringIO.new(OCTAL_WRAPPED_BY_SPACE_TGZ))
|
213
|
+
header = Archive::Tar::Minitar::PosixHeader.from_stream(reader)
|
214
|
+
assert_equal(210, header.size)
|
215
|
+
|
216
|
+
reader = Zlib::GzipReader.new(StringIO.new(OCTAL_WRAPPED_BY_SPACE_TGZ))
|
217
|
+
Minitar.unpack(reader, 'data__', [])
|
218
|
+
end
|
176
219
|
end
|
data/test/test_tar_reader.rb
CHANGED
@@ -4,6 +4,8 @@ require 'minitar'
|
|
4
4
|
require 'minitest_helper'
|
5
5
|
|
6
6
|
class TestTarReader < Minitest::Test
|
7
|
+
include Archive::Tar::Minitar::ByteSize
|
8
|
+
|
7
9
|
def test_open_no_block
|
8
10
|
str = tar_file_header('lib/foo', '', 0o10644, 10) + "\0" * 512
|
9
11
|
str += tar_file_header('bar', 'baz', 0o644, 0)
|
@@ -21,13 +23,14 @@ class TestTarReader < Minitest::Test
|
|
21
23
|
str = tar_file_header('lib/foo', '', 0o10644, 10) + "\0" * 512
|
22
24
|
str += tar_file_header('bar', 'baz', 0o644, 0)
|
23
25
|
str += tar_dir_header('foo', 'bar', 0o12345)
|
26
|
+
str += tar_file_header('src/', '', 0o755, 0) # "file" with a trailing slash
|
24
27
|
str += "\0" * 1024
|
25
|
-
names = %w(lib/foo bar foo)
|
26
|
-
prefixes = ['', 'baz', 'bar']
|
27
|
-
modes = [0o10644, 0o644, 0o12345]
|
28
|
-
sizes = [10, 0, 0]
|
29
|
-
isdir = [false, false, true]
|
30
|
-
isfile = [true, true, false]
|
28
|
+
names = %w(lib/foo bar foo src/)
|
29
|
+
prefixes = ['', 'baz', 'bar', '']
|
30
|
+
modes = [0o10644, 0o644, 0o12345, 0o755]
|
31
|
+
sizes = [10, 0, 0, 0]
|
32
|
+
isdir = [false, false, true, true]
|
33
|
+
isfile = [true, true, false, false]
|
31
34
|
Minitar::Reader.new(StringIO.new(str)) do |is|
|
32
35
|
i = 0
|
33
36
|
is.each_entry do |entry|
|
@@ -51,15 +54,15 @@ class TestTarReader < Minitest::Test
|
|
51
54
|
|
52
55
|
def test_rewind_entry_works
|
53
56
|
content = ('a'..'z').to_a.join(' ')
|
54
|
-
str = tar_file_header('lib/foo', '', 0o10644, content
|
55
|
-
"\0" * (512 - content
|
57
|
+
str = tar_file_header('lib/foo', '', 0o10644, bytesize(content)) +
|
58
|
+
content + "\0" * (512 - bytesize(content))
|
56
59
|
str << "\0" * 1024
|
57
60
|
Minitar::Reader.new(StringIO.new(str)) do |is|
|
58
61
|
is.each_entry do |entry|
|
59
62
|
3.times do
|
60
63
|
entry.rewind
|
61
64
|
assert_equal(content, entry.read)
|
62
|
-
assert_equal(content
|
65
|
+
assert_equal(bytesize(content), entry.pos)
|
63
66
|
end
|
64
67
|
end
|
65
68
|
end
|
@@ -67,8 +70,8 @@ class TestTarReader < Minitest::Test
|
|
67
70
|
|
68
71
|
def test_rewind_works
|
69
72
|
content = ('a'..'z').to_a.join(' ')
|
70
|
-
str = tar_file_header('lib/foo', '', 0o10644, content
|
71
|
-
"\0" * (512 - content
|
73
|
+
str = tar_file_header('lib/foo', '', 0o10644, bytesize(content)) +
|
74
|
+
content + "\0" * (512 - bytesize(content))
|
72
75
|
str << "\0" * 1024
|
73
76
|
Minitar::Reader.new(StringIO.new(str)) do |is|
|
74
77
|
3.times do
|
@@ -85,12 +88,12 @@ class TestTarReader < Minitest::Test
|
|
85
88
|
|
86
89
|
def test_read_works
|
87
90
|
contents = ('a'..'z').inject('') { |a, e| a << e * 100 }
|
88
|
-
str = tar_file_header('lib/foo', '', 0o10644, contents
|
89
|
-
str += "\0" * (512 - (str
|
91
|
+
str = tar_file_header('lib/foo', '', 0o10644, bytesize(contents)) + contents
|
92
|
+
str += "\0" * (512 - (bytesize(str) % 512))
|
90
93
|
Minitar::Reader.new(StringIO.new(str)) do |is|
|
91
94
|
is.each_entry do |entry|
|
92
95
|
assert_kind_of(Minitar::Reader::EntryStream, entry)
|
93
|
-
data = entry.read(3000) # bigger than contents
|
96
|
+
data = entry.read(3000) # bigger than bytesize(contents)
|
94
97
|
assert_equal(contents, data)
|
95
98
|
assert_equal(true, entry.eof?)
|
96
99
|
end
|
@@ -99,7 +102,7 @@ class TestTarReader < Minitest::Test
|
|
99
102
|
is.each_entry do |entry|
|
100
103
|
assert_kind_of(Minitar::Reader::EntryStream, entry)
|
101
104
|
data = entry.read(100)
|
102
|
-
(entry.size - data
|
105
|
+
(entry.size - bytesize(data)).times { data << entry.getc.chr }
|
103
106
|
assert_equal(contents, data)
|
104
107
|
assert_equal(nil, entry.read(10))
|
105
108
|
assert_equal(true, entry.eof?)
|
data/test/test_tar_writer.rb
CHANGED
@@ -4,11 +4,15 @@ require 'minitar'
|
|
4
4
|
require 'minitest_helper'
|
5
5
|
|
6
6
|
class TestTarWriter < Minitest::Test
|
7
|
+
include Archive::Tar::Minitar::ByteSize
|
8
|
+
|
7
9
|
class DummyIO
|
10
|
+
include Archive::Tar::Minitar::ByteSize
|
11
|
+
|
8
12
|
attr_reader :data
|
9
13
|
|
10
14
|
def initialize
|
11
|
-
|
15
|
+
reset
|
12
16
|
end
|
13
17
|
|
14
18
|
def write(dat)
|
@@ -18,11 +22,14 @@ class TestTarWriter < Minitest::Test
|
|
18
22
|
|
19
23
|
def reset
|
20
24
|
@data = ''
|
25
|
+
@data.force_encoding('ascii-8bit') if @data.respond_to?(:force_encoding)
|
21
26
|
end
|
22
27
|
end
|
23
28
|
|
24
29
|
def setup
|
25
30
|
@data = 'a' * 10
|
31
|
+
@unicode = [0xc3.chr, 0xa5.chr].join * 10
|
32
|
+
@unicode.force_encoding('utf-8') if @unicode.respond_to?(:force_encoding)
|
26
33
|
@dummyos = DummyIO.new
|
27
34
|
@os = Minitar::Writer.new(@dummyos)
|
28
35
|
end
|
@@ -146,12 +153,12 @@ class TestTarWriter < Minitest::Test
|
|
146
153
|
offset = 512 * 2
|
147
154
|
[content1, content2, ''].each do |data|
|
148
155
|
assert_headers_equal(tar_file_header('lib/bar/baz', '', 0o644,
|
149
|
-
data
|
156
|
+
bytesize(data)), dummyos[offset, 512])
|
150
157
|
offset += 512
|
151
158
|
until !data || data == ''
|
152
159
|
chunk = data[0, 512]
|
153
160
|
data[0, 512] = ''
|
154
|
-
assert_equal(chunk + "\0" * (512 - chunk
|
161
|
+
assert_equal(chunk + "\0" * (512 - bytesize(chunk)),
|
155
162
|
dummyos[offset, 512])
|
156
163
|
offset += 512
|
157
164
|
end
|
@@ -186,7 +193,26 @@ class TestTarWriter < Minitest::Test
|
|
186
193
|
f.write @data
|
187
194
|
end
|
188
195
|
@os.flush
|
189
|
-
assert_equal(@data + ("\0" * (512 - @data
|
196
|
+
assert_equal(@data + ("\0" * (512 - bytesize(@data))),
|
197
|
+
@dummyos.data[512, 512])
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_write_unicode_data
|
201
|
+
@dummyos.reset
|
202
|
+
|
203
|
+
if @unicode.respond_to?(:bytesize)
|
204
|
+
assert_equal 10, @unicode.size
|
205
|
+
assert_equal 20, @unicode.bytesize
|
206
|
+
@unicode.force_encoding('ascii-8bit')
|
207
|
+
end
|
208
|
+
|
209
|
+
file = ['lib/foo/b', 0xc3.chr, 0xa5.chr, 'r'].join
|
210
|
+
|
211
|
+
@os.add_file_simple(file, :mode => 0o644, :size => 20) do |f|
|
212
|
+
f.write @unicode
|
213
|
+
end
|
214
|
+
@os.flush
|
215
|
+
assert_equal(@unicode + ("\0" * (512 - bytesize(@unicode))),
|
190
216
|
@dummyos.data[512, 512])
|
191
217
|
end
|
192
218
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.8'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Austin Ziegler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|