metasploit-framework/spec/lib/rex/ole/direntry_spec.rb

260 lines
7.8 KiB
Ruby
Raw Normal View History

2014-11-03 21:31:12 +00:00
# -*- coding:binary -*-
require 'spec_helper'
require 'rex/ole'
describe Rex::OLE::DirEntry do
let(:storage) do
Rex::OLE::Storage.new
end
subject(:dir_entry) do
described_class.new(storage)
end
describe ".new" do
it "returns a Rex::OLE::DirEntry instance" do
expect(described_class.new(storage)).to be_a(Rex::OLE::DirEntry)
end
it { expect(dir_entry.instance_variable_get(:@stg)).to eq(storage) }
it { expect(dir_entry.sid).to eq(0) }
it { expect(dir_entry.instance_variable_get(:@_ab)).to eq('Root Entry') }
it { expect(dir_entry.instance_variable_get(:@_cb)).to be_nil }
it { expect(dir_entry.instance_variable_get(:@_mse)).to eq(Rex::OLE::STGTY_ROOT) }
it { expect(dir_entry.instance_variable_get(:@_bflags)).to eq(0) }
it { expect(dir_entry._sidLeftSib).to eq(Rex::OLE::SECT_FREE) }
it { expect(dir_entry._sidRightSib).to eq(Rex::OLE::SECT_FREE) }
it { expect(dir_entry._sidChild).to eq(Rex::OLE::SECT_FREE) }
it { expect(dir_entry.instance_variable_get(:@_clsId)).to be_a(Rex::OLE::CLSID) }
it { expect(dir_entry.instance_variable_get(:@_dwUserFlags)).to eq(0) }
it { expect(dir_entry.instance_variable_get(:@_ctime)).to eq("\x00" * 8) }
it { expect(dir_entry.instance_variable_get(:@_mtime)).to eq("\x00" * 8) }
it { expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_END) }
it { expect(dir_entry.instance_variable_get(:@_ulSize)).to eq(0) }
it { expect(dir_entry.instance_variable_get(:@children)).to be_an(Array) }
it { expect(dir_entry.instance_variable_get(:@children)).to be_empty }
end
describe "#length" do
it "returns _ulSize" do
dir_entry.instance_variable_set(:@_ulSize, 28)
expect(dir_entry.length).to eq(28)
end
end
describe "#<<" do
it "increments the children array" do
dir_entry << 1
children = dir_entry.instance_variable_get(:@children)
expect(children.length).to eq(1)
end
it "appends to the children array" do
dir_entry << 1
children = dir_entry.instance_variable_get(:@children)
expect(children).to eq([1])
end
end
describe "#each" do
it "calls the block for every children element" do
dir_entry << 1
dir_entry << 2
dir_entry << 3
res = 0
dir_entry.each { |elem| res += elem}
expect(res).to eq(1 + 2 + 3)
end
end
describe "#type" do
it "returns the _mse field" do
expect(dir_entry.type).to eq(Rex::OLE::STGTY_ROOT)
end
end
describe "#type=" do
it "modifies the _mse field" do
dir_entry.type = 3838
expect(dir_entry.instance_variable_get(:@_mse)).to eq(3838)
end
end
describe "#name" do
it "returns the _ab field" do
expect(dir_entry.name).to eq('Root Entry')
end
end
describe "#name=" do
it "modifies the _ab field" do
dir_entry.name = 'test'
expect(dir_entry.instance_variable_get(:@_ab)).to eq('test')
end
end
describe "#start_sector" do
it "returns the _sectStart field" do
expect(dir_entry.start_sector).to eq(Rex::OLE::SECT_END)
end
end
describe "#start_sector=" do
it "modifies the _sectStart field" do
dir_entry.start_sector = Rex::OLE::SECT_FREE
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_FREE)
end
end
describe "#find_stream_by_name_and_type" do
context "when any children matches the search criteria" do
it "returns nil" do
expect(dir_entry.find_stream_by_name_and_type('name', Rex::OLE::STGTY_ROOT)).to be_nil
end
end
context "when one children matches the search criteria" do
let(:stream) { Rex::OLE::Stream.new(storage) }
let(:name) { 'name' }
let(:type) { Rex::OLE::STGTY_ROOT }
it "returns the matching stream" do
stream.name = name
stream.type = type
dir_entry << stream
expect(dir_entry.find_stream_by_name_and_type(name, type)).to eq(stream)
end
end
context "when several children matches the search criteria" do
let(:stream) { Rex::OLE::Stream.new(storage) }
let(:stream_two) { Rex::OLE::Stream.new(storage) }
let(:name) { 'name' }
let(:type) { Rex::OLE::STGTY_ROOT }
let(:sid) { 2 }
it "returns the first matching stream" do
stream.name = name
stream.type = type
dir_entry << stream
stream_two.name = name
stream_two.type = type
stream_two.sid = sid
dir_entry << stream_two
expect(dir_entry.find_stream_by_name_and_type(name, type)).to eq(stream)
end
end
end
describe "#find_by_sid" do
let(:stream) { Rex::OLE::Stream.new(storage) }
let(:another_stream) { Rex::OLE::Stream.new(storage) }
context "when self match the criteria" do
it "returns self" do
expect(dir_entry.find_by_sid(0, dir_entry)).to eq(dir_entry)
end
end
context "when self and a children stream match the criteria" do
it "returns self" do
stream.sid = 0
dir_entry << stream
expect(dir_entry.find_by_sid(0, dir_entry)).to eq(dir_entry)
end
end
context "when only one children stream match the criteria" do
it "returns the child stream" do
stream.sid = 20
dir_entry << stream
expect(dir_entry.find_by_sid(20, dir_entry)).to eq(stream)
end
end
context "when several children stream match the criteria" do
it "returns the first child" do
stream.sid = 20
stream.name = 'stream'
dir_entry << stream
another_stream.sid = 20
another_stream.name = 'another'
dir_entry << another_stream
expect(dir_entry.find_by_sid(20, dir_entry)).to eq(stream)
end
end
end
describe "#pack" do
it "returns an string" do
expect(dir_entry.pack).to be_an(String)
end
it "includes the unicode dir entry name" do
expect(dir_entry.pack).to match(/R\x00o\x00o\x00t\x00 \x00E\x00n\x00t\x00r\x00y\x00/)
end
context "when _sectStart is undefined" do
it "sets _sectStart to SECT_END" do
dir_entry.instance_variable_set(:@_sectStart, nil)
dir_entry.pack
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_END)
end
end
context "when _sectStart is defined" do
it "doesn't modify _sectStart value" do
dir_entry.instance_variable_set(:@_sectStart, Rex::OLE::SECT_FREE)
dir_entry.pack
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_FREE)
end
end
it "sets _cb as the unicode length of the name" do
dir_entry.pack
expect(dir_entry.instance_variable_get(:@_cb)).to eq("Root Entry\x00".length * 2)
end
end
describe "#to_s" do
it "returns an string" do
expect(dir_entry.to_s).to be_an(String)
end
it "starts with {" do
expect(dir_entry.to_s).to start_with('{')
end
it "ends with }" do
expect(dir_entry.to_s).to end_with('}')
end
it "contains the entry name" do
expect(dir_entry.to_s).to match(/Root Entry/)
end
context "when _sectStart is undefined" do
it "sets _sectStart to SECT_END" do
dir_entry.instance_variable_set(:@_sectStart, nil)
dir_entry.to_s
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_END)
end
end
context "when _sectStart is defined" do
it "doesn't modify _sectStart value" do
dir_entry.instance_variable_set(:@_sectStart, Rex::OLE::SECT_FREE)
dir_entry.to_s
expect(dir_entry.instance_variable_get(:@_sectStart)).to eq(Rex::OLE::SECT_FREE)
end
end
it "sets _cb as the unicode length of the name" do
dir_entry.to_s
expect(dir_entry.instance_variable_get(:@_cb)).to eq("Root Entry\x00".length * 2)
end
end
end