Skip to content

Commit d023c92

Browse files
committed
Add specs for Rex::OLE::DirEntry
1 parent 4180016 commit d023c92

File tree

1 file changed

+259
-0
lines changed

1 file changed

+259
-0
lines changed

spec/lib/rex/ole/direntry_spec.rb

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
# -*- coding:binary -*-
2+
require 'spec_helper'
3+
4+
require 'rex/ole'
5+
6+
describe Rex::OLE::DirEntry do
7+
8+
let(:storage) do
9+
Rex::OLE::Storage.new
10+
end
11+
12+
subject(:dir_entry) do
13+
described_class.new(storage)
14+
end
15+
16+
describe ".new" do
17+
it "returns a Rex::OLE::DirEntry instance" do
18+
expect(described_class.new(storage)).to be_a(Rex::OLE::DirEntry)
19+
end
20+
21+
it { expect(dir_entry.instance_variable_get(:@stg)).to eq(storage) }
22+
it { expect(dir_entry.sid).to eq(0) }
23+
it { expect(dir_entry.instance_variable_get(:@_ab)).to eq('Root Entry') }
24+
it { expect(dir_entry.instance_variable_get(:@_cb)).to be_nil }
25+
it { expect(dir_entry.instance_variable_get(:@_mse)).to eq(Rex::OLE::STGTY_ROOT) }
26+
it { expect(dir_entry.instance_variable_get(:@_bflags)).to eq(0) }
27+
it { expect(dir_entry._sidLeftSib).to eq(Rex::OLE::SECT_FREE) }
28+
it { expect(dir_entry._sidRightSib).to eq(Rex::OLE::SECT_FREE) }
29+
it { expect(dir_entry._sidChild).to eq(Rex::OLE::SECT_FREE) }
30+
it { expect(dir_entry.instance_variable_get(:@_clsId)).to be_a(Rex::OLE::CLSID) }
31+
it { expect(dir_entry.instance_variable_get(:@_dwUserFlags)).to eq(0) }
32+
it { expect(dir_entry.instance_variable_get(:@_ctime)).to eq("\x00" * 8) }
33+
it { expect(dir_entry.instance_variable_get(:@_mtime)).to eq("\x00" * 8) }
34+
it { expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_END) }
35+
it { expect(dir_entry.instance_variable_get(:@_ulSize)).to eq(0) }
36+
it { expect(dir_entry.instance_variable_get(:@children)).to be_an(Array) }
37+
it { expect(dir_entry.instance_variable_get(:@children)).to be_empty }
38+
end
39+
40+
describe "#length" do
41+
it "returns _ulSize" do
42+
dir_entry.instance_variable_set(:@_ulSize, 28)
43+
expect(dir_entry.length).to eq(28)
44+
end
45+
end
46+
47+
describe "#<<" do
48+
it "increments the children array" do
49+
dir_entry << 1
50+
children = dir_entry.instance_variable_get(:@children)
51+
expect(children.length).to eq(1)
52+
end
53+
54+
it "appends to the children array" do
55+
dir_entry << 1
56+
children = dir_entry.instance_variable_get(:@children)
57+
expect(children).to eq([1])
58+
end
59+
end
60+
61+
describe "#each" do
62+
it "calls the block for every children element" do
63+
dir_entry << 1
64+
dir_entry << 2
65+
dir_entry << 3
66+
res = 0
67+
dir_entry.each { |elem| res += elem}
68+
expect(res).to eq(1 + 2 + 3)
69+
end
70+
end
71+
72+
describe "#type" do
73+
it "returns the _mse field" do
74+
expect(dir_entry.type).to eq(Rex::OLE::STGTY_ROOT)
75+
end
76+
end
77+
78+
describe "#type=" do
79+
it "modifies the _mse field" do
80+
dir_entry.type = 3838
81+
expect(dir_entry.instance_variable_get(:@_mse)).to eq(3838)
82+
end
83+
end
84+
85+
describe "#name" do
86+
it "returns the _ab field" do
87+
expect(dir_entry.name).to eq('Root Entry')
88+
end
89+
end
90+
91+
describe "#name=" do
92+
it "modifies the _ab field" do
93+
dir_entry.name = 'test'
94+
expect(dir_entry.instance_variable_get(:@_ab)).to eq('test')
95+
end
96+
end
97+
98+
describe "#start_sector" do
99+
it "returns the _sectStart field" do
100+
expect(dir_entry.start_sector).to eq(Rex::OLE::SECT_END)
101+
end
102+
end
103+
104+
describe "#start_sector=" do
105+
it "modifies the _sectStart field" do
106+
dir_entry.start_sector = Rex::OLE::SECT_FREE
107+
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_FREE)
108+
end
109+
end
110+
111+
describe "#find_stream_by_name_and_type" do
112+
context "when any children matches the search criteria" do
113+
it "returns nil" do
114+
expect(dir_entry.find_stream_by_name_and_type('name', Rex::OLE::STGTY_ROOT)).to be_nil
115+
end
116+
end
117+
118+
context "when one children matches the search criteria" do
119+
let(:stream) { Rex::OLE::Stream.new(storage) }
120+
let(:name) { 'name' }
121+
let(:type) { Rex::OLE::STGTY_ROOT }
122+
it "returns the matching stream" do
123+
stream.name = name
124+
stream.type = type
125+
dir_entry << stream
126+
expect(dir_entry.find_stream_by_name_and_type(name, type)).to eq(stream)
127+
end
128+
end
129+
130+
context "when several children matches the search criteria" do
131+
let(:stream) { Rex::OLE::Stream.new(storage) }
132+
let(:stream_two) { Rex::OLE::Stream.new(storage) }
133+
let(:name) { 'name' }
134+
let(:type) { Rex::OLE::STGTY_ROOT }
135+
let(:sid) { 2 }
136+
it "returns the first matching stream" do
137+
stream.name = name
138+
stream.type = type
139+
dir_entry << stream
140+
141+
stream_two.name = name
142+
stream_two.type = type
143+
stream_two.sid = sid
144+
dir_entry << stream_two
145+
expect(dir_entry.find_stream_by_name_and_type(name, type)).to eq(stream)
146+
end
147+
end
148+
end
149+
150+
describe "#find_by_sid" do
151+
let(:stream) { Rex::OLE::Stream.new(storage) }
152+
let(:another_stream) { Rex::OLE::Stream.new(storage) }
153+
154+
context "when self match the criteria" do
155+
it "returns self" do
156+
expect(dir_entry.find_by_sid(0, dir_entry)).to eq(dir_entry)
157+
end
158+
end
159+
160+
context "when self and a children stream match the criteria" do
161+
it "returns self" do
162+
stream.sid = 0
163+
dir_entry << stream
164+
expect(dir_entry.find_by_sid(0, dir_entry)).to eq(dir_entry)
165+
end
166+
end
167+
168+
context "when only one children stream match the criteria" do
169+
it "returns the child stream" do
170+
stream.sid = 20
171+
dir_entry << stream
172+
expect(dir_entry.find_by_sid(20, dir_entry)).to eq(stream)
173+
end
174+
end
175+
176+
context "when several children stream match the criteria" do
177+
it "returns the first child" do
178+
stream.sid = 20
179+
stream.name = 'stream'
180+
dir_entry << stream
181+
another_stream.sid = 20
182+
another_stream.name = 'another'
183+
dir_entry << another_stream
184+
expect(dir_entry.find_by_sid(20, dir_entry)).to eq(stream)
185+
end
186+
end
187+
end
188+
189+
describe "#pack" do
190+
it "returns an string" do
191+
expect(dir_entry.pack).to be_an(String)
192+
end
193+
194+
it "includes the unicode dir entry name" do
195+
expect(dir_entry.pack).to match(/R\x00o\x00o\x00t\x00 \x00E\x00n\x00t\x00r\x00y\x00/)
196+
end
197+
198+
context "when _sectStart is undefined" do
199+
it "sets _sectStart to SECT_END" do
200+
dir_entry.instance_variable_set(:@_sectStart, nil)
201+
dir_entry.pack
202+
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_END)
203+
end
204+
end
205+
206+
context "when _sectStart is defined" do
207+
it "doesn't modify _sectStart value" do
208+
dir_entry.instance_variable_set(:@_sectStart, Rex::OLE::SECT_FREE)
209+
dir_entry.pack
210+
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_FREE)
211+
end
212+
end
213+
214+
it "sets _cb as the unicode length of the name" do
215+
dir_entry.pack
216+
expect(dir_entry.instance_variable_get(:@_cb)).to eq("Root Entry\x00".length * 2)
217+
end
218+
end
219+
220+
describe "#to_s" do
221+
it "returns an string" do
222+
expect(dir_entry.to_s).to be_an(String)
223+
end
224+
225+
it "starts with {" do
226+
expect(dir_entry.to_s).to start_with('{')
227+
end
228+
229+
it "ends with }" do
230+
expect(dir_entry.to_s).to end_with('}')
231+
end
232+
233+
it "contains the entry name" do
234+
expect(dir_entry.to_s).to match(/Root Entry/)
235+
end
236+
237+
context "when _sectStart is undefined" do
238+
it "sets _sectStart to SECT_END" do
239+
dir_entry.instance_variable_set(:@_sectStart, nil)
240+
dir_entry.to_s
241+
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_END)
242+
end
243+
end
244+
245+
context "when _sectStart is defined" do
246+
it "doesn't modify _sectStart value" do
247+
dir_entry.instance_variable_set(:@_sectStart, Rex::OLE::SECT_FREE)
248+
dir_entry.to_s
249+
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_FREE)
250+
end
251+
end
252+
253+
it "sets _cb as the unicode length of the name" do
254+
dir_entry.to_s
255+
expect(dir_entry.instance_variable_get(:@_cb)).to eq("Root Entry\x00".length * 2)
256+
end
257+
end
258+
259+
end

0 commit comments

Comments
 (0)