ruby_smb 0.0.21 → 0.0.22

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.
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
+