Add support for Data Block Long
parent
9c5d7e66d4
commit
a68540cfa2
|
@ -4,4 +4,5 @@ require 'rex/java/serialization/model/null_reference'
|
||||||
require 'rex/java/serialization/model/utf'
|
require 'rex/java/serialization/model/utf'
|
||||||
require 'rex/java/serialization/model/long_utf'
|
require 'rex/java/serialization/model/long_utf'
|
||||||
require 'rex/java/serialization/model/block_data'
|
require 'rex/java/serialization/model/block_data'
|
||||||
|
require 'rex/java/serialization/model/block_data_long'
|
||||||
require 'rex/java/serialization/model/field'
|
require 'rex/java/serialization/model/field'
|
|
@ -0,0 +1,55 @@
|
||||||
|
module Rex
|
||||||
|
module Java
|
||||||
|
module Serialization
|
||||||
|
module Model
|
||||||
|
# This class provides a block data (long) representation
|
||||||
|
class BlockDataLong < Element
|
||||||
|
|
||||||
|
# @!attribute length
|
||||||
|
# @return [Integer] the length of the block
|
||||||
|
attr_accessor :length
|
||||||
|
# @!attribute contents
|
||||||
|
# @return [String] the contents of the block
|
||||||
|
attr_accessor :contents
|
||||||
|
|
||||||
|
# @param contents [String] the contents of the block
|
||||||
|
def initialize(contents = '')
|
||||||
|
self.contents = contents
|
||||||
|
self.length = contents.length
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unserializes a Java::Serialization::Model::BlockDataLong
|
||||||
|
#
|
||||||
|
# @param io [IO] the io to read from
|
||||||
|
# @return [self] if deserialization is possible
|
||||||
|
# @return [nil] if deserialization isn't possible
|
||||||
|
def decode(io)
|
||||||
|
raw_length = io.read(4)
|
||||||
|
return nil if raw_length.nil?
|
||||||
|
self.length = raw_length.unpack('N')[0]
|
||||||
|
|
||||||
|
if length == 0
|
||||||
|
self.contents = ''
|
||||||
|
else
|
||||||
|
self.contents = io.read(length)
|
||||||
|
return nil if contents.nil? || contents.length != length
|
||||||
|
end
|
||||||
|
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
# Serializes the Java::Serialization::Model::BlockDataLong
|
||||||
|
#
|
||||||
|
# @return [String] if serialization is possible
|
||||||
|
# @return [nil] if serialization isn't possible
|
||||||
|
def encode
|
||||||
|
encoded = [length].pack('N')
|
||||||
|
encoded << contents
|
||||||
|
|
||||||
|
encoded
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,91 @@
|
||||||
|
require 'rex/java'
|
||||||
|
require 'stringio'
|
||||||
|
|
||||||
|
describe Rex::Java::Serialization::Model::BlockDataLong do
|
||||||
|
subject(:block) do
|
||||||
|
described_class.new
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:sample_block) { "\x00\x00\x00\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" }
|
||||||
|
let(:sample_block_io) { StringIO.new(sample_block) }
|
||||||
|
let(:empty_block) { "\x00\x00\x00\x00" }
|
||||||
|
let(:empty_block_io) { StringIO.new(empty_block) }
|
||||||
|
let(:incomplete_block) { "\x00\x00\x00\x10\x01\x02\x03\x04\x05" }
|
||||||
|
let(:incomplete_block_io) { StringIO.new(incomplete_block) }
|
||||||
|
let(:empty_io) { StringIO.new('') }
|
||||||
|
|
||||||
|
describe ".new" do
|
||||||
|
it "Rex::Java::Serialization::Model::BlockDataLong" do
|
||||||
|
expect(block).to be_a(Rex::Java::Serialization::Model::BlockDataLong)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "initializes length to 0" do
|
||||||
|
expect(block.length).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "initializes contents with empty string" do
|
||||||
|
expect(block.contents).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#encode" do
|
||||||
|
context "when empty block" do
|
||||||
|
it { expect(block.encode).to eq(empty_block) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when filled block" do
|
||||||
|
it do
|
||||||
|
block.length = 16
|
||||||
|
block.contents = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
|
||||||
|
expect(block.encode).to eq(sample_block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#decode" do
|
||||||
|
context "when stream contains empty string" do
|
||||||
|
it "returns nil" do
|
||||||
|
expect(block.decode(empty_io)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when stream contains empty block" do
|
||||||
|
it "returns a Rex::Java::Serialization::Model::BlockDataLong" do
|
||||||
|
expect(block.decode(empty_block_io)).to be_a(Rex::Java::Serialization::Model::BlockDataLong)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets length to 0" do
|
||||||
|
block.decode(empty_block_io)
|
||||||
|
expect(block.length).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets contents to empty string" do
|
||||||
|
block.decode(empty_block_io)
|
||||||
|
expect(block.contents).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when stream contains incomplete block" do
|
||||||
|
it "returns nil" do
|
||||||
|
expect(block.decode(incomplete_block_io)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when stream contains correct block" do
|
||||||
|
|
||||||
|
it "returns a Rex::Java::Serialization::Model::BlockDataLong" do
|
||||||
|
expect(block.decode(sample_block_io)).to be_a(Rex::Java::Serialization::Model::BlockDataLong)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets length to 0" do
|
||||||
|
block.decode(sample_block_io)
|
||||||
|
expect(block.length).to eq(16)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets contents to sample string" do
|
||||||
|
block.decode(sample_block_io)
|
||||||
|
expect(block.contents).to eq("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue