From: nobu@... Date: 2004-10-04T02:14:51+09:00 Subject: [ruby-dev:24411] Re: Marshal.load dumps core なかだです。 At Sun, 3 Oct 2004 00:00:05 +0900, Tanaka Akira wrote in [ruby-dev:24404]: > > 次のようにすると core を吐きます。 > > % ./ruby -e ' > class C > def marshal_dump > end > def marshal_load(v) > $s.replace "" > end > end > o = [C.new, "a" * 0x20000] > $s = Marshal.dump(o) > p $s.length > Marshal.load($s) > ' これでどうでしょうか。 Index: marshal.c =================================================================== RCS file: /cvs/ruby/src/ruby/marshal.c,v retrieving revision 1.117 diff -U2 -p -d -r1.117 marshal.c --- marshal.c 29 Sep 2004 05:15:33 -0000 1.117 +++ marshal.c 3 Oct 2004 17:08:04 -0000 @@ -780,5 +780,6 @@ marshal_dump(argc, argv) struct load_arg { - char *ptr, *end; + VALUE src; + long pos; st_table *symbols; VALUE data; @@ -794,13 +795,13 @@ r_byte(arg) { int c; + VALUE src = arg->src; - if (!arg->end) { - VALUE src = (VALUE)arg->ptr; + if (arg->pos == -1L) { VALUE v = rb_funcall2(src, s_getc, 0, 0); if (NIL_P(v)) rb_eof_error(); c = (unsigned char)FIX2INT(v); } - else if (arg->ptr < arg->end) { - c = *(unsigned char*)arg->ptr++; + else if (arg->pos < RSTRING(src)->len) { + c = (unsigned char)RSTRING(src)->ptr[arg->pos++]; } else { @@ -867,9 +868,8 @@ r_bytes0(len, arg) struct load_arg *arg; { - VALUE str; + VALUE str, src = arg->src; if (len == 0) return rb_str_new(0, 0); - if (!arg->end) { - VALUE src = (VALUE)arg->ptr; + if (arg->pos == -1L) { VALUE n = LONG2NUM(len); str = rb_funcall2(src, s_read, 1, &n); @@ -880,10 +880,10 @@ r_bytes0(len, arg) } else { - if (arg->ptr + len > arg->end) { + if (arg->pos + len > RSTRING(src)->len) { too_short: rb_raise(rb_eArgError, "marshal data too short"); } - str = rb_str_new(arg->ptr, len); - arg->ptr += len; + str = rb_str_new(RSTRING(src)->ptr + arg->pos, len); + arg->pos += len; } return str; @@ -1389,9 +1389,9 @@ marshal_load(argc, argv) rb_scan_args(argc, argv, "11", &port, &proc); + arg.src = port; if (rb_respond_to(port, rb_intern("to_str"))) { arg.taint = OBJ_TAINTED(port); /* original taintedness */ - StringValue(port); /* possible conversion */ - arg.ptr = RSTRING(port)->ptr; - arg.end = arg.ptr + RSTRING(port)->len; + StringValue(arg.src); /* possible conversion */ + arg.pos = 0L; } else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) { @@ -1400,6 +1400,5 @@ marshal_load(argc, argv) } arg.taint = Qtrue; - arg.ptr = (char *)port; - arg.end = 0; + arg.pos = -1L; } else { -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦