minitar 0.7 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|