1. Gem::
  2. SafeMarshal::
  3. Visitors::
  4. ToRuby

class Gem::SafeMarshal::Visitors::ToRuby

Constants

COMPAT_CLASSES

Public Class Methods

Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 8definitialize(permitted_classes:,permitted_symbols:,permitted_ivars:)@permitted_classes =permitted_classes@permitted_symbols = ["E"].concat(permitted_symbols).concat(permitted_classes)@permitted_ivars =permitted_ivars@objects = []@symbols = []@class_cache = {}@stack = ["root"]@stack_idx =1end

Public Instance Methods

Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 26defvisit(target)stack_idx =@stack_idxsuperensure@stack_idx =stack_idx-1end
Calls superclass method

Private Instance Methods

Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 357defcall_method(receiver,method,*args)receiver.__send__(method,*args)rescueNoMethodError=>eraiseunlesse.receiver==receiverraiseMethodCallError,"Unable to call #{method.inspect} on #{receiver.inspect}, perhaps it is a class using marshal compat, which is not visible in ruby? #{e}"end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 365defformatted_stackformatted = []@stack[0,@stack_idx].eachdo|e|ife.is_a?(Integer)ifformatted.last=="ivar_"formatted[-1] ="ivar_#{e}"elseformatted<<"[#{e}]"endelseformatted<<eendendformattedend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 63defmap_ivars(klass,ivars)stack_idx =@stack_idxivars.map.with_indexdo|(k,v),i|@stack_idx =stack_idxpush_stack"ivar_"push_stackik =resolve_ivar(klass,k)@stack_idx =stack_idxpush_stackknextk,visit(v)endend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 35defpush_stack(element)@stack[@stack_idx] =element@stack_idx+=1end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 352defregister_object(o)@objects<<ooend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 281defresolve_class(n)@class_cache[n]||=beginto_s =resolve_symbol_name(n)raiseUnpermittedClassError.new(name:to_s,stack:formatted_stack)unless@permitted_classes.include?(to_s)visit_symbol_type(n)begin::Object.const_get(to_s)rescueNameErrorraiseArgumentError,"Undefined class #{to_s.inspect}"endendend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 308defresolve_ivar(klass,name)to_s =resolve_symbol_name(name)raiseUnpermittedIvarError.new(symbol:to_s,klass:klass,stack:formatted_stack)unless@permitted_ivars.fetch(klass.name, [].freeze).include?(to_s)visit_symbol_type(name)end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 329defresolve_symbol_name(element)caseelementwhenElements::Symbolelement.namewhenElements::SymbolLinkvisit_Gem_SafeMarshal_Elements_SymbolLink(element).nameelseraiseFormatError,"Expected symbol or symbol link, got #{element.inspect} @ #{formatted_stack.join(".")}"endend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 40defvisit_Gem_SafeMarshal_Elements_Array(a)array =register_object([])elements =a.elementssize =elements.sizeidx =0# not idiomatic, but there's a huge number of IMEMOs allocated here, so we avoid the block# because this is such a hot path when doing a bundle install with the full indexwhileidx<sizepush_stackidxarray<<visit(elements[idx])idx+=1endarrayend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 241defvisit_Gem_SafeMarshal_Elements_Bignum(b)result =0b.data.each_byte.with_indexdo|byte,exp|result+= (byte*2**(exp*8))endcaseb.signwhen43# ?+resultwhen45# ?--resultelseraiseFormatError,"Unexpected sign for Bignum #{b.sign.chr.inspect} (#{b.sign})"endend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 218defvisit_Gem_SafeMarshal_Elements_False(_)falseend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 226defvisit_Gem_SafeMarshal_Elements_Float(f)register_object(casef.stringwhen"inf"::Float::INFINITYwhen"-inf"-::Float::INFINITYwhen"nan"::Float::NANelsef.string.to_fend  )end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 154defvisit_Gem_SafeMarshal_Elements_Hash(o)hash =register_object({})o.pairs.each_with_indexdo|(k,v),i|push_stackik =visit(k)push_stackkhash[k] =visit(v)endhashend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 167defvisit_Gem_SafeMarshal_Elements_HashWithDefaultValue(o)hash =visit_Gem_SafeMarshal_Elements_Hash(o)push_stack:defaulthash.default =visit(o.default)hashend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 206defvisit_Gem_SafeMarshal_Elements_Integer(i)i.intend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 210defvisit_Gem_SafeMarshal_Elements_Nil(_)nilend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 174defvisit_Gem_SafeMarshal_Elements_Object(o)register_object(resolve_class(o.name).allocate)end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 178defvisit_Gem_SafeMarshal_Elements_ObjectLink(o)@objects.fetch(o.offset)end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 222defvisit_Gem_SafeMarshal_Elements_String(s)register_object(+s.str)end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 57defvisit_Gem_SafeMarshal_Elements_Symbol(s)name =s.nameraiseUnpermittedSymbolError.new(symbol:name,stack:formatted_stack)unless@permitted_symbols.include?(name)visit_symbol_type(s)end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 182defvisit_Gem_SafeMarshal_Elements_SymbolLink(o)@symbols.fetch(o.offset)end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 214defvisit_Gem_SafeMarshal_Elements_True(_)trueend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 257defvisit_Gem_SafeMarshal_Elements_UserClass(r)ifresolve_class(r.name)==::Hash&&r.wrapped_object.is_a?(Elements::Hash)hash =register_object({}.compare_by_identity)o =r.wrapped_objecto.pairs.each_with_indexdo|(k,v),i|push_stackik =visit(k)push_stackkhash[k] =visit(v)endifo.is_a?(Elements::HashWithDefaultValue)push_stack:defaulthash.default =visit(o.default)endhashelseraiseUnsupportedError.new("Unsupported user class #{resolve_class(r.name)} in marshal stream",stack:formatted_stack)endend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 186defvisit_Gem_SafeMarshal_Elements_UserDefined(o)register_object(call_method(resolve_class(o.name),:_load,o.binary_string))end
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 190defvisit_Gem_SafeMarshal_Elements_UserMarshal(o)klass =resolve_class(o.name)compat =COMPAT_CLASSES.fetch(klass,nil)idx =@objects.sizeobject =register_object(call_method(compat||klass,:allocate))push_stack:dataret =call_method(object,:marshal_load,visit(o.data))ifcompatobject =@objects[idx] =retendobjectend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 79defvisit_Gem_SafeMarshal_Elements_WithIvars(e)object_offset =@objects.sizepush_stack"object"object =visit(e.object)ivars =map_ivars(object.class,e.ivars)casee.objectwhenElements::UserDefinedifobject.class==::Timeinternal = []ivars.reject!do|k,v|casekwhen:offset,:zone,:nano_num,:nano_den,:submicrointernal<< [k,v]trueelsefalseendends =e.object.binary_string# 122 is the largest integer that can be represented in marshal in a single byteraiseTimeTooLargeError.new("binary string too large",stack:formatted_stack)ifs.bytesize>122marshal_string ="\x04\bIu:\tTime".bmarshal_string.concat(s.bytesize+5)marshal_string<<s# internal is limited to 5, so no overflow is possiblemarshal_string.concat(internal.size+5)internal.eachdo|k,v|k =k.name# ivar name can't be too large because only known ivars are in the internal ivars listmarshal_string.concat(":")marshal_string.concat(k.bytesize+5)marshal_string.concat(k)dumped =Marshal.dump(v)dumped[0,2] =""marshal_string.concat(dumped)endobject =@objects[object_offset] =Marshal.load(marshal_string)endwhenElements::Stringenc =nilivars.reject!do|k,v|casekwhen:EcasevwhenTrueClassenc ="UTF-8"whenFalseClassenc ="US-ASCII"elseraiseFormatError,"Unexpected value for String :E #{v.inspect}"endwhen:encodingenc =velsenextfalseendtrueendobject.force_encoding(enc)ifencendivars.eachdo|k,v|object.instance_variable_setk,vendobjectend
Source
# File lib/rubygems/safe_marshal/visitors/to_ruby.rb, line 316defvisit_symbol_type(element)caseelementwhenElements::Symbolsym =element.name.to_sym@symbols<<symsymwhenElements::SymbolLinkvisit_Gem_SafeMarshal_Elements_SymbolLink(element)endend