diff --git a/complex.c b/complex.c index 1aae3b6ca80b25..b3279f3e0a9e44 100644 --- a/complex.c +++ b/complex.c @@ -21,7 +21,8 @@ VALUE rb_cComplex; static ID id_abs, id_abs2, id_arg, id_cmp, id_conj, id_convert, id_denominator, id_divmod, id_eqeq_p, id_expt, id_fdiv, id_floor, id_idiv, id_imag, id_inspect, id_negate, id_numerator, id_quo, - id_real, id_real_p, id_to_f, id_to_i, id_to_r, id_to_s; + id_real, id_real_p, id_to_f, id_to_i, id_to_r, id_to_s, + id_i_real, id_i_imag; #define f_boolcast(x) ((x) ? Qtrue : Qfalse) @@ -1242,6 +1243,25 @@ nucomp_inspect(VALUE self) return s; } +/* :nodoc: */ +static VALUE +nucomp_dumper(VALUE self) +{ + return self; +} + +/* :nodoc: */ +static VALUE +nucomp_loader(VALUE self, VALUE a) +{ + get_dat1(self); + + dat->real = rb_ivar_get(a, id_i_real); + dat->imag = rb_ivar_get(a, id_i_imag); + + return self; +} + /* :nodoc: */ static VALUE nucomp_marshal_dump(VALUE self) @@ -1250,7 +1270,6 @@ nucomp_marshal_dump(VALUE self) get_dat1(self); a = rb_assoc_new(dat->real, dat->imag); - rb_copy_generic_ivar(a, self); return a; } @@ -1258,17 +1277,11 @@ nucomp_marshal_dump(VALUE self) static VALUE nucomp_marshal_load(VALUE self, VALUE a) { - get_dat1(self); - - rb_check_frozen(self); - rb_check_trusted(self); - Check_Type(a, T_ARRAY); if (RARRAY_LEN(a) != 2) rb_raise(rb_eArgError, "marshaled complex must have an array whose length is 2 but %ld", RARRAY_LEN(a)); - dat->real = RARRAY_PTR(a)[0]; - dat->imag = RARRAY_PTR(a)[1]; - rb_copy_generic_ivar(self, a); + rb_ivar_set(self, id_i_real, RARRAY_PTR(a)[0]); + rb_ivar_set(self, id_i_imag, RARRAY_PTR(a)[1]); return self; } @@ -1833,6 +1846,7 @@ float_arg(VALUE self) void Init_Complex(void) { + VALUE compat; #undef rb_intern #define rb_intern(str) rb_intern_const(str) @@ -1862,6 +1876,8 @@ Init_Complex(void) id_to_i = rb_intern("to_i"); id_to_r = rb_intern("to_r"); id_to_s = rb_intern("to_s"); + id_i_real = rb_intern("@real"); + id_i_imag = rb_intern("@image"); rb_cComplex = rb_define_class("Complex", rb_cNumeric); @@ -1951,7 +1967,9 @@ Init_Complex(void) rb_define_method(rb_cComplex, "inspect", nucomp_inspect, 0); rb_define_method(rb_cComplex, "marshal_dump", nucomp_marshal_dump, 0); - rb_define_method(rb_cComplex, "marshal_load", nucomp_marshal_load, 1); + compat = rb_define_class_under(rb_cComplex, "compatible", rb_cObject); + rb_define_method(compat, "marshal_load", nucomp_marshal_load, 1); + rb_marshal_define_compat(rb_cComplex, compat, nucomp_dumper, nucomp_loader); /* --- */ diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 82d078a0dd52ba..f5e117c117f41d 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -7251,11 +7251,6 @@ d_lite_marshal_dump(VALUE self) INT2FIX(m_of(dat)), DBL2NUM(m_sg(dat))); - if (FL_TEST(self, FL_EXIVAR)) { - rb_copy_generic_ivar(a, self); - FL_SET(a, FL_EXIVAR); - } - return a; } @@ -7336,6 +7331,19 @@ d_lite_marshal_load(VALUE self, VALUE a) return self; } +/* :nodoc: */ +static VALUE +d_lite_old_load(VALUE klass, VALUE s) +{ + VALUE data = rb_marshal_load(s); + VALUE self = rb_obj_alloc(klass); + Check_Type(data, T_ARRAY); + if (RARRAY_LEN(data) == 2) { + const VALUE *ptr = RARRAY_PTR(data); + data = rb_ary_new3(3, ptr[0], INT2FIX(0), ptr[1]); + } + return d_lite_marshal_load(self, data); +} /* datetime */ @@ -9674,6 +9682,7 @@ Init_date_core(void) #endif rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0); rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1); + rb_define_singleton_method(cDate, "_load", d_lite_old_load, 1); /* datetime */ diff --git a/rational.c b/rational.c index c4469c809249fe..e7a296a0d1e39f 100644 --- a/rational.c +++ b/rational.c @@ -25,7 +25,7 @@ VALUE rb_cRational; static ID id_abs, id_cmp, id_convert, id_eqeq_p, id_expt, id_fdiv, id_floor, id_idiv, id_inspect, id_integer_p, id_negate, id_to_f, - id_to_i, id_to_s, id_truncate; + id_to_i, id_to_s, id_truncate, id_i_num, id_i_den; #define f_boolcast(x) ((x) ? Qtrue : Qfalse) @@ -1588,6 +1588,25 @@ nurat_inspect(VALUE self) return s; } +/* :nodoc: */ +static VALUE +nurat_dumper(VALUE self) +{ + return self; +} + +/* :nodoc: */ +static VALUE +nurat_loader(VALUE self, VALUE a) +{ + get_dat1(self); + + dat->num = rb_ivar_get(a, id_i_num); + dat->den = rb_ivar_get(a, id_i_den); + + return self; +} + /* :nodoc: */ static VALUE nurat_marshal_dump(VALUE self) @@ -1596,7 +1615,6 @@ nurat_marshal_dump(VALUE self) get_dat1(self); a = rb_assoc_new(dat->num, dat->den); - rb_copy_generic_ivar(a, self); return a; } @@ -1604,21 +1622,18 @@ nurat_marshal_dump(VALUE self) static VALUE nurat_marshal_load(VALUE self, VALUE a) { - get_dat1(self); - rb_check_frozen(self); rb_check_trusted(self); Check_Type(a, T_ARRAY); if (RARRAY_LEN(a) != 2) rb_raise(rb_eArgError, "marshaled rational must have an array whose length is 2 but %ld", RARRAY_LEN(a)); - dat->num = RARRAY_PTR(a)[0]; - dat->den = RARRAY_PTR(a)[1]; - rb_copy_generic_ivar(self, a); - - if (f_zero_p(dat->den)) + if (f_zero_p(RARRAY_PTR(a)[1])) rb_raise_zerodiv(); + rb_ivar_set(self, id_i_num, RARRAY_PTR(a)[0]); + rb_ivar_set(self, id_i_den, RARRAY_PTR(a)[1]); + return self; } @@ -2295,6 +2310,7 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass) void Init_Rational(void) { + VALUE compat; #undef rb_intern #define rb_intern(str) rb_intern_const(str) @@ -2315,6 +2331,8 @@ Init_Rational(void) id_to_i = rb_intern("to_i"); id_to_s = rb_intern("to_s"); id_truncate = rb_intern("truncate"); + id_i_num = rb_intern("@numerator"); + id_i_den = rb_intern("@denominator"); rb_cRational = rb_define_class("Rational", rb_cNumeric); @@ -2375,7 +2393,9 @@ Init_Rational(void) rb_define_method(rb_cRational, "inspect", nurat_inspect, 0); rb_define_method(rb_cRational, "marshal_dump", nurat_marshal_dump, 0); - rb_define_method(rb_cRational, "marshal_load", nurat_marshal_load, 1); + compat = rb_define_class_under(rb_cRational, "compatible", rb_cObject); + rb_define_method(compat, "marshal_load", nurat_marshal_load, 1); + rb_marshal_define_compat(rb_cRational, compat, nurat_dumper, nurat_loader); /* --- */ diff --git a/test/date/test_date_marshal.rb b/test/date/test_date_marshal.rb index 4ea5565716e127..b385c0792fd8f0 100644 --- a/test/date/test_date_marshal.rb +++ b/test/date/test_date_marshal.rb @@ -38,4 +38,15 @@ def test_marshal assert_raise(RuntimeError){d.marshal_load(a)} end + def test_marshal_old + bug6652 = '[ruby-core:45891]' + + data = "\004\bu:\tDate=\004\b[\bo:\rRational\a:\017@numeratori\003%\275J:\021" \ + "@denominatori\ai\000i\003\031\025#" + assert_equal(Date.new(1993, 2, 24), Marshal.load(data), bug6652) + + data = "\004\bu:\rDateTimeC\004\b[\bo:\rRational\a:\017@numeratorl+\bK\355B\024\003\000:\021" \ + "@denominatori\002\030\025i\000i\003\031\025#" + assert_equal(DateTime.new(1993, 2, 24, 12, 34, 56), Marshal.load(data), bug6652) + end end diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb index aa6d6a77feadba..51fb519b673dda 100644 --- a/test/ruby/test_complex.rb +++ b/test/ruby/test_complex.rb @@ -657,15 +657,15 @@ def test_marshal assert_instance_of(Complex, c2) end - bug3656 = '[ruby-core:31622]' - assert_raise(TypeError, bug3656) { - Complex(1,2).marshal_load(0) - } - c = Complex(1,2) - c.freeze - assert(c.frozen?) - assert_raise(RuntimeError){c.marshal_load([2,3])} + assert_respond_to(c, :marshal_dump) + assert_not_respond_to(c, :marshal_load) + end + + def test_marshal_old + bug6625 = '[ruby-core:45775]' + data = "\004\bo:\fComplex\a:\n@reali\f:\v@imagei/" + assert_equal(Complex(7, 42), Marshal.load(data), bug6625) end def test_parse diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb index e1aafb5a0aa338..bf1bbd951721ca 100644 --- a/test/ruby/test_rational.rb +++ b/test/ruby/test_rational.rb @@ -827,15 +827,15 @@ def test_marshal Marshal.load("\x04\bU:\rRational[\ai\x06i\x05") } - bug3656 = '[ruby-core:31622]' - assert_raise(TypeError, bug3656) { - Rational(1,2).marshal_load(0) - } - c = Rational(1,2) - c.freeze - assert(c.frozen?) - assert_raise(RuntimeError){c.marshal_load([2,3])} + assert_respond_to(c, :marshal_dump) + assert_not_respond_to(c, :marshal_load) + end + + def test_marshal_old + bug6625 = '[ruby-core:45775]' + data = "\004\bo:\rRational\a:\021@denominatori\035:\017@numeratori\f" + assert_equal(Rational(7, 24), Marshal.load(data), bug6625) end def test_parse