123456789_123456789_123456789_123456789_123456789_

Class: Gem::SafeMarshal::Reader

Relationships & Source Files
Namespace Children
Exceptions:
Inherits: Object
Defined in: lib/rubygems/safe_marshal/reader.rb

Constant Summary

Class Method Summary

Instance Method Summary

Constructor Details

.new(io) ⇒ Reader

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 23

def initialize(io)
  @io = io
end

Instance Method Details

#read!

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 27

def read!
  read_header
  root = read_element
  raise UnconsumedBytesError unless @io.eof?
  root
end

#read_array (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 162

def read_array
  length = read_integer
  return EMPTY_ARRAY if length == 0
  elements = Array.new(length) do
    read_element
  end
  Elements::Array.new(elements)
end

#read_bignum (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 267

def read_bignum
  sign = read_byte
  data = @io.read(read_integer * 2)
  Elements::Bignum.new(sign, data)
end

#read_byte (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 44

def read_byte
  @io.getbyte
end

#read_class (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 277

def read_class
  raise NotImplementedError, "Reading Marshal objects of type class is not implemented"
end

#read_class_or_module (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 285

def read_class_or_module
  raise NotImplementedError, "Reading Marshal objects of type class_or_module is not implemented"
end

#read_data (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 289

def read_data
  raise NotImplementedError, "Reading Marshal objects of type data is not implemented"
end

#read_element (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 82

def read_element
  type = read_byte
  case type
  when 34 then read_string # ?"
  when 48 then read_nil # ?0
  when 58 then read_symbol # ?:
  when 59 then read_symbol_link # ?;
  when 64 then read_object_link # ?@
  when 70 then read_false # ?F
  when 73 then read_object_with_ivars # ?I
  when 84 then read_true # ?T
  when 85 then read_user_marshal # ?U
  when 91 then read_array # ?[
  when 102 then read_float # ?f
  when 105 then Elements::Integer.new(read_integer) # ?i
  when 108 then read_bignum # ?l
  when 111 then read_object # ?o
  when 117 then read_user_defined # ?u
  when 123 then read_hash # ?{
  when 125 then read_hash_with_default_value # ?}
  when 101 then read_extended_object # ?e
  when 99 then read_class # ?c
  when 109 then read_module # ?m
  when 77 then read_class_or_module # ?M
  when 100 then read_data # ?d
  when 47 then read_regexp # ?/
  when 83 then read_struct # ?S
  when 67 then read_user_class # ?C
  when nil
    raise EOFError, "Unexpected EOF"
  else
    raise Error, "Unknown marshal type discriminator #{type.chr.inspect} (#{type})"
  end
end

#read_extended_object (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 273

def read_extended_object
  raise NotImplementedError, "Reading Marshal objects of type extended_object is not implemented"
end

#read_false (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 149

def read_false
  Elements::False::FALSE
end

#read_float (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 262

def read_float
  string = @io.read(read_integer)
  Elements::Float.new(string)
end

#read_hash (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 232

def read_hash
  length = read_integer
  return EMPTY_HASH if length == 0
  pairs = Array.new(length) do
    [read_element, read_element]
  end
  Elements::Hash.new(pairs)
end

#read_hash_with_default_value (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 241

def read_hash_with_default_value
  pairs = Array.new(read_integer) do
    [read_element, read_element]
  end
  default = read_element
  Elements::HashWithDefaultValue.new(pairs, default)
end

#read_header (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 39

def read_header
  v = @io.read(2)
  raise UnsupportedVersionError, "Unsupported marshal version #{v.bytes.map(&:ord).join(".")}, expected #{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" unless v == MARSHAL_VERSION
end

#read_integer (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 48

def read_integer
  b = read_byte

  case b
  when 0x00
    0
  when 0x01
    read_byte
  when 0x02
    read_byte | (read_byte << 8)
  when 0x03
    read_byte | (read_byte << 8) | (read_byte << 16)
  when 0x04
    read_byte | (read_byte << 8) | (read_byte << 16) | (read_byte << 24)
  when 0xFC
    read_byte | (read_byte << 8) | (read_byte << 16) | (read_byte << 24) | -0x100000000
  when 0xFD
    read_byte | (read_byte << 8) | (read_byte << 16) | -0x1000000
  when 0xFE
    read_byte | (read_byte << 8) | -0x10000
  when 0xFF
    read_byte | -0x100
  when nil
    raise EOFError, "Unexpected EOF"
  else
    signed = (b ^ 128) - 128
    if b >= 128
      signed + 5
    else
      signed - 5
    end
  end
end

#read_module (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 281

def read_module
  raise NotImplementedError, "Reading Marshal objects of type module is not implemented"
end

#read_nil (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 258

def read_nil
  Elements::Nil::NIL
end

#read_object (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 249

def read_object
  name = read_element
  object = Elements::Object.new(name)
  ivars = Array.new(read_integer) do
    [read_element, read_element]
  end
  Elements::WithIvars.new(object, ivars)
end

#read_object_with_ivars (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 171

def read_object_with_ivars
  object = read_element
  ivars = Array.new(read_integer) do
    [read_element, read_element]
  end
  Elements::WithIvars.new(object, ivars)
end

#read_regexp (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 293

def read_regexp
  raise NotImplementedError, "Reading Marshal objects of type regexp is not implemented"
end

#read_string (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 138

def read_string
  length = read_integer
  return EMPTY_STRING if length == 0
  str = @io.read(length)
  Elements::String.new(str)
end

#read_struct (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 297

def read_struct
  raise NotImplementedError, "Reading Marshal objects of type struct is not implemented"
end

#read_symbol (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 120

def read_symbol
  len = read_integer
  if len == 1
    byte = read_byte
    if byte == 69 # ?E
      STRING_E_SYMBOL
    else
      Elements::Symbol.new(byte.chr)
    end
  else
    name = -@io.read(len)
    Elements::Symbol.new(name)
  end
end

#read_true (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 145

def read_true
  Elements::True::TRUE
end

#read_user_class (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 301

def read_user_class
  name = read_element
  wrapped_object = read_element
  Elements::UserClass.new(name, wrapped_object)
end

#read_user_defined (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 153

def read_user_defined
  name = read_element
  binary_string = @io.read(read_integer)
  Elements::UserDefined.new(name, binary_string)
end

#read_user_marshal (private)

[ GitHub ]

  
# File 'lib/rubygems/safe_marshal/reader.rb', line 184

def read_user_marshal
  name = read_element
  data = read_element
  Elements::UserMarshal.new(name, data)
end