Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix CompiledFile unmarshalling

This Ruby unmarshaller is not currently exercised by normal code
loading: it uses marshal.cpp instead.

Fixes #1706.
  • Loading branch information...
commit a6fb7b6c6c4254c841ca0e109034b3c7fc4507e4 1 parent 3026bd1
John Firebaugh jfirebaugh authored
50 lib/compiler/compiled_file.rb
View
@@ -99,15 +99,15 @@ def unmarshal(stream)
def unmarshal_data
kind = next_type
case kind
- when ?t
+ when 116 # ?t
return true
- when ?f
+ when 102 # ?f
return false
- when ?n
+ when 110 # ?n
return nil
- when ?I
+ when 73 # ?I
return next_string.to_i(16)
- when ?d
+ when 100 # ?d
str = next_string.chop
# handle the special NaN, Infinity and -Infinity differently
@@ -133,24 +133,21 @@ def unmarshal_data
raise TypeError, "Invalid Float format: #{str}"
end
end
- when ?s
+ when 115 # ?s
enc = unmarshal_data
count = next_string.to_i
str = next_bytes count
str.force_encoding enc if enc and defined?(Encoding)
- discard # remove the \n
return str
- when ?x
+ when 120 # ?x
count = next_string.to_i
str = next_bytes count
- discard # remove the \n
return str.to_sym
- when ?c
+ when 99 # ?c
count = next_string.to_i
str = next_bytes count
- discard
return str.split("::").inject(Object) { |a,n| a.const_get(n) }
- when ?p
+ when 112 # ?p
count = next_string.to_i
obj = Tuple.new(count)
i = 0
@@ -159,7 +156,7 @@ def unmarshal_data
i += 1
end
return obj
- when ?i
+ when 105 # ?i
count = next_string.to_i
seq = InstructionSequence.new(count)
i = 0
@@ -168,11 +165,11 @@ def unmarshal_data
i += 1
end
return seq
- when ?E
+ when 69 # ?E
count = next_string.to_i
name = next_bytes count
return Encoding.find(name) if defined?(Encoding)
- when ?M
+ when 77 # ?M
version = next_string.to_i
if version != 1
raise "Unknown CompiledMethod version #{version}"
@@ -229,34 +226,17 @@ def next_string
private :next_string
##
- # Returns the next _count_ bytes in _@data_.
+ # Returns the next _count_ bytes in _@data_, skipping the
+ # trailing "\n" character.
def next_bytes(count)
str = String.from_bytearray @data, @start, count
- @start += count
+ @start += count + 1
str
end
private :next_bytes
##
- # Returns the next byte in _@data_.
- def next_byte
- byte = @data[@start]
- @start += 1
- byte
- end
-
- private :next_byte
-
- ##
- # Moves the next read pointer ahead by one character.
- def discard
- @start += 1
- end
-
- private :discard
-
- ##
# For object +val+, return a String represetation.
def marshal(val)
79 spec/compiler/compiled_file/marshal/unmarshal_spec.rb
View
@@ -0,0 +1,79 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+
+describe "Rubinius::CompiledFile::Marshal#unmarshal" do
+ it "unmarshals true" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("t\n").should == true
+ end
+
+ it "unmarshals false" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("f\n").should == false
+ end
+
+ it "unmarshals nil" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("n\n").should == nil
+ end
+
+ it "unmarshals an Integer" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("I\nCAFEF00D").should == 0xCAFEF00D
+ end
+
+ it "unmarshals a Float" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("d\n +0.785000000000000031086244689504383131861686706542968750 2\n").should == 3.14
+ end
+
+ it "unmarshals +infinity" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("d\nInfinity\n").should be_positive_infinity
+ end
+
+ it "unmarshals -infinity" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("d\n-Infinity\n").should be_negative_infinity
+ end
+
+ it "unmarshals NaN" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("d\nNaN\n").should be_nan
+ end
+
+ it "unmarshals a Symbol" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("x\n12\nHello world!\n").should == :"Hello world!"
+ end
+
+ it "unmarshals a constant" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("c\n22\nRubinius::CompiledFile\n").should == Rubinius::CompiledFile
+ end
+
+ ruby_version_is ""..."1.9" do
+ it "unmarshals a String" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("s\nE\n0\n\n12\nHello world!\n").should == "Hello world!"
+ end
+
+ it "returns nil when unmarshalling an encoding" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("E\n5\nUTF-8\n13\n").should be_nil
+ end
+ end
+
+ ruby_version_is "1.9" do
+ it "unmarshals a String" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ str = marshal.unmarshal("s\nE\n5\nUTF-8\n12\nHello world!\n")
+ str.should == "Hello world!"
+ str.encoding.should == Encoding::UTF_8
+ end
+
+ it "unmarshals an encoding" do
+ marshal = Rubinius::CompiledFile::Marshal.new
+ marshal.unmarshal("E\n5\nUTF-8\n13\n").should == Encoding::UTF_8
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.