Backport #4339 » ruby-1.8.7-marshal.patch
ruby-1.8.7-p352/marshal.c | ||
---|---|---|
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 {
|
||
... | ... | |
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(void *ptr)
|
||
{
|
||
clear_dump_arg(ptr);
|
||
xfree(ptr);
|
||
}
|
||
static VALUE
|
||
... | ... | |
}
|
||
}
|
||
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)
|
||
struct dump_arg *arg;
|
||
{
|
||
if (!DATA_PTR(arg->wrapper)) return 0;
|
||
static void
|
||
clear_dump_arg(struct dump_arg *arg)
|
||
{
|
||
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;
|
||
}
|
||
/*
|
||
... | ... | |
{
|
||
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);
|
||
... | ... | |
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);
|
||
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;
|
||
}
|
||
c_arg.obj = obj;
|
||
c_arg.arg = &arg;
|
||
c_arg.limit = limit;
|
||
w_byte(MARSHAL_MAJOR, &arg);
|
||
w_byte(MARSHAL_MINOR, &arg);
|
||
rb_ensure(dump, (VALUE)&c_arg, dump_ensure, (VALUE)&arg);
|
||
RBASIC(arg.str)->klass = rb_cString;
|
||
port = arg->str;
|
||
}
|
||
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);
|
||
}
|
||
RBASIC(arg->str)->klass = rb_cString;
|
||
clear_dump_arg(arg);
|
||
RB_GC_GUARD(wrapper);
|
||
return port;
|
||
}
|
||
... | ... | |
st_table *data;
|
||
VALUE proc;
|
||
int taint;
|
||
VALUE wrapper;
|
||
};
|
||
static void
|
||
... | ... | |
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));
|
||
... | ... | |
return r_object0(arg, arg->proc, 0, Qnil);
|
||
}
|
||
static VALUE
|
||
load(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;
|
||
static void
|
||
clear_load_arg(struct load_arg *arg)
|
||
{
|
||
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;
|
||
}
|
||
/*
|
||
... | ... | |
{
|
||
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);
|
||
... | ... | |
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;
|
||
major = r_byte(&arg);
|
||
minor = r_byte(&arg);
|
||
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);
|
||
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);
|
||
... | ... | |
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;
|
||
}
|
- « Previous
- 1
- 2
- 3
- Next »