Skip to content

Commit a69c0c4

Browse files
andrykonchineregon
authored andcommitted
Fix Marshal and dumping String in a multibyte encoding
1 parent 45e656f commit a69c0c4

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

spec/ruby/core/marshal/dump_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ def _dump(level)
193193
Marshal.dump(MarshalSpec::ClassWithOverriddenName).should == "\x04\bc)MarshalSpec::ClassWithOverriddenName"
194194
end
195195

196+
it "dumps a class with multibyte characters in name" do
197+
source_object = eval("MarshalSpec::MultibyteぁあぃいClass".force_encoding(Encoding::UTF_8))
198+
Marshal.dump(source_object).should == "\x04\bc,MarshalSpec::Multibyte\xE3\x81\x81\xE3\x81\x82\xE3\x81\x83\xE3\x81\x84Class"
199+
end
200+
196201
it "raises TypeError with an anonymous Class" do
197202
-> { Marshal.dump(Class.new) }.should raise_error(TypeError, /can't dump anonymous class/)
198203
end
@@ -211,6 +216,11 @@ def _dump(level)
211216
Marshal.dump(MarshalSpec::ModuleWithOverriddenName).should == "\x04\bc*MarshalSpec::ModuleWithOverriddenName"
212217
end
213218

219+
it "dumps a module with multibyte characters in name" do
220+
source_object = eval("MarshalSpec::MultibyteけげこごModule".force_encoding(Encoding::UTF_8))
221+
Marshal.dump(source_object).should == "\x04\bm-MarshalSpec::Multibyte\xE3\x81\x91\xE3\x81\x92\xE3\x81\x93\xE3\x81\x94Module"
222+
end
223+
214224
it "raises TypeError with an anonymous Module" do
215225
-> { Marshal.dump(Module.new) }.should raise_error(TypeError)
216226
end
@@ -664,6 +674,11 @@ class << obj
664674
Marshal.dump(obj).should include("MarshalSpec::TimeWithOverriddenName")
665675
end
666676

677+
it "dumps a Time subclass with multibyte characters in name" do
678+
source_object = eval("MarshalSpec::MultibyteぁあぃいTime".force_encoding(Encoding::UTF_8))
679+
Marshal.dump(source_object).should == "\x04\bc+MarshalSpec::Multibyte\xE3\x81\x81\xE3\x81\x82\xE3\x81\x83\xE3\x81\x84Time"
680+
end
681+
667682
it "raises TypeError with an anonymous Time subclass" do
668683
-> { Marshal.dump(Class.new(Time).now) }.should raise_error(TypeError)
669684
end

spec/ruby/core/marshal/fixtures/marshal_data.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,17 @@ def self.name
262262
end
263263
end
264264

265+
module_eval(<<~ruby.force_encoding(Encoding::UTF_8))
266+
class MultibyteぁあぃいClass
267+
end
268+
269+
module MultibyteけげこごModule
270+
end
271+
272+
class MultibyteぁあぃいTime < Time
273+
end
274+
ruby
275+
265276
DATA = {
266277
"nil" => [nil, "\004\b0"],
267278
"1..2" => [(1..2),

src/main/ruby/truffleruby/core/marshal.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ class Class
5959
end
6060

6161
name = Primitive.module_name self
62-
"c#{ms.serialize_integer(name.length)}#{name}"
62+
"c#{ms.serialize_integer(name.bytesize)}#{name.b}"
6363
end
6464
end
6565

6666
class Module
6767
private def __marshal__(ms)
6868
raise TypeError, "can't dump anonymous module #{self}" if Primitive.module_anonymous?(self)
6969
name = Primitive.module_name self
70-
"m#{ms.serialize_integer(name.length)}#{name}"
70+
"m#{ms.serialize_integer(name.bytesize)}#{name.b}"
7171
end
7272
end
7373

@@ -95,7 +95,7 @@ class Float
9595
end
9696
end
9797

98-
sl = str.length
98+
sl = str.bytesize
9999
if sign == 1
100100
ss = '-'
101101
sl += 1
@@ -168,7 +168,7 @@ def __custom_marshal__(ms)
168168
out << Truffle::Type.binary_string("u#{ms.serialize(name.to_sym)}")
169169

170170
str = _dump
171-
out << ms.serialize_integer(str.length) + str
171+
out << ms.serialize_integer(str.bytesize) + str.b
172172

173173
count = ivars.size + extra_values.size
174174
out << ms.serialize_integer(count)

0 commit comments

Comments
 (0)