mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
merge revision(s) 25230,34866:
* marshal.c (struct {dump,load}_arg): manage with dfree, instead of using local variable which may be moved by context switch. [ruby-dev:39425] * marshal.c (mark_dump_arg): mark destination string. patch by Vit Ondruch. [Bug #4339] * marshal.c (clear_dump_arg, clear_load_arg): clean up also data tables as same as symbols tables. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@34867 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2cb7a6c056
commit
c31e7c1e8b
4 changed files with 119 additions and 76 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
Fri Mar 2 11:44:33 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* marshal.c (mark_dump_arg): mark destination string. patch by
|
||||
Vit Ondruch. [Bug #4339]
|
||||
|
||||
* marshal.c (clear_dump_arg, clear_load_arg): clean up also data
|
||||
tables as same as symbols tables.
|
||||
|
||||
Fri Mar 2 11:44:33 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* marshal.c (struct {dump,load}_arg): manage with dfree, instead
|
||||
of using local variable which may be moved by context switch.
|
||||
[ruby-dev:39425]
|
||||
|
||||
Wed Feb 8 14:06:59 2012 Hiroshi Nakamura <nahi@ruby-lang.org>
|
||||
|
||||
* ext/openssl/ossl_ssl.c: Add SSL constants and allow to unset SSL
|
||||
|
|
143
marshal.c
143
marshal.c
|
@ -85,12 +85,10 @@ static ID s_dump_data, s_load_data, s_alloc, s_call;
|
|||
static ID s_getc, s_read, s_write, s_binmode;
|
||||
|
||||
struct dump_arg {
|
||||
VALUE obj;
|
||||
VALUE str, dest;
|
||||
st_table *symbols;
|
||||
st_table *data;
|
||||
int taint;
|
||||
VALUE wrapper;
|
||||
};
|
||||
|
||||
struct dump_call_arg {
|
||||
|
@ -104,20 +102,31 @@ check_dump_arg(arg, sym)
|
|||
struct dump_arg *arg;
|
||||
ID sym;
|
||||
{
|
||||
if (!DATA_PTR(arg->wrapper)) {
|
||||
if (!arg->symbols) {
|
||||
rb_raise(rb_eRuntimeError, "Marshal.dump reentered at %s",
|
||||
rb_id2name(sym));
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_dump_arg _((struct dump_arg *arg));
|
||||
|
||||
static void
|
||||
mark_dump_arg(ptr)
|
||||
void *ptr;
|
||||
{
|
||||
struct dump_arg *p = ptr;
|
||||
if (!ptr)
|
||||
if (!p->symbols)
|
||||
return;
|
||||
rb_mark_set(p->data);
|
||||
rb_gc_mark(p->str);
|
||||
}
|
||||
|
||||
static void
|
||||
free_dump_arg(ptr)
|
||||
void *ptr;
|
||||
{
|
||||
clear_dump_arg(ptr);
|
||||
xfree(ptr);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -699,32 +708,18 @@ w_object(obj, arg, limit)
|
|||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
dump(arg)
|
||||
struct dump_call_arg *arg;
|
||||
{
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
dump_ensure(arg)
|
||||
static void
|
||||
clear_dump_arg(arg)
|
||||
struct dump_arg *arg;
|
||||
{
|
||||
if (!DATA_PTR(arg->wrapper)) return 0;
|
||||
if (!arg->symbols) return;
|
||||
st_free_table(arg->symbols);
|
||||
arg->symbols = 0;
|
||||
st_free_table(arg->data);
|
||||
DATA_PTR(arg->wrapper) = 0;
|
||||
arg->wrapper = 0;
|
||||
arg->data = 0;
|
||||
if (arg->taint) {
|
||||
OBJ_TAINT(arg->str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -760,8 +755,8 @@ marshal_dump(argc, argv)
|
|||
{
|
||||
VALUE obj, port, a1, a2;
|
||||
int limit = -1;
|
||||
struct dump_arg arg;
|
||||
struct dump_call_arg c_arg;
|
||||
struct dump_arg *arg;
|
||||
VALUE wrapper;
|
||||
|
||||
port = Qnil;
|
||||
rb_scan_args(argc, argv, "12", &obj, &a1, &a2);
|
||||
|
@ -775,37 +770,40 @@ marshal_dump(argc, argv)
|
|||
else if (NIL_P(a1)) goto type_error;
|
||||
else port = a1;
|
||||
}
|
||||
arg.dest = 0;
|
||||
arg.symbols = st_init_numtable();
|
||||
arg.data = st_init_numtable();
|
||||
arg.taint = Qfalse;
|
||||
arg.str = rb_str_buf_new(0);
|
||||
RBASIC(arg.str)->klass = 0;
|
||||
arg.wrapper = Data_Wrap_Struct(rb_cData, mark_dump_arg, 0, &arg);
|
||||
wrapper = Data_Make_Struct(rb_cData, struct dump_arg, mark_dump_arg, free_dump_arg, arg);
|
||||
arg->dest = 0;
|
||||
arg->symbols = st_init_numtable();
|
||||
arg->data = st_init_numtable();
|
||||
arg->taint = Qfalse;
|
||||
arg->str = rb_str_buf_new(0);
|
||||
RBASIC(arg->str)->klass = 0;
|
||||
if (!NIL_P(port)) {
|
||||
if (!rb_respond_to(port, s_write)) {
|
||||
type_error:
|
||||
rb_raise(rb_eTypeError, "instance of IO needed");
|
||||
}
|
||||
arg.dest = port;
|
||||
arg->dest = port;
|
||||
if (rb_respond_to(port, s_binmode)) {
|
||||
rb_funcall2(port, s_binmode, 0, 0);
|
||||
check_dump_arg(&arg, s_binmode);
|
||||
check_dump_arg(arg, s_binmode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
port = arg.str;
|
||||
port = arg->str;
|
||||
}
|
||||
|
||||
c_arg.obj = obj;
|
||||
c_arg.arg = &arg;
|
||||
c_arg.limit = limit;
|
||||
w_byte(MARSHAL_MAJOR, arg);
|
||||
w_byte(MARSHAL_MINOR, arg);
|
||||
|
||||
w_byte(MARSHAL_MAJOR, &arg);
|
||||
w_byte(MARSHAL_MINOR, &arg);
|
||||
w_object(obj, arg, limit);
|
||||
if (arg->dest) {
|
||||
rb_io_write(arg->dest, arg->str);
|
||||
rb_str_resize(arg->str, 0);
|
||||
}
|
||||
|
||||
rb_ensure(dump, (VALUE)&c_arg, dump_ensure, (VALUE)&arg);
|
||||
RBASIC(arg.str)->klass = rb_cString;
|
||||
RBASIC(arg->str)->klass = rb_cString;
|
||||
clear_dump_arg(arg);
|
||||
RB_GC_GUARD(wrapper);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
@ -817,7 +815,6 @@ struct load_arg {
|
|||
st_table *data;
|
||||
VALUE proc;
|
||||
int taint;
|
||||
VALUE wrapper;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -825,22 +822,31 @@ check_load_arg(arg, sym)
|
|||
struct load_arg *arg;
|
||||
ID sym;
|
||||
{
|
||||
if (!DATA_PTR(arg->wrapper)) {
|
||||
if (!arg->symbols) {
|
||||
rb_raise(rb_eRuntimeError, "Marshal.load reentered at %s",
|
||||
rb_id2name(sym));
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_load_arg _((struct load_arg *arg));
|
||||
|
||||
static void
|
||||
mark_load_arg(ptr)
|
||||
void *ptr;
|
||||
{
|
||||
struct load_arg *p = ptr;
|
||||
if (!ptr)
|
||||
if (!p->symbols)
|
||||
return;
|
||||
rb_mark_tbl(p->data);
|
||||
}
|
||||
|
||||
static void
|
||||
free_load_arg(void *ptr)
|
||||
{
|
||||
clear_load_arg(ptr);
|
||||
xfree(ptr);
|
||||
}
|
||||
|
||||
static VALUE r_object _((struct load_arg *arg));
|
||||
|
||||
static int
|
||||
|
@ -1415,23 +1421,15 @@ r_object(arg)
|
|||
return r_object0(arg, arg->proc, 0, Qnil);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
load(arg)
|
||||
static void
|
||||
clear_load_arg(arg)
|
||||
struct load_arg *arg;
|
||||
{
|
||||
return r_object(arg);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
load_ensure(arg)
|
||||
struct load_arg *arg;
|
||||
{
|
||||
if (!DATA_PTR(arg->wrapper)) return 0;
|
||||
if (!arg->symbols) return;
|
||||
st_free_table(arg->symbols);
|
||||
arg->symbols = 0;
|
||||
st_free_table(arg->data);
|
||||
DATA_PTR(arg->wrapper) = 0;
|
||||
arg->wrapper = 0;
|
||||
return 0;
|
||||
arg->data = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1452,8 +1450,8 @@ marshal_load(argc, argv)
|
|||
{
|
||||
VALUE port, proc;
|
||||
int major, minor, taint = Qfalse;
|
||||
VALUE v;
|
||||
struct load_arg arg;
|
||||
VALUE v, wrapper;
|
||||
struct load_arg *arg;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &port, &proc);
|
||||
v = rb_check_string_type(port);
|
||||
|
@ -1470,17 +1468,18 @@ marshal_load(argc, argv)
|
|||
else {
|
||||
rb_raise(rb_eTypeError, "instance of IO needed");
|
||||
}
|
||||
arg.src = port;
|
||||
arg.offset = 0;
|
||||
arg.symbols = st_init_numtable();
|
||||
arg.data = st_init_numtable();
|
||||
arg.proc = 0;
|
||||
arg.wrapper = Data_Wrap_Struct(rb_cData, mark_load_arg, 0, &arg);
|
||||
arg.taint = taint;
|
||||
wrapper = Data_Make_Struct(rb_cData, struct load_arg, mark_load_arg, free_load_arg, arg);
|
||||
arg->src = port;
|
||||
arg->offset = 0;
|
||||
arg->symbols = st_init_numtable();
|
||||
arg->data = st_init_numtable();
|
||||
arg->proc = 0;
|
||||
arg->taint = taint;
|
||||
|
||||
major = r_byte(&arg);
|
||||
minor = r_byte(&arg);
|
||||
major = r_byte(arg);
|
||||
minor = r_byte(arg);
|
||||
if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
|
||||
clear_load_arg(arg);
|
||||
rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
|
||||
\tformat version %d.%d required; %d.%d given",
|
||||
MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
|
||||
|
@ -1491,8 +1490,10 @@ marshal_load(argc, argv)
|
|||
MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
|
||||
}
|
||||
|
||||
if (!NIL_P(proc)) arg.proc = proc;
|
||||
v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg);
|
||||
if (!NIL_P(proc)) arg->proc = proc;
|
||||
v = r_object(arg);
|
||||
clear_load_arg(arg);
|
||||
RB_GC_GUARD(wrapper);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,34 @@ class TestMarshal < Test::Unit::TestCase
|
|||
assert_equal("marshal data too short", e.message)
|
||||
end
|
||||
|
||||
class DumpTest
|
||||
def marshal_dump
|
||||
loop { Thread.pass }
|
||||
end
|
||||
end
|
||||
|
||||
class LoadTest
|
||||
def marshal_dump
|
||||
nil
|
||||
end
|
||||
def marshal_load(obj)
|
||||
loop { Thread.pass }
|
||||
end
|
||||
end
|
||||
|
||||
def test_context_switch
|
||||
o = DumpTest.new
|
||||
Thread.new { Marshal.dump(o) }
|
||||
GC.start
|
||||
assert(true, '[ruby-dev:39425]')
|
||||
|
||||
o = LoadTest.new
|
||||
m = Marshal.dump(o)
|
||||
Thread.new { Marshal.load(m) }
|
||||
GC.start
|
||||
assert(true, '[ruby-dev:39425]')
|
||||
end
|
||||
|
||||
def test_taint
|
||||
x = Object.new
|
||||
x.taint
|
||||
|
|
10
version.h
10
version.h
|
@ -1,15 +1,15 @@
|
|||
#define RUBY_VERSION "1.8.7"
|
||||
#define RUBY_RELEASE_DATE "2012-02-08"
|
||||
#define RUBY_RELEASE_DATE "2012-03-02"
|
||||
#define RUBY_VERSION_CODE 187
|
||||
#define RUBY_RELEASE_CODE 20120208
|
||||
#define RUBY_PATCHLEVEL 358
|
||||
#define RUBY_RELEASE_CODE 20120302
|
||||
#define RUBY_PATCHLEVEL 359
|
||||
|
||||
#define RUBY_VERSION_MAJOR 1
|
||||
#define RUBY_VERSION_MINOR 8
|
||||
#define RUBY_VERSION_TEENY 7
|
||||
#define RUBY_RELEASE_YEAR 2012
|
||||
#define RUBY_RELEASE_MONTH 2
|
||||
#define RUBY_RELEASE_DAY 8
|
||||
#define RUBY_RELEASE_MONTH 3
|
||||
#define RUBY_RELEASE_DAY 2
|
||||
|
||||
#ifdef RUBY_EXTERN
|
||||
RUBY_EXTERN const char ruby_version[];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue