2014-10-28 21:45:21 +00:00
|
|
|
# -*- coding:binary -*-
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
require 'rex/ole'
|
|
|
|
|
|
|
|
describe Rex::OLE::DIFAT do
|
2014-11-04 16:39:42 +00:00
|
|
|
before(:each) do
|
|
|
|
Rex::OLE::Util.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
|
|
|
end
|
2014-10-28 21:45:21 +00:00
|
|
|
|
|
|
|
let(:storage) do
|
|
|
|
Rex::OLE::Storage.new
|
|
|
|
end
|
|
|
|
|
|
|
|
subject(:difat) do
|
|
|
|
described_class.new(storage)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe ".new" do
|
|
|
|
it "returns a Rex::OLE::DIFAT instance" do
|
|
|
|
expect(described_class.new(storage)).to be_a(Rex::OLE::DIFAT)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "initializes @stg" do
|
|
|
|
expect(difat.instance_variable_get(:@stg)).to eq(storage)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "initializes @entries" do
|
|
|
|
expect(difat.instance_variable_get(:@entries)).to be_an(Array)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "initializes @entries as empty array" do
|
|
|
|
expect(difat.instance_variable_get(:@entries)).to be_empty
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#[]=" do
|
|
|
|
context "when the entry doesn't exist" do
|
|
|
|
it "sets an element in the @entries array" do
|
|
|
|
difat[0] = 1
|
|
|
|
expect(difat.instance_variable_get(:@entries)[0]).to eq(1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when the entry exists" do
|
|
|
|
it "replaces the element in the @entries array" do
|
|
|
|
difat[0] = 1
|
|
|
|
difat[0] = 2
|
|
|
|
expect(difat.instance_variable_get(:@entries)[0]).to eq(2)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#[]" do
|
|
|
|
context "when the entry doesn't exist" do
|
|
|
|
it "returns nil" do
|
|
|
|
expect(difat[3]).to eq(nil)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when the entry exists" do
|
|
|
|
it "returns the entry value" do
|
|
|
|
difat[3] = 31
|
|
|
|
expect(difat[3]).to eq(31)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
describe "#+" do
|
|
|
|
context "when @entries is empty" do
|
|
|
|
it "sets the @entries values" do
|
|
|
|
difat + [1, 2]
|
|
|
|
expect(difat.instance_variable_get(:@entries)).to eq([1, 2])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when @entries isn't empty" do
|
|
|
|
it "concatenates the array to @entries" do
|
|
|
|
difat[2] = 0
|
|
|
|
difat + [1, 2]
|
|
|
|
expect(difat.instance_variable_get(:@entries)).to eq([nil, nil, 0, 1, 2])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#<<" do
|
|
|
|
it "concatenates the element to the @entries array" do
|
|
|
|
difat[0] = 1
|
|
|
|
difat << 3
|
|
|
|
expect(difat.instance_variable_get(:@entries)).to eq([1, 3])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#length" do
|
2014-11-03 15:23:26 +00:00
|
|
|
subject(:difat_length) do
|
|
|
|
difat.length
|
|
|
|
end
|
|
|
|
|
2014-10-28 21:45:21 +00:00
|
|
|
context "when @entries is empty" do
|
|
|
|
it "returns 0" do
|
2014-11-03 15:23:26 +00:00
|
|
|
is_expected.to eq(0)
|
2014-10-28 21:45:21 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when @entries isn't empty" do
|
|
|
|
it "returns the @entries length" do
|
|
|
|
difat[0] = 1
|
|
|
|
difat[1] = 2
|
2014-11-03 15:23:26 +00:00
|
|
|
is_expected.to eq(2)
|
2014-10-28 21:45:21 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#slice!" do
|
|
|
|
context "when @entries is empty" do
|
|
|
|
it "returns empty array" do
|
|
|
|
expect(difat.slice!(0, 1)).to eq([])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when start is out of range" do
|
|
|
|
it "returns nil" do
|
|
|
|
difat[0] = 1
|
|
|
|
expect(difat.slice!(10, 1)).to eq(nil)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when stop is 0" do
|
|
|
|
it "returns empty array" do
|
|
|
|
difat[0] = 1
|
|
|
|
expect(difat.slice!(0, 0)).to eq([])
|
|
|
|
end
|
|
|
|
|
|
|
|
it "doesn't delete nothing" do
|
|
|
|
difat[0] = 1
|
|
|
|
difat.slice!(0, 0)
|
|
|
|
expect(difat[0]).to eq(1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when @entries is long enough" do
|
|
|
|
it "returns the deleted elements" do
|
|
|
|
difat + [1, 2]
|
|
|
|
expect(difat.slice!(0, 1)).to eq([1])
|
|
|
|
end
|
|
|
|
|
|
|
|
it "deletes the elements in the range" do
|
|
|
|
difat + [1, 2]
|
|
|
|
difat.slice!(0, 1)
|
|
|
|
expect(difat.instance_variable_get(:@entries)).to eq([2])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#reset" do
|
|
|
|
it "resets the @entries array" do
|
|
|
|
difat[0] = 1
|
|
|
|
difat.reset
|
|
|
|
expect(difat.length).to eq(0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#each" do
|
|
|
|
it "calls the block for every @entries element" do
|
|
|
|
difat + [1, 2, 3]
|
|
|
|
res = 0
|
|
|
|
difat.each { |elem| res += elem}
|
|
|
|
expect(res).to eq(1 + 2 + 3)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#to_s" do
|
2014-11-03 15:23:26 +00:00
|
|
|
subject(:difat_string) do
|
|
|
|
difat.to_s
|
|
|
|
end
|
|
|
|
|
2014-10-28 21:45:21 +00:00
|
|
|
it "returns an String" do
|
2014-11-03 15:23:26 +00:00
|
|
|
is_expected.to be_an(String)
|
2014-10-28 21:45:21 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it "starts with {" do
|
2014-11-03 15:23:26 +00:00
|
|
|
is_expected.to start_with('{')
|
2014-10-28 21:45:21 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it "ends with }" do
|
2014-11-03 15:23:26 +00:00
|
|
|
is_expected.to end_with('}')
|
2014-10-28 21:45:21 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it "contains @entries values" do
|
|
|
|
difat + [Rex::OLE::SECT_FAT, 1, 2, 3, Rex::OLE::SECT_DIF, Rex::OLE::SECT_FREE, Rex::OLE::SECT_END]
|
2014-11-03 15:23:26 +00:00
|
|
|
is_expected.to match(/FAT, 0x1, 0x2, 0x3, DIF, FREE, END/)
|
2014-10-28 21:45:21 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#read" do
|
2014-11-03 15:23:26 +00:00
|
|
|
context "when difat is empty" do
|
|
|
|
it "returns nil" do
|
|
|
|
expect(difat.read).to be_nil
|
|
|
|
end
|
|
|
|
end
|
2014-10-28 21:45:21 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "#write" do
|
2014-11-03 15:23:26 +00:00
|
|
|
context "when entries is empty" do
|
|
|
|
it "returns 0" do
|
|
|
|
expect(difat.write).to eq(0)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fills the first 109 FAT sectors in the storage header" do
|
|
|
|
difat.write
|
|
|
|
storage = difat.instance_variable_get(:@stg)
|
|
|
|
expect(storage.header._sectFat.length).to eq(109)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fills the first 109 FAT sectors in the storage header with SECT_FREE" do
|
|
|
|
difat.write
|
|
|
|
storage = difat.instance_variable_get(:@stg)
|
|
|
|
storage.header._sectFat.each { |s|
|
|
|
|
expect(s).to eq(Rex::OLE::SECT_FREE)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when entries length is less than 109" do
|
|
|
|
let(:entries) { [1] * 20 }
|
|
|
|
|
|
|
|
it "returns the number of entries" do
|
|
|
|
difat + entries
|
|
|
|
expect(difat.write).to eq(20)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fills the first 109 FAT sectors in the storage header" do
|
|
|
|
difat + entries
|
|
|
|
difat.write
|
|
|
|
storage = difat.instance_variable_get(:@stg)
|
|
|
|
expect(storage.header._sectFat.length).to eq(109)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fills the first FAT sectors with the entries" do
|
|
|
|
difat + entries
|
|
|
|
difat.write
|
|
|
|
storage = difat.instance_variable_get(:@stg)
|
|
|
|
(0..entries.length - 1).each { |i|
|
|
|
|
expect(storage.header._sectFat[i]).to eq(1)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fills the remaining FAT sectors with FREE sectors" do
|
|
|
|
difat + entries
|
|
|
|
difat.write
|
|
|
|
storage = difat.instance_variable_get(:@stg)
|
|
|
|
(entries.length..109 - 1).each { |i|
|
|
|
|
expect(storage.header._sectFat[i]).to eq(Rex::OLE::SECT_FREE)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when entries length is 109" do
|
|
|
|
let(:entries) { [1] * 109 }
|
|
|
|
|
|
|
|
it "returns the number of entries" do
|
|
|
|
difat + entries
|
|
|
|
expect(difat.write).to eq(109)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fills the first 109 FAT sectors in the storage header" do
|
|
|
|
difat + entries
|
|
|
|
difat.write
|
|
|
|
storage = difat.instance_variable_get(:@stg)
|
|
|
|
expect(storage.header._sectFat.length).to eq(109)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fills the first 109 FAT sectors with the entries" do
|
|
|
|
difat + entries
|
|
|
|
difat.write
|
|
|
|
storage = difat.instance_variable_get(:@stg)
|
|
|
|
(0..storage.header._sectFat.length - 1).each { |i|
|
|
|
|
expect(storage.header._sectFat[i]).to eq(1)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when entries length is greater than 109" do
|
|
|
|
let(:entries) { [1] * 110 }
|
|
|
|
|
|
|
|
it "raises a RuntimeError" do
|
|
|
|
difat + entries
|
|
|
|
expect { difat.write }.to raise_error(RuntimeError)
|
|
|
|
end
|
|
|
|
end
|
2014-10-28 21:45:21 +00:00
|
|
|
|
|
|
|
end
|
|
|
|
end
|