ruby_smb 0.0.21 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/examples/net_share_enum_all.rb +5 -2
  5. data/lib/ruby_smb.rb +1 -1
  6. data/lib/ruby_smb/client.rb +4 -35
  7. data/lib/ruby_smb/dcerpc.rb +7 -22
  8. data/lib/ruby_smb/dcerpc/bind.rb +30 -36
  9. data/lib/ruby_smb/dcerpc/bind_ack.rb +72 -0
  10. data/lib/ruby_smb/dcerpc/error.rb +15 -0
  11. data/lib/ruby_smb/dcerpc/ndr.rb +31 -30
  12. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +11 -0
  13. data/lib/ruby_smb/dcerpc/pdu_header.rb +29 -0
  14. data/lib/ruby_smb/dcerpc/ptypes.rb +26 -0
  15. data/lib/ruby_smb/dcerpc/request.rb +17 -30
  16. data/lib/ruby_smb/dcerpc/response.rb +15 -34
  17. data/lib/ruby_smb/dcerpc/srvsvc.rb +5 -7
  18. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +8 -4
  19. data/lib/ruby_smb/dcerpc/uuid.rb +31 -13
  20. data/lib/ruby_smb/smb1/bit_field.rb +0 -1
  21. data/lib/ruby_smb/smb1/bit_field/trans_flags.rb +3 -2
  22. data/lib/ruby_smb/smb1/data_block.rb +5 -0
  23. data/lib/ruby_smb/smb1/dcerpc.rb +67 -0
  24. data/lib/ruby_smb/smb1/packet.rb +1 -0
  25. data/lib/ruby_smb/smb1/packet/trans.rb +7 -1
  26. data/lib/ruby_smb/smb1/packet/trans/data_block.rb +19 -7
  27. data/lib/ruby_smb/smb1/packet/trans/request.rb +36 -25
  28. data/lib/ruby_smb/smb1/packet/trans/response.rb +22 -21
  29. data/lib/ruby_smb/smb1/packet/trans/subcommands.rb +1 -0
  30. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +61 -0
  31. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +44 -0
  32. data/lib/ruby_smb/smb1/packet/trans2/request.rb +1 -1
  33. data/lib/ruby_smb/smb1/pipe.rb +3 -0
  34. data/lib/ruby_smb/smb2/dcerpc.rb +68 -0
  35. data/lib/ruby_smb/smb2/pipe.rb +3 -0
  36. data/lib/ruby_smb/version.rb +1 -1
  37. data/spec/lib/ruby_smb/client_spec.rb +53 -6
  38. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +224 -0
  39. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +255 -7
  40. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +31 -0
  41. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +84 -0
  42. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +106 -13
  43. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +89 -8
  44. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +176 -0
  45. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +97 -1
  46. data/spec/lib/ruby_smb/smb1/data_block_spec.rb +43 -3
  47. data/spec/lib/ruby_smb/smb1/packet/trans/data_block_spec.rb +137 -0
  48. data/spec/lib/ruby_smb/smb1/packet/trans/request_spec.rb +239 -13
  49. data/spec/lib/ruby_smb/smb1/packet/trans/response_spec.rb +122 -13
  50. data/spec/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request_spec.rb +254 -0
  51. data/spec/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response_spec.rb +122 -0
  52. data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +2 -2
  53. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +199 -1
  54. data/spec/lib/ruby_smb/smb2/file_spec.rb +2 -1
  55. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +196 -1
  56. metadata +25 -10
  57. metadata.gz.sig +0 -0
  58. data/lib/ruby_smb/dcerpc/handle.rb +0 -60
  59. data/lib/ruby_smb/smb1/bit_field/trans2_flags.rb +0 -15
  60. data/spec/lib/ruby_smb/dcerpc/handle_spec.rb +0 -31
  61. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +0 -13
  62. data/spec/lib/ruby_smb/smb1/bit_field/trans2_flags_spec.rb +0 -26
@@ -1,15 +1,96 @@
1
- require 'spec_helper'
2
-
3
1
  RSpec.describe RubySMB::Dcerpc::Response do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :pdu_header }
5
+ it { is_expected.to respond_to :alloc_hint }
6
+ it { is_expected.to respond_to :p_cont_id }
7
+ it { is_expected.to respond_to :cancel_count }
8
+ it { is_expected.to respond_to :stub }
9
+ it { is_expected.to respond_to :auth_verifier }
4
10
 
5
- let(:raw_response){'0500020310000000b801000000000000a00100000000000001000000010000000000020006000000040002000600000008000200000000800c00020010000200000000001400020018000200000000801c00020020000200000000002400020028000200030000802c000200300002000000000034000200070000000000000007000000410044004d0049004e002400000000000d000000000000000d000000520065006d006f00740065002000410064006d0069006e0000000000020000000000000002000000430000000100000000000000010000000000000003000000000000000300000043002400000000000e000000000000000e000000440065006600610075006c007400200073006800610072006500000007000000000000000700000064006f00670065003600340000000000010000000000000001000000000000000500000000000000050000004900500043002400000000000b000000000000000b000000520065006d006f00740065002000490050004300000000000600000000000000060000005500730065007200730000000100000000000000010000000000000006000000380002000000000000000000'.strip.gsub(/([A-Fa-f0-9]{1,2})\s*?/) { $1.hex.chr }}
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
6
14
 
7
- describe '#read' do
15
+ describe '#pdu_header' do
16
+ subject(:header) { packet.pdu_header }
17
+
18
+ it 'is a standard PDU Header' do
19
+ expect(header).to be_a RubySMB::Dcerpc::PDUHeader
20
+ end
8
21
 
9
- let(:response){described_class.read(raw_response)}
22
+ it 'should have the #ptype field set to PTypes::RESPONSE' do
23
+ expect(header.ptype).to eq RubySMB::Dcerpc::PTypes::RESPONSE
24
+ end
25
+ end
26
+
27
+ describe '#alloc_hint' do
28
+ it 'should be a 32-bit unsigned integer' do
29
+ expect(packet.alloc_hint).to be_a BinData::Uint32le
30
+ end
10
31
 
11
- it 'should use the alloc_hint to determine stub length' do
12
- expect(response.stub.do_num_bytes).to eq response.alloc_hint
32
+ it 'should be the size of the #stub field' do
33
+ stub = 'ABCD'
34
+ packet.stub = stub
35
+ expect(packet.alloc_hint).to eq(stub.length)
13
36
  end
14
37
  end
15
- end
38
+
39
+ describe '#p_cont_id' do
40
+ it 'should be a 16-bit unsigned integer' do
41
+ expect(packet.p_cont_id).to be_a BinData::Uint16le
42
+ end
43
+ end
44
+
45
+ describe '#cancel_count' do
46
+ it 'should be a 8-bit unsigned integer' do
47
+ expect(packet.cancel_count).to be_a BinData::Uint8
48
+ end
49
+ end
50
+
51
+ describe '#stub' do
52
+ it 'is a string' do
53
+ expect(packet.stub).to be_a BinData::String
54
+ end
55
+
56
+ it 'reads the expected number of bytes' do
57
+ stub = 'ABCDEFGH'
58
+ packet.pdu_header.frag_length = 28
59
+ packet.stub.read(stub)
60
+ expect(packet.stub).to eq(stub[0,4])
61
+ end
62
+ end
63
+
64
+ describe '#auth_verifier' do
65
+ it 'should be a string' do
66
+ expect(packet.auth_verifier).to be_a BinData::String
67
+ end
68
+
69
+ it 'should not exist if the #auth_length PDU header field is 0' do
70
+ packet.pdu_header.auth_length = 0
71
+ expect(packet.auth_verifier?).to be false
72
+ end
73
+
74
+ it 'should exist only if the #auth_length PDU header field is greater than 0' do
75
+ packet.pdu_header.auth_length = 10
76
+ expect(packet.auth_verifier?).to be true
77
+ end
78
+
79
+ it 'reads #auth_length bytes' do
80
+ auth_verifier = '12345678'
81
+ packet.pdu_header.auth_length = 6
82
+ packet.auth_verifier.read(auth_verifier)
83
+ expect(packet.auth_verifier).to eq(auth_verifier[0,6])
84
+ end
85
+ end
86
+
87
+ it 'reads its own binary representation and output the same packet' do
88
+ packet.stub = 'ABCD'
89
+ packet.auth_verifier = '123456'
90
+ packet.pdu_header.auth_length = 6
91
+ binary = packet.to_binary_s
92
+ expect(described_class.read(binary)).to eq(packet)
93
+ end
94
+ end
95
+
96
+
@@ -0,0 +1,176 @@
1
+ RSpec.describe RubySMB::Dcerpc::Srvsvc::NetShareEnumAll do
2
+ subject(:packet) { described_class.new(host: '1.2.3.4') }
3
+
4
+ it { is_expected.to respond_to :referent_id }
5
+ it { is_expected.to respond_to :max_count }
6
+ it { is_expected.to respond_to :offset }
7
+ it { is_expected.to respond_to :actual_count }
8
+ it { is_expected.to respond_to :server_unc }
9
+ it { is_expected.to respond_to :pad }
10
+ it { is_expected.to respond_to :level }
11
+ it { is_expected.to respond_to :ctr }
12
+ it { is_expected.to respond_to :ctr_referent_id }
13
+ it { is_expected.to respond_to :ctr_count }
14
+ it { is_expected.to respond_to :pointer_to_array }
15
+ it { is_expected.to respond_to :max_buffer }
16
+ it { is_expected.to respond_to :resume_referent_id }
17
+ it { is_expected.to respond_to :resume_handle }
18
+
19
+ it 'is little endian' do
20
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
21
+ end
22
+
23
+ describe '#referent_id' do
24
+ it 'should be a 32-bit unsigned integer' do
25
+ expect(packet.referent_id).to be_a BinData::Uint32le
26
+ end
27
+
28
+ it 'should have a default value of 1' do
29
+ expect(packet.referent_id).to eq 1
30
+ end
31
+ end
32
+
33
+ describe '#max_count' do
34
+ it 'should be a 32-bit unsigned integer' do
35
+ expect(packet.max_count).to be_a BinData::Uint32le
36
+ end
37
+
38
+ it 'should be the number of unicode characters in the #server_unc field' do
39
+ expect(packet.max_count).to eq(packet.server_unc.do_num_bytes / 2)
40
+ end
41
+ end
42
+
43
+ describe '#offset' do
44
+ it 'should be a 32-bit unsigned integer' do
45
+ expect(packet.offset).to be_a BinData::Uint32le
46
+ end
47
+
48
+ it 'should have a default value of 0' do
49
+ expect(packet.offset).to eq 0
50
+ end
51
+ end
52
+
53
+ describe '#actual_count' do
54
+ it 'should be a 32-bit unsigned integer' do
55
+ expect(packet.actual_count).to be_a BinData::Uint32le
56
+ end
57
+
58
+ it 'should be the same value than #max_count' do
59
+ expect(packet.actual_count).to eq(packet.max_count)
60
+ end
61
+ end
62
+
63
+ describe '#server_unc' do
64
+ it 'is a Stringz16' do
65
+ expect(packet.server_unc).to be_a RubySMB::Field::Stringz16
66
+ end
67
+
68
+ it 'uses the #host parameter value to create the UNC unicode string' do
69
+ expect(packet.server_unc).to eq("\\\\#{"1.2.3.4".encode('utf-8')}".encode('utf-16le'))
70
+ end
71
+ end
72
+
73
+ describe '#pad' do
74
+ it 'should keep #level 4-byte aligned' do
75
+ expect(packet.level.abs_offset % 4).to eq 0
76
+ end
77
+ end
78
+
79
+ describe '#level' do
80
+ it 'should be a 32-bit unsigned integer' do
81
+ expect(packet.level).to be_a BinData::Uint32le
82
+ end
83
+
84
+ it 'should have a default value of 1' do
85
+ expect(packet.level).to eq 1
86
+ end
87
+ end
88
+
89
+ describe '#ctr' do
90
+ it 'should be a 32-bit unsigned integer' do
91
+ expect(packet.ctr).to be_a BinData::Uint32le
92
+ end
93
+
94
+ it 'should have a default value of 1' do
95
+ expect(packet.ctr).to eq 1
96
+ end
97
+ end
98
+
99
+ describe '#ctr_referent_id' do
100
+ it 'should be a 32-bit unsigned integer' do
101
+ expect(packet.ctr_referent_id).to be_a BinData::Uint32le
102
+ end
103
+
104
+ it 'should have a default value of 1' do
105
+ expect(packet.ctr_referent_id).to eq 1
106
+ end
107
+ end
108
+
109
+ describe '#ctr_count' do
110
+ it 'should be a 32-bit unsigned integer' do
111
+ expect(packet.ctr_count).to be_a BinData::Uint32le
112
+ end
113
+
114
+ it 'should have a default value of 0' do
115
+ expect(packet.ctr_count).to eq 0
116
+ end
117
+ end
118
+
119
+ describe '#pointer_to_array' do
120
+ it 'should be a 32-bit unsigned integer' do
121
+ expect(packet.pointer_to_array).to be_a BinData::Uint32le
122
+ end
123
+
124
+ it 'should have a default value of 0' do
125
+ expect(packet.pointer_to_array).to eq 0
126
+ end
127
+ end
128
+
129
+ describe '#max_buffer' do
130
+ it 'should be a 32-bit unsigned integer' do
131
+ expect(packet.max_buffer).to be_a BinData::Uint32le
132
+ end
133
+
134
+ it 'should have a default value of 4294967295' do
135
+ expect(packet.max_buffer).to eq 4294967295
136
+ end
137
+ end
138
+
139
+ describe '#resume_referent_id' do
140
+ it 'should be a 32-bit unsigned integer' do
141
+ expect(packet.resume_referent_id).to be_a BinData::Uint32le
142
+ end
143
+
144
+ it 'should have a default value of 1' do
145
+ expect(packet.resume_referent_id).to eq 1
146
+ end
147
+ end
148
+
149
+ describe '#resume_handle' do
150
+ it 'should be a 32-bit unsigned integer' do
151
+ expect(packet.resume_handle).to be_a BinData::Uint32le
152
+ end
153
+
154
+ it 'should have a default value of 0' do
155
+ expect(packet.resume_handle).to eq 0
156
+ end
157
+ end
158
+
159
+ describe '#pad_length' do
160
+ it 'returns 0 when #level is already 4-byte aligned' do
161
+ expect(packet.pad_length).to eq 0
162
+ end
163
+
164
+ it 'returns 2 when #level is only 2-byte aligned' do
165
+ packet.server_unc = packet.server_unc + 'A'.encode('utf-16le')
166
+ expect(packet.pad_length).to eq 2
167
+ end
168
+ end
169
+
170
+ describe 'class method self.parse_response' do
171
+ # TODO: this class method will be refactored to use proper BinData NDR
172
+ # fields once they are ready (see https://github.com/rapid7/ruby_smb/issues/124)
173
+ end
174
+ end
175
+
176
+
@@ -1,4 +1,100 @@
1
- require 'spec_helper'
1
+ RSpec.describe RubySMB::Dcerpc::Uuid do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :time_low }
5
+ it { is_expected.to respond_to :time_mid }
6
+ it { is_expected.to respond_to :time_hi_and_version }
7
+ it { is_expected.to respond_to :clock_seq_hi_and_reserved }
8
+ it { is_expected.to respond_to :clock_seq_low }
9
+ it { is_expected.to respond_to :node }
10
+
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
14
+
15
+ describe '#time_low' do
16
+ it 'should be a 32-bit unsigned integer' do
17
+ expect(packet.time_low).to be_a BinData::Uint32le
18
+ end
19
+ end
20
+
21
+ describe '#time_mid' do
22
+ it 'should be a 16-bit unsigned integer' do
23
+ expect(packet.time_mid).to be_a BinData::Uint16le
24
+ end
25
+ end
26
+
27
+ describe '#time_hi_and_version' do
28
+ it 'should be a 16-bit unsigned integer' do
29
+ expect(packet.time_hi_and_version).to be_a BinData::Uint16le
30
+ end
31
+ end
32
+
33
+ describe '#clock_seq_hi_and_reserved' do
34
+ it 'should be a 8-bit unsigned integer' do
35
+ expect(packet.clock_seq_hi_and_reserved).to be_a BinData::Uint8
36
+ end
37
+ end
38
+
39
+ describe '#clock_seq_low' do
40
+ it 'should be a 8-bit unsigned integer' do
41
+ expect(packet.clock_seq_low).to be_a BinData::Uint8
42
+ end
43
+ end
44
+
45
+ describe '#node' do
46
+ it 'should be an Array' do
47
+ expect(packet.node).to be_a BinData::Array
48
+ end
49
+
50
+ it 'should have 6 elements' do
51
+ expect(packet.node.size).to eq 6
52
+ end
53
+
54
+ it 'should have 8-bit unsigned integer elements' do
55
+ expect(packet.node[0]).to be_a BinData::Uint8
56
+ end
57
+ end
58
+
59
+ context 'when using a string representation of UUID' do
60
+ let(:uuid_string){ '8a885d04-1ceb-11c9-9fe8-08002b104860' }
61
+
62
+ before :example do
63
+ packet.set(uuid_string)
64
+ end
65
+
66
+ describe '#get' do
67
+ it 'returns the correct string representation of UUID' do
68
+ expect(packet.get).to eq uuid_string
69
+ end
70
+ end
71
+
72
+ describe '#set' do
73
+ it 'sets the expected values' do
74
+ expect(packet.time_low).to eq 0x8A885D04
75
+ expect(packet.time_mid).to eq 0x1CEb
76
+ expect(packet.time_hi_and_version).to eq 0x11C9
77
+ expect(packet.clock_seq_hi_and_reserved).to eq 0x9F
78
+ expect(packet.clock_seq_low).to eq 0xE8
79
+ expect(packet.node).to eq [0x08, 0x00, 0x2B, 0x10, 0x48, 0x60]
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
2
98
 
3
99
  RSpec.describe RubySMB::Dcerpc::Uuid do
4
100
  let(:uuid_string){'8a885d04-1ceb-11c9-9fe8-08002b104860'}
@@ -1,9 +1,20 @@
1
1
  RSpec.describe RubySMB::SMB1::DataBlock do
2
2
  subject(:data_block) { described_class.new }
3
3
 
4
+ let(:record_class) do
5
+ Class.new(described_class) do
6
+ int8 :field1
7
+ int32 :field2
8
+ end
9
+ end
10
+
4
11
  it { is_expected.to respond_to :byte_count }
5
12
 
6
- describe 'byte_count' do
13
+ it 'is little endian' do
14
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
15
+ end
16
+
17
+ describe '#byte_count' do
7
18
  it 'should be a 16-bit field per the SMB spec' do
8
19
  expect(data_block.byte_count).to be_a BinData::Uint16le
9
20
  end
@@ -20,7 +31,36 @@ RSpec.describe RubySMB::SMB1::DataBlock do
20
31
  end
21
32
  end
22
33
 
23
- it 'is little endian' do
24
- expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
34
+ describe 'class method #data_fields' do
35
+ it 'lists all the fields except #byte_count field' do
36
+ expect(record_class.data_fields).to eq([:field1, :field2])
37
+ end
25
38
  end
39
+
40
+ describe '#calculate_byte_count' do
41
+ it 'returns the expected expected packet size' do
42
+ expect(record_class.new.calculate_byte_count).to eq(5)
43
+ end
44
+
45
+ it 'does not count disabled fields' do
46
+ record_class.class_eval do
47
+ int8 :field3, onlyif: -> { false }
48
+ end
49
+ expect(record_class.new.calculate_byte_count).to eq(5)
50
+ end
51
+ end
52
+
53
+ describe '#field_enabled?' do
54
+ it 'returns true when the field is enabled' do
55
+ expect(record_class.new.field_enabled?(:field1)).to be true
56
+ end
57
+
58
+ it 'returns false when the field is disabled' do
59
+ record_class.class_eval do
60
+ int8 :field3, onlyif: -> { false }
61
+ end
62
+ expect(record_class.new.field_enabled?(:field3)).to be false
63
+ end
64
+ end
65
+
26
66
  end
@@ -0,0 +1,137 @@
1
+ RSpec.describe RubySMB::SMB1::Packet::Trans::DataBlock do
2
+ let(:data_block_class) { Class.new(described_class) }
3
+ subject(:data_block_obj) { data_block_class.new }
4
+
5
+ it { is_expected.to respond_to :enable_padding }
6
+ it { is_expected.to respond_to :enable_padding= }
7
+
8
+ it 'is a standard DataBlock' do
9
+ expect(data_block_obj).to be_a RubySMB::SMB1::DataBlock
10
+ end
11
+
12
+ describe '#enable_padding' do
13
+ it 'is true by default' do
14
+ expect(data_block_obj.enable_padding).to be true
15
+ end
16
+ end
17
+
18
+ describe '#pad1_length' do
19
+ context 'when enable_padding is false' do
20
+ it 'returns 0' do
21
+ data_block_obj.enable_padding = false
22
+ expect(data_block_obj.send(:pad1_length)).to eq(0)
23
+ end
24
+ end
25
+
26
+ context 'when enable_padding is true' do
27
+ context 'when #name field exists' do
28
+ let(:my_name) { double('name') }
29
+
30
+ before :example do
31
+ data_block_class.class_exec{
32
+ def name() end
33
+ }
34
+ allow(data_block_obj).to receive(:name).and_return(my_name)
35
+ allow(data_block_obj).to receive(:respond_to?).with(:name).and_return(true)
36
+ allow(my_name).to receive(:abs_offset).and_return(0)
37
+ allow(my_name).to receive(:to_binary_s).and_return("")
38
+ end
39
+
40
+ it 'returns 0 if trans_parameters is 4-byte aligned' do
41
+ expect(data_block_obj.send(:pad1_length)).to eq(0)
42
+ end
43
+
44
+ it 'returns the correct number of byte if trans_parameters is not 4-byte aligned' do
45
+ allow(my_name).to receive(:abs_offset).and_return(1)
46
+ expect(data_block_obj.send(:pad1_length)).to eq(3)
47
+ end
48
+ end
49
+
50
+ context 'when #name field does not exist' do
51
+ let(:byte_count) { double('byte_count') }
52
+
53
+ before :example do
54
+ data_block_class.class_exec{
55
+ def byte_count() end
56
+ }
57
+ allow(data_block_obj).to receive(:byte_count).and_return(byte_count)
58
+ allow(data_block_obj).to receive(:respond_to?).with(:name).and_return(false)
59
+ allow(byte_count).to receive(:abs_offset).and_return(2)
60
+ end
61
+
62
+ it 'returns 0 if trans_parameters is 4-byte aligned' do
63
+ expect(data_block_obj.send(:pad1_length)).to eq(0)
64
+ end
65
+
66
+ it 'returns the correct number of byte if trans_parameters is not 4-byte aligned' do
67
+ allow(byte_count).to receive(:abs_offset).and_return(1)
68
+ expect(data_block_obj.send(:pad1_length)).to eq(1)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#pad2_length' do
75
+ context 'when enable_padding is false' do
76
+ it 'returns 0' do
77
+ data_block_obj.enable_padding = false
78
+ expect(data_block_obj.send(:pad2_length)).to eq(0)
79
+ end
80
+ end
81
+
82
+ context 'when enable_padding is true' do
83
+ let(:trans_parameters) { double('trans_parameters') }
84
+
85
+ before :example do
86
+ data_block_class.class_exec{
87
+ def trans_parameters() end
88
+ }
89
+ allow(data_block_obj).to receive(:trans_parameters).and_return(trans_parameters)
90
+ allow(data_block_obj).to receive(:respond_to?).with(:name).and_return(false)
91
+ allow(trans_parameters).to receive(:abs_offset).and_return(0)
92
+ allow(trans_parameters).to receive(:length).and_return(0)
93
+ end
94
+
95
+ it 'returns 0 if trans_parameters is 4-byte aligned' do
96
+ expect(data_block_obj.send(:pad2_length)).to eq(0)
97
+ end
98
+
99
+ it 'returns the correct number of byte if trans_parameters is not 4-byte aligned' do
100
+ allow(trans_parameters).to receive(:abs_offset).and_return(1)
101
+ expect(data_block_obj.send(:pad2_length)).to eq(3)
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '#pad_name_length' do
107
+ context 'when enable_padding is false' do
108
+ it 'returns 0' do
109
+ data_block_obj.enable_padding = false
110
+ expect(data_block_obj.send(:pad_name_length)).to eq(0)
111
+ end
112
+ end
113
+
114
+ context 'when enable_padding is true' do
115
+ let(:byte_count) { double('byte_count') }
116
+
117
+ before :example do
118
+ data_block_class.class_exec{
119
+ def byte_count() end
120
+ }
121
+ allow(data_block_obj).to receive(:byte_count).and_return(byte_count)
122
+ allow(data_block_obj).to receive(:respond_to?).with(:name).and_return(false)
123
+ allow(byte_count).to receive(:abs_offset).and_return(0)
124
+ end
125
+
126
+ it 'returns 0 if trans_parameters is 4-byte aligned' do
127
+ expect(data_block_obj.send(:pad_name_length)).to eq(0)
128
+ end
129
+
130
+ it 'returns the correct number of byte if trans_parameters is not 4-byte aligned' do
131
+ allow(byte_count).to receive(:abs_offset).and_return(1)
132
+ expect(data_block_obj.send(:pad_name_length)).to eq(1)
133
+ end
134
+ end
135
+ end
136
+ end
137
+