summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-11 05:37:43 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-11 05:37:43 +0000
commit50bf2e550a6fb7cfa197d8429cf4a1e4f5e3e9c7 (patch)
tree0c316c6942ccb100ca7f860b7a9e7452cd705bfb
parentd61a305270246ddc050e7b165b8242629957a25f (diff)
* 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
-rw-r--r--ChangeLog5
-rw-r--r--marshal.c45
-rw-r--r--test/ruby/test_marshal.rb10
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 <nobu@ruby-lang.org>
+
+ * 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 <akr@fsij.org>
* 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