From 6f281d14ff1c133e01910f3f28384e92f9795d86 Mon Sep 17 00:00:00 2001 From: Richard Ramsden Date: Sun, 6 May 2012 18:52:24 -0700 Subject: [PATCH] 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 --- lib/X11/display.rb | 26 +++++++-------- lib/X11/packet.rb | 80 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/lib/X11/display.rb b/lib/X11/display.rb index d8bd558..4dc86df 100644 --- a/lib/X11/display.rb +++ b/lib/X11/display.rb @@ -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 diff --git a/lib/X11/packet.rb b/lib/X11/packet.rb index 5a10a8c..7a0bf1c 100644 --- a/lib/X11/packet.rb +++ b/lib/X11/packet.rb @@ -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