From 50bf2e550a6fb7cfa197d8429cf4a1e4f5e3e9c7 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 11 Feb 2010 05:37:43 +0000 Subject: * marshal.c (r_object0): read sequentially since marshal source may not be possible to rewind. [ruby-dev:40386] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26639 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ marshal.c | 45 +++++++++++---------------------------------- test/ruby/test_marshal.rb | 10 ++++++++++ 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8e057e3c5..087bc85540 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Feb 11 14:37:39 2010 Nobuyoshi Nakada + + * marshal.c (r_object0): read sequentially since marshal source + may not be possible to rewind. [ruby-dev:40386] + Thu Feb 11 09:49:31 2010 Tanaka Akira * lib/resolv.rb: fix [ruby-core:28144] reported by Hans de Graaff. diff --git a/marshal.c b/marshal.c index 3b5054c007..395254094f 100644 --- a/marshal.c +++ b/marshal.c @@ -1258,7 +1258,7 @@ r_leave(VALUE v, struct load_arg *arg) } static void -r_ivar(VALUE obj, struct load_arg *arg) +r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg) { long len; @@ -1270,6 +1270,7 @@ r_ivar(VALUE obj, struct load_arg *arg) int idx = id2encidx(id, val, arg); if (idx >= 0) { rb_enc_associate_index(obj, idx); + if (has_encoding) *has_encoding = TRUE; } else { rb_ivar_set(obj, id, val); @@ -1323,35 +1324,6 @@ obj_alloc_by_path(VALUE path, struct load_arg *arg) return rb_obj_alloc(klass); } -static int -has_encoding(struct load_arg *arg) -{ - int res = FALSE; - long offset = arg->offset; - r_long(arg); - switch (r_byte(arg)) { - case TYPE_SYMBOL: - switch (r_byte(arg)) { - case 6: - if (r_byte(arg) == 'E') res = TRUE; - break; - case 13: - if (r_byte(arg) == 'e') res = TRUE; - break; - } - break; - case TYPE_SYMLINK: - { - ID id = r_symlink(arg); - if (id == rb_intern("E") || id == rb_id_encoding()) - res = TRUE; - } - break; - } - arg->offset = offset; - return res; -} - static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod) { @@ -1378,7 +1350,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) int ivar = TRUE; v = r_object0(arg, &ivar, extmod); - if (ivar) r_ivar(v, arg); + if (ivar) r_ivar(v, NULL, arg); } break; @@ -1522,8 +1494,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) { volatile VALUE str = r_bytes(arg); int options = r_byte(arg); + int has_encoding = FALSE; - if (!ivp || !has_encoding(arg)) { + if (ivp) { + r_ivar(str, &has_encoding, arg); + *ivp = FALSE; + } + if (!has_encoding) { VALUE pat; VALUE dst; static const char rsrc[] = @@ -1617,7 +1594,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) } data = r_string(arg); if (ivp) { - r_ivar(data, arg); + r_ivar(data, NULL, arg); *ivp = FALSE; } v = rb_funcall(klass, s_load, 1, data); @@ -1659,7 +1636,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) rb_raise(rb_eArgError, "dump format error"); } v = r_entry0(v, idx, arg); - r_ivar(v, arg); + r_ivar(v, NULL, arg); v = r_leave(v, arg); } break; diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb index 28cf38c7db..31975b7aea 100644 --- a/test/ruby/test_marshal.rb +++ b/test/ruby/test_marshal.rb @@ -1,4 +1,5 @@ require 'test/unit' +require 'tempfile' require_relative 'marshaltestlib' class TestMarshal < Test::Unit::TestCase @@ -325,6 +326,15 @@ class TestMarshal < Test::Unit::TestCase b = "\x82\xa2".force_encoding(Encoding::Windows_31J) c = [/#{a}/, /#{b}/] assert_equal(c, Marshal.load(Marshal.dump(c)), bug2109) + + assert_nothing_raised(ArgumentError, '[ruby-dev:40386]') do + re = Tempfile.open("marshal_regexp") do |f| + f.binmode.write("\x04\bI/\x00\x00\x06:\rencoding\"\rUS-ASCII") + f.close + Marshal.load(f.open.binmode) + end + assert_equal(//, re) + end end class DumpTest -- cgit v1.2.3