We dont need to pass lengths of strings

Instead of manually passing lengths of strings
we can check the length of the parameter
passed in when we construct the packet
This commit is contained in:
Richard Ramsden 2012-05-06 18:52:24 -07:00
parent bbc950ae39
commit 6f281d14ff
2 changed files with 71 additions and 35 deletions

View file

@ -24,7 +24,7 @@ module X11
authorize(host, family, display_id)
end
private
private
def authorize(host, family, display_id)
auth_info = Auth.new.get_by_hostname(host||"localhost", family, display_id)
@ -34,8 +34,6 @@ private
Protocol::BYTE_ORDER,
Protocol::MAJOR,
Protocol::MINOR,
auth_name.length,
auth_data.length,
auth_name,
auth_data
)
@ -43,17 +41,17 @@ private
@socket.write(handshake)
case @socket.read(1).unpack("w").first
when X11::Auth::FAILED
len, major, minor, xlen = @socket.read(7).unpack("CSSS")
reason = @socket.read(xlen * 4)
reason = reason[0..len]
raise AuthorizationError, "Connection to server failed -- (version #{major}.#{minor}) #{reason}"
when X11::Auth::AUTHENTICATE
raise AuthorizationError, "Connection requires authentication"
when X11::Auth::SUCCESS
puts "CONNECTION SUCCESS"
else
raise AuthorizationError, "Received unknown opcode #{type}"
when X11::Auth::FAILED
len, major, minor, xlen = @socket.read(7).unpack("CSSS")
reason = @socket.read(xlen * 4)
reason = reason[0..len]
raise AuthorizationError, "Connection to server failed -- (version #{major}.#{minor}) #{reason}"
when X11::Auth::AUTHENTICATE
raise AuthorizationError, "Connection requires authentication"
when X11::Auth::SUCCESS
puts "SUCCESS"
else
raise AuthorizationError, "Received unknown opcode #{type}"
end
end

View file

@ -2,22 +2,61 @@ module X11
module Packet
class BasePacket
include X11::Encode
@@fields = []
# Takes a list of ruby objects and encodes them
# to binary data-types defined in X11::Encode
def self.create(*values)
@@fields.map do |name, type|
if :static == name
type
else
type.call(values.shift)
@@struct = []
class << self
def create(*values)
lengths = lengths_for(values)
packet = @@struct.map do |tuple|
type, name, encode_fun = tuple
case type
when :field
encode_fun.call(values.shift)
when :length
encode_fun.call(lengths[name])
when :unused
name
end
end
end.join
end
packet.join
end
def field(name, encode_fun)
@@struct.push([:field, name, encode_fun])
end
def unused(size)
@@struct.push([:unused, "\x00" * size])
end
def length(name, encode_fun)
@@struct.push([:length, name, encode_fun])
end
private
def lengths_for(args)
args = args.dup
lengths = {}
fields.each do |type, name, klass|
value = args.shift
lengths[name] = value.size if value.is_a?(String)
end
return lengths
end
def fields
@@struct.dup.delete_if do |type,name,klass|
type == :unused or type == :length
end
end
def self.field(name, type)
@@fields.push([name, type])
end
end
@ -36,16 +75,15 @@ module X11
# p unused, p=pad(n)
# d STRING8 authorization-protocol-data
# q unused, q=pad(d)
#
class ClientHandshake < BasePacket
field :byte_order, Uint8
field :static, "\x00"
field :proto_version_major, Uint16
field :proto_version_minor, Uint16
field :auth_proto_name_length, Uint16
field :auth_proto_data_length, Uint16
field :static, "\x00"
field :static, "\x00"
unused 1
field :protocol_major_version, Uint16
field :protocol_minor_version, Uint16
length :auth_proto_name, Uint16
length :auth_proto_data, Uint16
unused 1
field :auth_proto_name, String8
field :auth_proto_data, String8
end