Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

497 lines (394 sloc) 10.858 kb
require 'spec_helper'
require 'ronin/binary/struct'
describe Binary::Struct do
describe "layout" do
subject do
struct = Class.new(described_class)
struct.class_eval do
layout :x, :uint,
:y, :uint
end
struct.new
end
it "should return the layout" do
subject.class.layout.should == [
:x,
:y
]
end
context "when given fields" do
it "should populate fields" do
subject.class.fields.should == {
:x => [:uint, nil],
:y => [:uint, nil]
}
end
it "should define reader methods" do
subject.should respond_to(:x)
subject.should respond_to(:y)
end
it "should define writer methods" do
subject.should respond_to(:x=)
subject.should respond_to(:y=)
end
end
end
describe "field?" do
subject do
struct = Class.new(described_class)
struct.class_eval { layout :x, :uint }
struct
end
it "should determine if fields exist" do
subject.field?(:x).should == true
subject.field?(:foo).should == false
end
end
describe "endian" do
subject do
struct = Class.new(described_class)
struct.class_eval { endian :little }
struct
end
it "should return the endianness of the Struct" do
subject.endian.should == :little
end
context "when given an argument" do
it "should set the endianness" do
subject.endian :big
subject.endian.should == :big
end
end
end
describe "typedefs" do
end
describe "typedef" do
subject do
struct = Class.new(described_class)
struct.class_eval do
typedef :uint32_t, :test_t
end
struct
end
it "should register a new type in typedefs" do
subject.typedefs.should have_key(:test_t)
end
it "should resolve the existing type" do
subject.typedefs[:test_t].should == :uint32
end
end
describe "#initialize" do
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :uint
end
layout :int, :uint,
:int_array, [:uint, 2],
:float, :float,
:float_array, [:float, 2],
:char, :char,
:char_array, [:char, 2],
:string, :string,
:struct, nested_struct,
:struct_array, [nested_struct, 2]
end
struct.new
end
it "should set integers to 0" do
subject[:int].should == 0
end
it "should set arrays of integers to [0, ...]" do
subject[:int_array].should == [0, 0]
end
it "should set floats to 0.0" do
subject[:float].should == 0.0
end
it "should set arrays of floats to [0.0, ...]" do
subject[:float_array].should == [0.0, 0.0]
end
it "should set chars to '\\0'" do
subject[:char].should == "\0"
end
it "should set arrays of chars to ''" do
subject[:char_array].should == ''
end
it "should set strings to ''" do
subject[:string].should == ''
end
it "should initialize nested structs" do
subject[:struct][:int].should == 0
end
it "should initialize arrays of nested structs" do
subject[:struct_array][0][:int].should == 0
subject[:struct_array][1][:int].should == 0
end
end
describe "#[]" do
subject do
struct = Class.new(described_class)
struct.class_eval do
layout :x, :uint,
:y, :uint
end
struct.new
end
before(:all) do
subject.instance_variable_set('@x',10)
end
it "should access the instance variable" do
subject[:x].should == 10
end
it "should still call the underlying reader method" do
subject.should_receive(:x).and_return(10)
subject[:x]
end
it "should raise ArgumentError for unknown fields" do
lambda {
subject[:foo]
}.should raise_error(ArgumentError)
end
end
describe "#[]=" do
subject do
struct = Class.new(described_class)
struct.class_eval do
layout :x, :uint,
:y, :uint
end
struct.new
end
before(:each) do
subject.instance_variable_set('@x',0)
end
it "should set the underlying instance variable" do
subject[:x] = 20
subject.instance_variable_get('@x').should == 20
end
it "should still call the underlying writer method" do
subject.should_receive(:x=).with(20)
subject[:x] = 20
end
it "should raise ArgumentError for unknown fields" do
lambda {
subject[:foo] = 20
}.should raise_error(ArgumentError)
end
end
describe "#values" do
let(:x) { 10 }
let(:y) { 20 }
subject do
struct = Class.new(described_class)
struct.class_eval do
layout :x, :uint,
:y, :uint
end
struct.new
end
before(:each) do
subject.x = x
subject.y = y
end
it "should return the values of the fields" do
subject.values.should == [x, y]
end
context "nested structs" do
let(:z) { 30 }
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :uint
end
layout :x, :uint,
:y, :uint,
:z, nested_struct
end
struct.new
end
before(:each) do
subject.z.int = z
end
it "should nest the values of nested structs" do
subject.values.should == [x, y, [z]]
end
end
context "arrays of nested structs" do
let(:z) { 30 }
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :uint
end
layout :x, :uint,
:y, :uint,
:z, [nested_struct, 2]
end
struct.new
end
before(:each) do
subject.z[0].int = z
subject.z[1].int = z
end
it "should nest the values of nested structs" do
subject.values.should == [x, y, [[z], [z]]]
end
end
end
describe "#clear" do
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :int
end
layout :x, :uint,
:y, :float,
:z, nested_struct
end
struct.new
end
before(:all) do
subject.x = 100
subject.y = 15.0
subject.z.int = -1
subject.clear
end
it "should reset fields to their default values" do
subject.x.should == 0
subject.y.should == 0.0
end
it "should reinitialize nested structs" do
subject.z.int.should == 0
end
end
describe "#pack" do
context "arrays of chars" do
let(:string) { "hello" }
let(:packed) { string.ljust(10,"\0") }
subject do
struct = Class.new(described_class)
struct.class_eval do
layout :chars, [:char, 10]
end
struct.new
end
before(:each) do
subject.chars = string
end
it "should pack arrays of chars into a String" do
subject.pack.should == packed
end
end
context "structs" do
let(:packed) { "\x0a\x00\x14\x00\x00\x00" }
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :uint32_le
end
layout :int, :uint16_le,
:struct, nested_struct
end
struct.new
end
before(:each) do
subject.int = 10
subject.struct.int = 20
end
it "should pack the nested struct fields" do
subject.pack.should == packed
end
end
context "arrays of structs" do
let(:packed) { "\x0a\x00\x14\x00\x00\x00\x1e\x00\x00\x00" }
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :uint32_le
end
layout :int, :uint16_le,
:struct, [nested_struct, 2]
end
struct.new
end
before(:each) do
subject.int = 10
subject.struct[0].int = 20
subject.struct[1].int = 30
end
it "should pack the nested fields" do
subject.pack.should == packed
end
end
end
describe "#unpack" do
context "arrays of chars" do
let(:string) { "hello" }
let(:packed) { string.ljust(10,"\0") }
subject do
struct = Class.new(described_class)
struct.class_eval do
layout :chars, [:char, 10]
end
struct.new
end
it "should unpack arrays of chars into a String" do
subject.unpack(packed)
subject.chars.should == string
end
end
context "structs" do
let(:packed) { "\x0a\x00\x14\x00\x00\x00" }
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :uint32_le
end
layout :int, :uint16_le,
:struct, nested_struct
end
struct.new
end
it "should unpack the nested struct fields" do
subject.unpack(packed)
subject.int.should == 10
subject.struct.int.should == 20
end
end
context "arrays of structs" do
let(:packed) { "\x0a\x00\x14\x00\x00\x00\x1e\x00\x00\x00" }
subject do
struct = Class.new(described_class)
struct.class_eval do
nested_struct = Class.new(Ronin::Binary::Struct)
nested_struct.class_eval do
layout :int, :uint32_le
end
layout :int, :uint16_le,
:struct, [nested_struct, 2]
end
struct.new
end
it "should unpack the nested fields" do
subject.unpack(packed)
subject.int.should == 10
subject.struct[0].int.should == 20
subject.struct[1].int.should == 30
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.