arr-pm 0.0.6 → 0.0.11
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.
Potentially problematic release.
This version of arr-pm might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.rubocop.yml +73 -0
- data/Gemfile +3 -1
- data/Guardfile +77 -0
- data/Makefile +0 -19
- data/arr-pm.gemspec +3 -1
- data/cpio.rb +202 -0
- data/lib/arr-pm/file.rb +34 -10
- data/lib/arr-pm/file/header.rb +3 -2
- data/lib/arr-pm/file/lead.rb +1 -1
- data/lib/arr-pm/file/tag.rb +1 -1
- data/lib/arr-pm/namespace.rb +6 -0
- data/lib/arr-pm/v2/architecture.rb +32 -0
- data/lib/arr-pm/v2/error.rb +32 -0
- data/lib/arr-pm/v2/format.rb +16 -0
- data/lib/arr-pm/v2/header.rb +35 -0
- data/lib/arr-pm/v2/header_header.rb +36 -0
- data/lib/arr-pm/v2/lead.rb +121 -0
- data/lib/arr-pm/v2/package.rb +18 -0
- data/lib/arr-pm/v2/tag.rb +295 -0
- data/lib/arr-pm/v2/type.rb +15 -0
- data/spec/arr-pm/v2/header_spec.rb +34 -0
- data/spec/arr-pm/v2/lead_spec.rb +125 -0
- data/spec/fixtures/example-1.0-1.x86_64.rpm +0 -0
- data/spec/fixtures/example.json +55 -0
- metadata +45 -27
- data/header-verify.rb +0 -71
- data/notify-failure.sh +0 -15
- data/printrpm.rb +0 -22
- data/test/all.rb +0 -24
- data/test/docs.rb +0 -42
- data/test/testing.rb +0 -14
@@ -0,0 +1,15 @@
|
|
1
|
+
require "arr-pm/namespace"
|
2
|
+
|
3
|
+
module ArrPM::V2::Type
|
4
|
+
BINARY = 0
|
5
|
+
SOURCE = 1
|
6
|
+
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Is a given rpm type value valid?
|
10
|
+
#
|
11
|
+
# The only valid types are BINARY (0) or SOURCE (1)
|
12
|
+
def valid?(value)
|
13
|
+
return (value == BINARY || value == SOURCE)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "flores/random"
|
4
|
+
|
5
|
+
require "arr-pm/v2/header"
|
6
|
+
require "arr-pm/v2/type"
|
7
|
+
require "arr-pm/v2/architecture"
|
8
|
+
require "json"
|
9
|
+
|
10
|
+
describe ArrPM::V2::Header do
|
11
|
+
context "with a known good rpm" do
|
12
|
+
let(:path) { File.join(File.dirname(__FILE__), "../../fixtures/example-1.0-1.x86_64.rpm") }
|
13
|
+
let(:file) { File.new(path) }
|
14
|
+
|
15
|
+
before do
|
16
|
+
lead = ArrPM::V2::Lead.new
|
17
|
+
lead.load(file)
|
18
|
+
|
19
|
+
# Throw away the signature if we have one
|
20
|
+
described_class.new.load(file) if lead.signature?
|
21
|
+
|
22
|
+
subject.load(file)
|
23
|
+
end
|
24
|
+
|
25
|
+
expectations = JSON.parse(File.read(File.join(File.dirname(__FILE__), "../../fixtures/example.json")))
|
26
|
+
|
27
|
+
expectations.each do |name, expected_value|
|
28
|
+
it "should have expected value for the #{name} tag" do
|
29
|
+
tag = subject.tags.find { |t| t.tag.to_s == name }
|
30
|
+
expect(tag.value).to be == expected_value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "flores/random"
|
4
|
+
|
5
|
+
require "arr-pm/v2/lead"
|
6
|
+
require "arr-pm/v2/type"
|
7
|
+
require "arr-pm/v2/architecture"
|
8
|
+
|
9
|
+
describe ArrPM::V2::Lead do
|
10
|
+
let(:major) { Flores::Random.integer(0..255) }
|
11
|
+
let(:minor) { Flores::Random.integer(0..255) }
|
12
|
+
let(:magic) { described_class::MAGIC }
|
13
|
+
let(:type) { ArrPM::V2::Type::BINARY }
|
14
|
+
let(:architecture) { ArrPM::V2::Architecture::I386 }
|
15
|
+
let(:os) { 0 }
|
16
|
+
let(:os_bytes) { [os].pack("n").unpack("C2") }
|
17
|
+
let(:signature_type) { 0 }
|
18
|
+
let(:signature_type_bytes) { [signature_type].pack("n").unpack("C2") }
|
19
|
+
let(:longname) { "test-1.0-1" }
|
20
|
+
let(:longnamebytes) { longname.bytes + (66-longname.bytesize).times.collect { 0 } }
|
21
|
+
let(:leadbytes) { magic + [major, minor] + [0, type, 0, architecture] + longnamebytes + os_bytes + signature_type_bytes + 16.times.collect { 0 } }
|
22
|
+
let(:lead) { leadbytes.pack("C*") }
|
23
|
+
|
24
|
+
describe ".parse_magic" do
|
25
|
+
context "when given an invalid magic value" do
|
26
|
+
# Generate random bytes for the magic value, should be bad.
|
27
|
+
let(:magic) { Flores::Random.iterations(0..10).collect { Flores::Random.integer(0..255) } }
|
28
|
+
|
29
|
+
it "should fail" do
|
30
|
+
expect { described_class.parse_magic(leadbytes) }.to raise_error(ArrPM::V2::Error::InvalidMagicValue)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when given a valid magic value" do
|
35
|
+
it "should succeed" do
|
36
|
+
expect { described_class.parse_magic(leadbytes) }.not_to raise_error
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".parse_version" do
|
42
|
+
context "when given an invalid version value" do
|
43
|
+
let(:data) { magic + [major, minor] }
|
44
|
+
|
45
|
+
it "should return an array of two values " do
|
46
|
+
expect(described_class.parse_version(leadbytes)).to be == [major, minor]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe ".parse_type" do
|
52
|
+
context "when given an invalid type" do
|
53
|
+
let(:type) { Flores::Random.integer(2..1000) }
|
54
|
+
it "should fail" do
|
55
|
+
expect { described_class.parse_type(leadbytes) }.to raise_error(ArrPM::V2::Error::InvalidType)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
context "with a valid type" do
|
59
|
+
it "should return the type" do
|
60
|
+
expect(described_class.parse_type(leadbytes)).to be == type
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe ".parse_name" do
|
66
|
+
context "with a valid name" do
|
67
|
+
it "should return the name" do
|
68
|
+
expect(described_class.parse_name(leadbytes)).to be == longname
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe ".parse_signature_type" do
|
74
|
+
it "should return the signature type" do
|
75
|
+
expect(described_class.parse_signature_type(leadbytes)).to be == signature_type
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe ".parse_reserved" do
|
80
|
+
it "should return exactly 16 bytes" do
|
81
|
+
expect(described_class.parse_reserved(leadbytes).count).to be == 16
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#parse" do
|
86
|
+
before do
|
87
|
+
subject.parse(lead)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should have a correct parsed values" do
|
91
|
+
expect(subject.name).to be == longname
|
92
|
+
expect(subject.major).to be == major
|
93
|
+
expect(subject.minor).to be == minor
|
94
|
+
expect(subject.type).to be == type
|
95
|
+
expect(subject.architecture).to be == architecture
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#dump" do
|
100
|
+
before do
|
101
|
+
subject.parse(lead)
|
102
|
+
end
|
103
|
+
|
104
|
+
let(:blob) { subject.serialize }
|
105
|
+
|
106
|
+
it "should parse successfully" do
|
107
|
+
subject.parse(blob)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "with a known good rpm" do
|
112
|
+
let(:path) { File.join(File.dirname(__FILE__), "../../fixtures/example-1.0-1.x86_64.rpm") }
|
113
|
+
|
114
|
+
before do
|
115
|
+
subject.load(File.new(path))
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should have expected values" do
|
119
|
+
expect(subject.name).to be == "example-1.0-1"
|
120
|
+
expect(subject.major).to be == 3
|
121
|
+
expect(subject.minor).to be == 0
|
122
|
+
expect(subject.architecture).to be == architecture
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
Binary file
|
@@ -0,0 +1,55 @@
|
|
1
|
+
{
|
2
|
+
"NAME": "example",
|
3
|
+
"VERSION": "1.0",
|
4
|
+
"RELEASE": "1",
|
5
|
+
"SUMMARY": "no description given",
|
6
|
+
"DESCRIPTION": "no description given",
|
7
|
+
"BUILDTIME": [
|
8
|
+
1466326707
|
9
|
+
],
|
10
|
+
"BUILDHOST": "localhost",
|
11
|
+
"SIZE": [
|
12
|
+
0
|
13
|
+
],
|
14
|
+
"VENDOR": "none",
|
15
|
+
"LICENSE": "unknown",
|
16
|
+
"PACKAGER": "<jls@localhost.localdomain>",
|
17
|
+
"GROUP": "default",
|
18
|
+
"URL": "http://example.com/no-uri-given",
|
19
|
+
"OS": "linux",
|
20
|
+
"ARCH": "x86_64",
|
21
|
+
"SOURCERPM": "example-1.0-1.src.rpm",
|
22
|
+
"PROVIDENAME": [
|
23
|
+
"example",
|
24
|
+
"example(x86-64)"
|
25
|
+
],
|
26
|
+
"REQUIREFLAGS": [
|
27
|
+
16777226,
|
28
|
+
16777226
|
29
|
+
],
|
30
|
+
"REQUIRENAME": [
|
31
|
+
"rpmlib(CompressedFileNames)",
|
32
|
+
"rpmlib(PayloadFilesHavePrefix)"
|
33
|
+
],
|
34
|
+
"REQUIREVERSION": [
|
35
|
+
"3.0.4-1",
|
36
|
+
"4.0-1"
|
37
|
+
],
|
38
|
+
"RPMVERSION": "4.13.0-rc1",
|
39
|
+
"PREFIXES": [
|
40
|
+
"/"
|
41
|
+
],
|
42
|
+
"PROVIDEFLAGS": [
|
43
|
+
8,
|
44
|
+
8
|
45
|
+
],
|
46
|
+
"PROVIDEVERSION": [
|
47
|
+
"1.0-1",
|
48
|
+
"1.0-1"
|
49
|
+
],
|
50
|
+
"PAYLOADFORMAT": "cpio",
|
51
|
+
"PAYLOADCOMPRESSOR": "gzip",
|
52
|
+
"PAYLOADFLAGS": "9",
|
53
|
+
"PLATFORM": "x86_64-redhat-linux-gnu",
|
54
|
+
"ENCODING": "utf-8"
|
55
|
+
}
|
metadata
CHANGED
@@ -1,30 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arr-pm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.11
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jordan Sissel
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2021-06-15 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: cabin
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: flores
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">"
|
28
39
|
- !ruby/object:Gem::Version
|
29
40
|
version: '0'
|
30
41
|
description: This library allows to you to read and write rpm packages. Written in
|
@@ -35,14 +46,16 @@ executables: []
|
|
35
46
|
extensions: []
|
36
47
|
extra_rdoc_files: []
|
37
48
|
files:
|
38
|
-
- .batcave/manifest
|
39
|
-
- .gitignore
|
49
|
+
- ".batcave/manifest"
|
50
|
+
- ".gitignore"
|
51
|
+
- ".rubocop.yml"
|
40
52
|
- Gemfile
|
53
|
+
- Guardfile
|
41
54
|
- LICENSE
|
42
55
|
- Makefile
|
43
56
|
- README.md
|
44
57
|
- arr-pm.gemspec
|
45
|
-
-
|
58
|
+
- cpio.rb
|
46
59
|
- lib/arr-pm.rb
|
47
60
|
- lib/arr-pm/conflicts.rb
|
48
61
|
- lib/arr-pm/file.rb
|
@@ -51,36 +64,41 @@ files:
|
|
51
64
|
- lib/arr-pm/file/tag.rb
|
52
65
|
- lib/arr-pm/namespace.rb
|
53
66
|
- lib/arr-pm/requires.rb
|
54
|
-
-
|
55
|
-
-
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
|
67
|
+
- lib/arr-pm/v2/architecture.rb
|
68
|
+
- lib/arr-pm/v2/error.rb
|
69
|
+
- lib/arr-pm/v2/format.rb
|
70
|
+
- lib/arr-pm/v2/header.rb
|
71
|
+
- lib/arr-pm/v2/header_header.rb
|
72
|
+
- lib/arr-pm/v2/lead.rb
|
73
|
+
- lib/arr-pm/v2/package.rb
|
74
|
+
- lib/arr-pm/v2/tag.rb
|
75
|
+
- lib/arr-pm/v2/type.rb
|
76
|
+
- spec/arr-pm/v2/header_spec.rb
|
77
|
+
- spec/arr-pm/v2/lead_spec.rb
|
78
|
+
- spec/fixtures/example-1.0-1.x86_64.rpm
|
79
|
+
- spec/fixtures/example.json
|
80
|
+
homepage:
|
60
81
|
licenses:
|
61
82
|
- Apache 2
|
62
|
-
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
63
85
|
rdoc_options: []
|
64
86
|
require_paths:
|
65
87
|
- lib
|
66
88
|
- lib
|
67
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
-
none: false
|
69
90
|
requirements:
|
70
|
-
- -
|
91
|
+
- - ">="
|
71
92
|
- !ruby/object:Gem::Version
|
72
93
|
version: '0'
|
73
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
95
|
requirements:
|
76
|
-
- -
|
96
|
+
- - ">="
|
77
97
|
- !ruby/object:Gem::Version
|
78
98
|
version: '0'
|
79
99
|
requirements: []
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
specification_version: 3
|
100
|
+
rubygems_version: 3.2.15
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
84
103
|
summary: RPM reader and writer library
|
85
104
|
test_files: []
|
86
|
-
has_rdoc:
|
data/header-verify.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
HEADER_MAGIC = "\x8e\xad\xe8\x01\x00\x00\x00\x00"
|
2
|
-
TAG_ENTRY_SIZE = 16 # tag id, type, offset, count == 16 bytes
|
3
|
-
|
4
|
-
def read_header(io)
|
5
|
-
# RPM 'header' section looks like:
|
6
|
-
#
|
7
|
-
# MAGIC (8 bytes) index_count (4 bytes), data_length (4 bytes )
|
8
|
-
#
|
9
|
-
# * index_count is the number of 'tags' in this header.
|
10
|
-
# * data_length is a blob containing all the values for the tags
|
11
|
-
#
|
12
|
-
# Header has a header of 'magic' + index_count (4 bytes) + data_length (4 bytes)
|
13
|
-
#p "start of header" => io.pos
|
14
|
-
data = io.read(16).unpack("a8NN")
|
15
|
-
|
16
|
-
# TODO(sissel): @index_count is really a count, rename?
|
17
|
-
@magic, @index_count, @data_length = data
|
18
|
-
if @magic != HEADER_MAGIC
|
19
|
-
puts "Magic value in header was wrong. Expected #{HEADER_MAGIC.inspect}, but got #{@magic.inspect}"
|
20
|
-
exit 1
|
21
|
-
end
|
22
|
-
|
23
|
-
@index_size = @index_count * TAG_ENTRY_SIZE
|
24
|
-
tag_data = io.read(@index_size)
|
25
|
-
data = io.read(@data_length)
|
26
|
-
#p "end of header" => io.pos
|
27
|
-
|
28
|
-
(0 ... @index_count).each do |i|
|
29
|
-
offset = i * TAG_ENTRY_SIZE
|
30
|
-
entry_data = tag_data[i * TAG_ENTRY_SIZE, TAG_ENTRY_SIZE]
|
31
|
-
tag, tag_type, offset, count = entry_data.unpack("NNNN")
|
32
|
-
if block_given?
|
33
|
-
yield :tag => tag, :type => tag_type, :offset => offset, :count => count
|
34
|
-
end
|
35
|
-
#entry << data
|
36
|
-
end # each index
|
37
|
-
return 16 + @index_size + @data_length
|
38
|
-
end
|
39
|
-
|
40
|
-
if ARGV.length != 1
|
41
|
-
puts "Usage: #{$0} blah.rpm"
|
42
|
-
exit 1
|
43
|
-
end
|
44
|
-
|
45
|
-
rpm = File.new(ARGV[0])
|
46
|
-
|
47
|
-
# Read the 'lead' - it's mostly an ignored part of the rpm file.
|
48
|
-
lead = rpm.read(96)
|
49
|
-
magic, major, minor, type, archnum, name, osnum, signature_type, reserved = lead.unpack("A4CCnnA66nnA16")
|
50
|
-
|
51
|
-
puts "RPM file version #{major}.#{minor} (#{signature_type == 5 ? "signed" : "unsigned"})"
|
52
|
-
|
53
|
-
if signature_type == 5
|
54
|
-
# Read a header for the rpm signature. This has the same format as a normal
|
55
|
-
# rpm header
|
56
|
-
puts "Checking signature"
|
57
|
-
length = read_header(rpm) do |tag|
|
58
|
-
# print each tag in this header
|
59
|
-
p tag
|
60
|
-
end
|
61
|
-
|
62
|
-
# signature headers are padded up to an 8-byte boundar, details here:
|
63
|
-
# http://rpm.org/gitweb?p=rpm.git;a=blob;f=lib/signature.c;h=63e59c00f255a538e48cbc8b0cf3b9bd4a4dbd56;hb=HEAD#l204
|
64
|
-
# Throw away the pad.
|
65
|
-
rpm.read((length % 8))
|
66
|
-
end
|
67
|
-
|
68
|
-
# Read the rpm header
|
69
|
-
puts "Checking header"
|
70
|
-
read_header(rpm)
|
71
|
-
p rpm.read(4)
|