From: "Eregon (Benoit Daloze)" Date: 2013-04-20T18:39:09+09:00 Subject: [ruby-core:54478] [Backport 200 - Backport #8276] Marshal.load modifies restored object after calling #marshal_load Issue #8276 has been updated by Eregon (Benoit Daloze). nobu (Nobuyoshi Nakada) wrote: > Note that returning frozen object from marshal_load is wrong in common. > In this particular case, removed excess encoding information because it is duplicated to marshal_dump data, but the other instance variables are set after marshal_load. > Your code has a potential bug and should separate marshal_dump and initialize. How would you reliably freeze the object again then? Should it be a feature of Marshal? ---------------------------------------- Backport #8276: Marshal.load modifies restored object after calling #marshal_load https://bugs.ruby-lang.org/issues/8276#change-38781 Author: Eregon (Benoit Daloze) Status: Assigned Priority: Normal Assignee: nagachika (Tomoyuki Chikanaga) Category: Target version: Given this code, a simple class freezing instances on creation (so they are immutable): class T def initialize(data) @data = data freeze end def marshal_dump @data end def marshal_load data initialize(data) end end t = T.new("dd") s = Marshal.dump(t) p Marshal.load(s) # => ...:in `load': can't modify frozen T (RuntimeError) Freezing on creation from Marshal is needed to ensure immutability and it seems the right place to do it. It used to work (ruby 2.0.0dev (2012-07-15 trunk 36395) [x86_64-darwin10.8.0] did fine). The backtrace: (gdb) bt #0 rb_raise (exc=4304355040, fmt=0x1001be828 "can't modify frozen %s") at error.c:1810 #1 0x000000010004344f in rb_error_frozen (what=) at error.c:2020 #2 0x0000000100004600 in rb_enc_associate_index (obj=, idx=1) at encoding.c:749 #3 0x000000010008233b in r_ivar (obj=4320803800, has_encoding=0x0, arg=0x1006b84b0) at marshal.c:1374 #4 0x00000001000811f1 in r_object0 (arg=0x1006b84b0, ivp=, extmod=8) at marshal.c:1475 #5 0x00000001000821ad in r_object [inlined] () at /Users/benoitdaloze/EREGONMS/Ruby/git/ruby/marshal.c:1890 #6 0x00000001000821ad in marshal_load (argc=, argv=) at marshal.c:1978 ... -- http://bugs.ruby-lang.org/