From 90a88ab9a09d19165cf3668b6a8473024e064fa7 Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 9 Oct 2003 17:45:53 +0000 Subject: [PATCH] * marshal.c (r_object0): remove unnecessary iv restoration for USRMARSHAL. [ruby-dev:21582] * marshal.c (w_object): dump generic instance variables from a string from '_dump'. * variable.c (rb_generic_ivar_table): return 0 if obj's FL_EXIVAR is not set. * time.c (time_dump): copy instance variables to dumped string, to be included in the marshaled data. * bignum.c (rb_big2ulong): add range check to ensure round trip. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 19 ++++++++++++++++--- bignum.c | 7 ++++++- marshal.c | 52 +++++++++++++++++++--------------------------------- pack.c | 13 ++++++++++--- time.c | 21 ++++++++++----------- variable.c | 1 + 6 files changed, 62 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2339ce0b51..4859b3c1b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,14 +23,27 @@ Thu Oct 9 17:43:36 2003 Nobuyoshi Nakada * eval.c (proc_save_safe_level, proc_get_safe_level, proc_set_safe_level): save/restore safe level 1..4. +Thu Oct 9 16:33:23 2003 Yukihiro Matsumoto + + * marshal.c (r_object0): remove unnecessary iv restoration for + USRMARSHAL. [ruby-dev:21582] + + * marshal.c (w_object): dump generic instance variables from + a string from '_dump'. + + * variable.c (rb_generic_ivar_table): return 0 if obj's FL_EXIVAR + is not set. + + * time.c (time_dump): copy instance variables to dumped string, to + be included in the marshaled data. + + * bignum.c (rb_big2ulong): add range check to ensure round trip. + Thu Oct 9 15:45:27 2003 Yukihiro Matsumoto * pack.c (uv_to_utf8): change message to "out of range", since negative values are not "too big". [ruby-dev21567] - * marshal.c (w_object): should pass the value of "weak" to - w_object(). [ruby-dev:21555] and [ruby-dev:21561] - Thu Oct 9 14:05:38 2003 Nobuyoshi Nakada * eval.c (rb_set_end_proc, rb_exec_end_proc): restore safe level. diff --git a/bignum.c b/bignum.c index 6882580eae..7c3e029d57 100644 --- a/bignum.c +++ b/bignum.c @@ -729,7 +729,12 @@ rb_big2ulong(x) { unsigned long num = big2ulong(x, "unsigned long"); - if (!RBIGNUM(x)->sign) return -num; + if (!RBIGNUM(x)->sign) { + if ((long)num < 0) { + rb_raise(rb_eRangeError, "bignum out of range of unsigned long"); + } + return -num; + } return num; } diff --git a/marshal.c b/marshal.c index 3df15789cc..387b3052f0 100644 --- a/marshal.c +++ b/marshal.c @@ -93,7 +93,6 @@ struct dump_call_arg { VALUE obj; struct dump_arg *arg; int limit; - int weak; }; static void w_long _((long, struct dump_arg*)); @@ -333,15 +332,15 @@ w_unique(s, arg) w_symbol(rb_intern(s), arg); } -static void w_object _((VALUE,struct dump_arg*,int,int)); +static void w_object _((VALUE,struct dump_arg*,int)); static int hash_each(key, value, arg) VALUE key, value; struct dump_call_arg *arg; { - w_object(key, arg->arg, arg->limit, arg->weak); - w_object(value, arg->arg, arg->limit, arg->weak); + w_object(key, arg->arg, arg->limit); + w_object(value, arg->arg, arg->limit); return ST_CONTINUE; } @@ -404,7 +403,7 @@ w_obj_each(id, value, arg) struct dump_call_arg *arg; { w_symbol(id, arg->arg); - w_object(value, arg->arg, arg->limit, arg->weak); + w_object(value, arg->arg, arg->limit); return ST_CONTINUE; } @@ -423,11 +422,10 @@ w_ivar(tbl, arg) } static void -w_object(obj, arg, limit, weak) +w_object(obj, arg, limit) VALUE obj; struct dump_arg *arg; int limit; - int weak; { struct dump_call_arg c_arg; st_table *ivtbl = 0; @@ -439,7 +437,6 @@ w_object(obj, arg, limit, weak) limit--; c_arg.limit = limit; c_arg.arg = arg; - c_arg.weak = weak; if (ivtbl = rb_generic_ivar_table(obj)) { w_byte(TYPE_IVAR, arg); @@ -463,7 +460,7 @@ w_object(obj, arg, limit, weak) w_long(FIX2LONG(obj), arg); } else { - w_object(rb_int2big(FIX2LONG(obj)), arg, limit, weak); + w_object(rb_int2big(FIX2LONG(obj)), arg, limit); } #endif } @@ -485,17 +482,11 @@ w_object(obj, arg, limit, weak) if (rb_respond_to(obj, s_mdump)) { VALUE v; - if (TYPE(obj) == T_OBJECT) { - w_byte(TYPE_IVAR, arg); - ivtbl = ROBJECT(obj)->iv_tbl; - } v = rb_funcall(obj, s_mdump, 0, 0); w_byte(TYPE_USRMARSHAL, arg); w_unique(rb_class2name(CLASS_OF(obj)), arg); - w_object(v, arg, limit, weak); - c_arg.weak = Qtrue; - ivtbl = rb_generic_ivar_table(v); - if (ivtbl) w_ivar(ivtbl, &c_arg); + w_object(v, arg, limit); + if (ivtbl) w_ivar(0, &c_arg); return; } if (rb_respond_to(obj, s_dump)) { @@ -505,11 +496,14 @@ w_object(obj, arg, limit, weak) if (TYPE(v) != T_STRING) { rb_raise(rb_eTypeError, "_dump() must return string"); } + if (!ivtbl && (ivtbl = rb_generic_ivar_table(v))) { + w_byte(TYPE_IVAR, arg); + } w_class(TYPE_USERDEF, obj, arg); w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg); - c_arg.weak = Qtrue; - ivtbl = rb_generic_ivar_table(v); - if (ivtbl) w_ivar(ivtbl, &c_arg); + if (ivtbl) { + w_ivar(ivtbl, &c_arg); + } return; } @@ -595,7 +589,7 @@ w_object(obj, arg, limit, weak) w_long(len, arg); while (len--) { - w_object(*ptr, arg, limit, weak); + w_object(*ptr, arg, limit); ptr++; } } @@ -616,7 +610,7 @@ w_object(obj, arg, limit, weak) w_long(RHASH(obj)->tbl->num_entries, arg); st_foreach(RHASH(obj)->tbl, hash_each, (st_data_t)&c_arg); if (!NIL_P(RHASH(obj)->ifnone)) { - w_object(RHASH(obj)->ifnone, arg, limit, weak); + w_object(RHASH(obj)->ifnone, arg, limit); } break; @@ -634,7 +628,7 @@ w_object(obj, arg, limit, weak) } for (i=0; iptr[i]), arg); - w_object(RSTRUCT(obj)->ptr[i], arg, limit, weak); + w_object(RSTRUCT(obj)->ptr[i], arg, limit); } } break; @@ -655,15 +649,11 @@ w_object(obj, arg, limit, weak) rb_obj_classname(obj)); } v = rb_funcall(obj, s_dump_data, 0); - w_object(v, arg, limit, weak); + w_object(v, arg, limit); } break; default: - if (weak) { - w_byte(TYPE_NIL, arg); - return; - } rb_raise(rb_eTypeError, "can't dump %s", rb_obj_classname(obj)); break; @@ -678,7 +668,7 @@ static VALUE dump(arg) struct dump_call_arg *arg; { - w_object(arg->obj, arg->arg, arg->limit, arg->weak); + w_object(arg->obj, arg->arg, arg->limit); if (arg->arg->dest) { rb_io_write(arg->arg->dest, arg->arg->str); rb_str_resize(arg->arg->str, 0); @@ -1216,10 +1206,6 @@ r_object0(arg, proc, ivp) } r_entry(v, arg); data = r_object(arg); - if (ivp) { - r_ivar(v, arg); - *ivp = Qfalse; - } rb_funcall(v, s_mload, 1, data); } break; diff --git a/pack.c b/pack.c index fd5245a618..553668de3f 100644 --- a/pack.c +++ b/pack.c @@ -825,7 +825,7 @@ pack_pack(ary, fmt) case 'U': while (len-- > 0) { - unsigned long l; + long l; char buf[8]; int le; @@ -834,6 +834,9 @@ pack_pack(ary, fmt) else { l = NUM2ULONG(from); } + if (l < 0) { + rb_raise(rb_eArgError, "pack(U): negative value"); + } le = uv_to_utf8(buf, l); rb_str_buf_cat(res, (char*)buf, le); } @@ -918,7 +921,11 @@ pack_pack(ary, fmt) if (NIL_P(from)) ul = 0; else { - ul = NUM2ULONG(from); + long l = NUM2LONG(from); + if (l < 0) { + rb_raise(rb_eArgError, "cannot compress negative numbers"); + } + ul = l; } while (ul) { @@ -1857,7 +1864,7 @@ uv_to_utf8(buf, uv) buf[5] = (uv&0x3f)|0x80; return 6; } - rb_raise(rb_eArgError, "uv_to_utf8(); value out of range"); + rb_raise(rb_eArgError, "pack(U): value out of range"); } static const long utf8_limits[] = { diff --git a/time.c b/time.c index 8c75b709f5..c0b1c38fe7 100644 --- a/time.c +++ b/time.c @@ -1317,7 +1317,6 @@ time_mdump(time) char buf[8]; time_t t; int i; - VALUE str; GetTimeval(time, tobj); @@ -1345,13 +1344,7 @@ time_mdump(time) s = RSHIFT(s, 8); } - str = rb_str_new(buf, 8); - if (FL_TEST(time, FL_EXIVAR)) { - rb_copy_generic_ivar(str, time); - FL_SET(str, FL_EXIVAR); - } - - return str; + return rb_str_new(buf, 8); } static VALUE @@ -1360,10 +1353,16 @@ time_dump(argc, argv, time) VALUE *argv; VALUE time; { - VALUE dummy; + VALUE str; - rb_scan_args(argc, argv, "01", &dummy); - return time_mdump(time); + rb_scan_args(argc, argv, "01", 0); + str = time_mdump(time); + if (FL_TEST(time, FL_EXIVAR)) { + rb_copy_generic_ivar(str, time); + FL_SET(str, FL_EXIVAR); + } + + return str; } static VALUE diff --git a/variable.c b/variable.c index 32616fc13f..3cee63b465 100644 --- a/variable.c +++ b/variable.c @@ -780,6 +780,7 @@ rb_generic_ivar_table(obj) { st_table *tbl; + if (!FL_TEST(obj, FL_EXIVAR)) return 0; if (!generic_iv_tbl) return 0; if (!st_lookup(generic_iv_tbl, obj, (st_data_t *)&tbl)) return 0; return tbl;