minitar 1.0.2 → 1.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +285 -0
- data/CONTRIBUTING.md +273 -0
- data/CONTRIBUTORS.md +27 -0
- data/LICENCE.md +39 -0
- data/Manifest.txt +29 -6
- data/README.md +70 -0
- data/Rakefile +74 -19
- data/SECURITY.md +64 -0
- data/docs/ruby.txt +3 -3
- data/lib/minitar/input.rb +69 -56
- data/lib/minitar/output.rb +34 -22
- data/lib/minitar/pax_header.rb +111 -0
- data/lib/minitar/posix_header.rb +96 -57
- data/lib/minitar/reader.rb +65 -70
- data/lib/minitar/version.rb +5 -0
- data/lib/minitar/writer.rb +50 -88
- data/lib/minitar.rb +60 -64
- data/licenses/bsdl.txt +20 -0
- data/licenses/dco.txt +34 -0
- data/licenses/ruby.txt +52 -0
- data/test/fixtures/issue_46.tar.gz +0 -0
- data/test/fixtures/issue_62.tar.gz +0 -0
- data/test/fixtures/tar_input.tgz +0 -0
- data/test/fixtures/test_input_non_strict_octal.tgz +0 -0
- data/test/fixtures/test_input_relative.tgz +0 -0
- data/test/fixtures/test_input_space_octal.tgz +0 -0
- data/test/fixtures/test_minitar.tar.gz +0 -0
- data/test/minitest_helper.rb +12 -1
- data/test/support/minitar_test_helpers/fixtures.rb +38 -0
- data/test/support/minitar_test_helpers/header.rb +130 -0
- data/test/support/minitar_test_helpers/tarball.rb +324 -0
- data/test/support/minitar_test_helpers.rb +36 -0
- data/test/test_filename_boundary_conditions.rb +74 -0
- data/test/test_gnu_tar_compatibility.rb +92 -0
- data/test/test_integration_pack_unpack_cycle.rb +38 -0
- data/test/test_issue_46.rb +5 -23
- data/test/test_issue_62.rb +50 -0
- data/test/test_minitar.rb +168 -39
- data/test/test_pax_header.rb +104 -0
- data/test/test_pax_support.rb +66 -0
- data/test/test_tar_header.rb +289 -75
- data/test/test_tar_input.rb +14 -61
- data/test/test_tar_output.rb +7 -9
- data/test/test_tar_reader.rb +17 -18
- data/test/test_tar_writer.rb +105 -126
- metadata +95 -89
- data/Contributing.md +0 -94
- data/History.md +0 -236
- data/Licence.md +0 -15
- data/README.rdoc +0 -92
- data/test/support/tar_test_helpers.rb +0 -134
- /data/{Code-of-Conduct.md → CODE_OF_CONDUCT.md} +0 -0
data/README.rdoc
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
= minitar
|
2
|
-
|
3
|
-
home :: https://github.com/halostatue/minitar/
|
4
|
-
code :: https://github.com/halostatue/minitar/
|
5
|
-
bugs :: https://github.com/halostatue/minitar/issues
|
6
|
-
rdoc :: https://rdoc.info/gems/minitar/
|
7
|
-
cli :: https://github.com/halostatue/minitar-cli
|
8
|
-
|
9
|
-
== Description
|
10
|
-
|
11
|
-
The minitar library is a pure-Ruby library that provides the ability to deal
|
12
|
-
with POSIX tar(1) archive files.
|
13
|
-
|
14
|
-
This is release 0.12. This is likely the last revision before 1.0.
|
15
|
-
|
16
|
-
minitar (previously called Archive::Tar::Minitar) is based heavily on code
|
17
|
-
originally written by Mauricio Julio Fernández Pradier for the rpa-base
|
18
|
-
project.
|
19
|
-
|
20
|
-
== Synopsis
|
21
|
-
|
22
|
-
Using minitar is easy. The simplest case is:
|
23
|
-
|
24
|
-
require 'minitar'
|
25
|
-
|
26
|
-
# Packs everything that matches Find.find('tests').
|
27
|
-
# test.tar will automatically be closed by Minitar.pack.
|
28
|
-
Minitar.pack('tests', File.open('test.tar', 'wb'))
|
29
|
-
|
30
|
-
# Unpacks 'test.tar' to 'x', creating 'x' if necessary.
|
31
|
-
Minitar.unpack('test.tar', 'x')
|
32
|
-
|
33
|
-
A gzipped tar can be written with:
|
34
|
-
|
35
|
-
require 'zlib'
|
36
|
-
# test.tgz will be closed automatically.
|
37
|
-
Minitar.pack('tests', Zlib::GzipWriter.new(File.open('test.tgz', 'wb'))
|
38
|
-
|
39
|
-
# test.tgz will be closed automatically.
|
40
|
-
Minitar.unpack(Zlib::GzipReader.new(File.open('test.tgz', 'rb')), 'x')
|
41
|
-
|
42
|
-
As the case above shows, one need not write to a file. However, it will
|
43
|
-
sometimes require that one dive a little deeper into the API, as in the case of
|
44
|
-
StringIO objects. Note that I'm not providing a block with Minitar::Output, as
|
45
|
-
Minitar::Output#close automatically closes both the Output object and the
|
46
|
-
wrapped data stream object.
|
47
|
-
|
48
|
-
begin
|
49
|
-
sgz = Zlib::GzipWriter.new(StringIO.new(String.new))
|
50
|
-
tar = Output.new(sgz)
|
51
|
-
Find.find('tests') do |entry|
|
52
|
-
Minitar.pack_file(entry, tar)
|
53
|
-
end
|
54
|
-
ensure
|
55
|
-
# Closes both tar and sgz.
|
56
|
-
tar.close
|
57
|
-
end
|
58
|
-
|
59
|
-
== Minitar and Security
|
60
|
-
|
61
|
-
Minitar aims to be secure by default for the data *inside* of a tarfile. If
|
62
|
-
there are any security issues discovered, please feel free to open an issue.
|
63
|
-
Should you wish to make a more confidential report, you can find my PGP key
|
64
|
-
information at {Keybase}[https://keybase.io/halostatue]. Bear with me: I do not
|
65
|
-
use PGP regularly, so it may take some time to remember the command invocations
|
66
|
-
required to successfully handle this.
|
67
|
-
|
68
|
-
Minitar does *not* perform validation of path names provided to the convenience
|
69
|
-
calsses Minitar::Output and Minitar::Input, which use Kernel.open for their
|
70
|
-
underlying implementations when not given an IO-like object.
|
71
|
-
|
72
|
-
Improper use of these classes with arbitrary input filenames may leave your
|
73
|
-
your software to the same class of vulnerability as reported for Net::FTP
|
74
|
-
({CVE-2017-17405}[https://nvd.nist.gov/vuln/detail/CVE-2017-17405]). Of
|
75
|
-
particular note, "if the localfile argument starts with the '|' pipe character,
|
76
|
-
the command following the pipe character is executed."
|
77
|
-
|
78
|
-
Additionally, the use of the `open-uri` library (which extends Kernel.open with
|
79
|
-
transparent implementations of Net::HTTP, Net::HTTPS, and Net::FTP), there are
|
80
|
-
other possible vulnerabilities when accepting arbitrary input, as
|
81
|
-
{detailed}[https://sakurity.com/blog/2015/02/28/openuri.html] by Egor Homakov.
|
82
|
-
|
83
|
-
These security vulnerabilities may be avoided, even with the Minitar::Output
|
84
|
-
and Minitar::Input convenience classes, by providing IO-like objects instead of
|
85
|
-
pathname-like objects as the source or destination of these classes.
|
86
|
-
|
87
|
-
== minitar Semantic Versioning
|
88
|
-
|
89
|
-
The minitar library uses a {Semantic Versioning}[http://semver.org/] scheme
|
90
|
-
with one change:
|
91
|
-
|
92
|
-
* When PATCH is zero (+0+), it will be omitted from version references.
|
@@ -1,134 +0,0 @@
|
|
1
|
-
module TarTestHelpers
|
2
|
-
Field = Struct.new(:name, :offset, :length)
|
3
|
-
def self.Field(name, length)
|
4
|
-
# standard:disable ThreadSafety/InstanceVariableInClassMethod
|
5
|
-
@offset ||= 0
|
6
|
-
field = Field.new(name, @offset, length)
|
7
|
-
@offset += length
|
8
|
-
# standard:enable ThreadSafety/InstanceVariableInClassMethod
|
9
|
-
|
10
|
-
FIELDS[name] = field
|
11
|
-
FIELD_ORDER << name
|
12
|
-
field
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
FIELDS = {}
|
18
|
-
FIELD_ORDER = []
|
19
|
-
|
20
|
-
Field("name", 100)
|
21
|
-
Field("mode", 8)
|
22
|
-
Field("uid", 8)
|
23
|
-
Field("gid", 8)
|
24
|
-
Field("size", 12)
|
25
|
-
Field("mtime", 12)
|
26
|
-
Field("checksum", 8)
|
27
|
-
Field("typeflag", 1)
|
28
|
-
Field("linkname", 100)
|
29
|
-
Field("magic", 6)
|
30
|
-
Field("version", 2)
|
31
|
-
Field("uname", 32)
|
32
|
-
Field("gname", 32)
|
33
|
-
Field("devmajor", 8)
|
34
|
-
Field("devminor", 8)
|
35
|
-
Field("prefix", 155)
|
36
|
-
|
37
|
-
BLANK_CHECKSUM = " " * 8
|
38
|
-
NULL_100 = "\0" * 100
|
39
|
-
USTAR = "ustar\0"
|
40
|
-
DOUBLE_ZERO = "00"
|
41
|
-
|
42
|
-
def assert_headers_equal(expected, actual)
|
43
|
-
FIELD_ORDER.each do |field|
|
44
|
-
message = if field == "checksum"
|
45
|
-
"Header checksums are expected to match."
|
46
|
-
else
|
47
|
-
"Header field #{field} is expected to match."
|
48
|
-
end
|
49
|
-
|
50
|
-
offset = FIELDS[field].offset
|
51
|
-
length = FIELDS[field].length
|
52
|
-
|
53
|
-
assert_equal expected[offset, length], actual[offset, length], message
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def assert_modes_equal(expected, actual, name)
|
58
|
-
return if Minitar.windows?
|
59
|
-
|
60
|
-
assert_equal(
|
61
|
-
mode_string(expected),
|
62
|
-
mode_string(actual),
|
63
|
-
"Mode for #{name} does not match"
|
64
|
-
)
|
65
|
-
end
|
66
|
-
|
67
|
-
def tar_file_header(fname, dname, mode, length)
|
68
|
-
update_checksum(header("0", fname, dname, length, mode))
|
69
|
-
end
|
70
|
-
|
71
|
-
def tar_dir_header(name, prefix, mode)
|
72
|
-
update_checksum(header("5", name, prefix, 0, mode))
|
73
|
-
end
|
74
|
-
|
75
|
-
def tar_symlink_header(name, prefix, mode, target)
|
76
|
-
update_checksum(header("2", name, prefix, 0, mode, target))
|
77
|
-
end
|
78
|
-
|
79
|
-
def header(type, fname, dname, length, mode, link_name = "")
|
80
|
-
raw_header(type,
|
81
|
-
asciiz(fname, 100),
|
82
|
-
asciiz(dname, 155),
|
83
|
-
z(to_oct(length, 11)),
|
84
|
-
z(to_oct(mode, 7)),
|
85
|
-
asciiz(link_name, 100))
|
86
|
-
end
|
87
|
-
|
88
|
-
def raw_header(type, fname, dname, length, mode, link_name = "")
|
89
|
-
arr = [
|
90
|
-
fname, mode, z(to_oct(nil, 7)), z(to_oct(nil, 7)),
|
91
|
-
length, z(to_oct(0, 11)), BLANK_CHECKSUM, type,
|
92
|
-
asciiz(link_name, 100), USTAR, DOUBLE_ZERO, asciiz("", 32), asciiz("", 32),
|
93
|
-
z(to_oct(nil, 7)), z(to_oct(nil, 7)), dname
|
94
|
-
]
|
95
|
-
|
96
|
-
h = arr.join.bytes.to_a.pack("C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155")
|
97
|
-
ret = h + "\0" * (512 - h.bytesize)
|
98
|
-
assert_equal 512, ret.bytesize
|
99
|
-
ret
|
100
|
-
end
|
101
|
-
|
102
|
-
def update_checksum(header)
|
103
|
-
header[FIELDS["checksum"].offset, FIELDS["checksum"].length] =
|
104
|
-
# inject(:+) was introduced in which version?
|
105
|
-
sp(z(to_oct(header.unpack("C*").inject { |a, e| a + e }, 6)))
|
106
|
-
header
|
107
|
-
end
|
108
|
-
|
109
|
-
def to_oct(n, pad_size)
|
110
|
-
if n.nil?
|
111
|
-
"\0" * pad_size
|
112
|
-
else
|
113
|
-
"%0#{pad_size}o" % n
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def asciiz(str, length)
|
118
|
-
str + "\0" * (length - str.bytesize)
|
119
|
-
end
|
120
|
-
|
121
|
-
def sp(s)
|
122
|
-
s + " "
|
123
|
-
end
|
124
|
-
|
125
|
-
def z(s)
|
126
|
-
s + "\0"
|
127
|
-
end
|
128
|
-
|
129
|
-
def mode_string(value)
|
130
|
-
"%04o" % (value & 0o777)
|
131
|
-
end
|
132
|
-
|
133
|
-
Minitest::Test.send(:include, self)
|
134
|
-
end
|
File without changes
|