CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/spec/lib/rex/proto/thrift/thrift_data_spec.rb
Views: 1904
1
# -*- coding: binary -*-
2
require 'spec_helper'
3
require 'rex/text'
4
5
RSpec.describe Rex::Proto::Thrift::ThriftData do
6
subject(:instance) { described_class.new }
7
8
it { should respond_to :data_type }
9
it { should respond_to :field_id }
10
it { should respond_to :data_value }
11
12
it 'is big endian' do
13
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :big
14
end
15
16
it 'tracks the data type in a ThriftDataType field' do
17
expect(instance.data_type).to be_a Rex::Proto::Thrift::ThriftDataType
18
end
19
20
it 'tracks the field ID in a Uint16 field' do
21
expect(instance.field_id).to be_a BinData::Uint16be
22
end
23
24
it 'tracks the data value in a Choice field' do
25
expect(instance.data_value).to be_a BinData::Choice
26
end
27
28
it 'sets the data type correctly by default' do
29
expect(instance.data_type).to eq Rex::Proto::Thrift::ThriftDataType::T_STOP
30
end
31
32
context 'when the data type is T_STOP' do
33
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_STOP }
34
let(:value) { {
35
data_type: data_type
36
} }
37
let(:binary_s) { [data_type].pack('C') }
38
39
describe '#to_binary_s' do
40
it 'should correctly encode' do
41
expect(described_class.new(value).to_binary_s).to eq binary_s
42
end
43
end
44
45
describe '.read' do
46
it 'should correctly decode' do
47
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
48
end
49
end
50
end
51
52
context 'when the data type is T_BOOLEAN' do
53
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_BOOLEAN }
54
let(:field_id) { rand(0xffff) }
55
let(:value) { {
56
data_type: data_type,
57
field_id: field_id,
58
data_value: true
59
} }
60
let(:binary_s) { [data_type, field_id, 1].pack('CnC') }
61
62
describe '#to_binary_s' do
63
it 'should correctly encode' do
64
expect(described_class.new(value).to_binary_s).to eq binary_s
65
end
66
end
67
68
describe '.read' do
69
it 'should correctly decode' do
70
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
71
end
72
end
73
end
74
75
context 'when the data type is T_I16' do
76
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_I16 }
77
let(:field_id) { rand(0xffff) }
78
let(:number) { 0x7fff - rand(0xffff) }
79
let(:value) { {
80
data_type: data_type,
81
field_id: field_id,
82
data_value: number
83
} }
84
let(:binary_s) { [data_type, field_id, number].pack('Cns>') }
85
86
describe '#to_binary_s' do
87
it 'should correctly encode' do
88
expect(described_class.new(value).to_binary_s).to eq binary_s
89
end
90
end
91
92
describe '.read' do
93
it 'should correctly decode' do
94
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
95
end
96
end
97
end
98
99
context 'when the data type is T_I32' do
100
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_I32 }
101
let(:field_id) { rand(0xffff) }
102
let(:number) { 0x7fffffff - rand(0xffffffff) }
103
let(:value) { {
104
data_type: data_type,
105
field_id: field_id,
106
data_value: number
107
} }
108
let(:binary_s) { [data_type, field_id, number].pack('Cnl>') }
109
110
describe '#to_binary_s' do
111
it 'should correctly encode' do
112
expect(described_class.new(value).to_binary_s).to eq binary_s
113
end
114
end
115
116
describe '.read' do
117
it 'should correctly decode' do
118
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
119
end
120
end
121
end
122
123
context 'when the data type is T_I64' do
124
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_I64 }
125
let(:field_id) { rand(0xffff) }
126
let(:number) { 0x7fffffffffffffff - rand(0xffffffffffffffff) }
127
let(:value) { {
128
data_type: data_type,
129
field_id: field_id,
130
data_value: number
131
} }
132
let(:binary_s) { [data_type, field_id, number].pack('Cnq>') }
133
134
describe '#to_binary_s' do
135
it 'should correctly encode' do
136
expect(described_class.new(value).to_binary_s).to eq binary_s
137
end
138
end
139
140
describe '.read' do
141
it 'should correctly decode' do
142
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
143
end
144
end
145
end
146
147
context 'when the data type is T_UTF7' do
148
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_UTF7 }
149
let(:field_id) { rand(0xffff) }
150
let(:text) { Rex::Text.rand_text_alphanumeric(10) }
151
let(:value) { {
152
data_type: data_type,
153
field_id: field_id,
154
data_value: text
155
} }
156
let(:binary_s) { [data_type, field_id, text.length].pack('CnN') + text }
157
158
describe '#to_binary_s' do
159
it 'should correctly encode' do
160
expect(described_class.new(value).to_binary_s).to eq binary_s
161
end
162
end
163
164
describe '.read' do
165
it 'should correctly decode' do
166
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
167
end
168
end
169
end
170
171
context 'when the data type is T_STRUCT' do
172
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_STRUCT }
173
let(:field_id) { rand(0xffff) }
174
let(:object) { [ { data_type: Rex::Proto::Thrift::ThriftDataType::T_STOP } ] }
175
let(:value) { {
176
data_type: data_type,
177
field_id: field_id,
178
data_value: object
179
} }
180
let(:binary_s) { [data_type, field_id, 0].pack('CnC') }
181
182
describe '#to_binary_s' do
183
it 'should correctly encode' do
184
expect(described_class.new(value).to_binary_s).to eq binary_s
185
end
186
end
187
188
describe '.read' do
189
it 'should correctly decode' do
190
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
191
end
192
end
193
end
194
195
context 'when the data type is T_SET' do
196
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_SET }
197
let(:field_id) { rand(0xffff) }
198
let(:object) { { data_type: Rex::Proto::Thrift::ThriftDataType::T_I16, members_size: 0 } }
199
let(:value) { {
200
data_type: data_type,
201
field_id: field_id,
202
data_value: object
203
} }
204
let(:binary_s) { [data_type, field_id, Rex::Proto::Thrift::ThriftDataType::T_I16, 0].pack('CnCN') }
205
206
describe '#to_binary_s' do
207
it 'should correctly encode' do
208
expect(described_class.new(value).to_binary_s).to eq binary_s
209
end
210
end
211
212
describe '.read' do
213
it 'should correctly decode' do
214
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
215
end
216
end
217
end
218
219
context 'when the data type is T_LIST' do
220
let(:data_type) { Rex::Proto::Thrift::ThriftDataType::T_LIST }
221
let(:field_id) { rand(0xffff) }
222
let(:object) { { data_type: Rex::Proto::Thrift::ThriftDataType::T_I16, members_size: 0 } }
223
let(:value) { {
224
data_type: data_type,
225
field_id: field_id,
226
data_value: object
227
} }
228
let(:binary_s) { [data_type, field_id, Rex::Proto::Thrift::ThriftDataType::T_I16, 0].pack('CnCN') }
229
230
describe '#to_binary_s' do
231
it 'should correctly encode' do
232
expect(described_class.new(value).to_binary_s).to eq binary_s
233
end
234
end
235
236
describe '.read' do
237
it 'should correctly decode' do
238
expect(described_class.read(binary_s).snapshot.keep_if { |k,_| value.key? k }).to eq value
239
end
240
end
241
end
242
end
243
244