Skip to content

Commit f032276

Browse files
committed
Fix the case of unmarshalling a String.clone instance
* In such a case, one cannot bind String#__allocate__ to that class, but they are the same implementation (CallTarget) anyway, using the same Layout, which is required for correctness. * MRI also refuses binding a method on a module/class clone, even though that seems relatively safe. * Use the same error as MRI in the broken case.
1 parent 31b10eb commit f032276

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

src/main/ruby/core/marshal.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,19 @@ def construct_string
229229
bytes = get_byte_sequence.force_encoding(Encoding::ASCII_8BIT)
230230

231231
if @user_class
232-
obj = STRING_ALLOCATE.bind(get_user_class).call
232+
cls = get_user_class
233+
if cls < String
234+
obj = STRING_ALLOCATE.bind(cls).call
235+
else
236+
allocate = cls.method(:__allocate__)
237+
if allocate.unbind == STRING_ALLOCATE
238+
# For example, String.clone falls in this case
239+
obj = allocate.call
240+
else
241+
raise ArgumentError, 'dump format error (user class)'
242+
end
243+
end
244+
233245
Truffle.invoke_primitive(:string_initialize, obj, bytes, Encoding::ASCII_8BIT)
234246
else
235247
obj = bytes

0 commit comments

Comments
 (0)