e$B%A%1%C%He(B #3463 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)
e$BC4Ev<Te(B Nobuyoshi N.e$B$K%;%C%He(B
e$B1sF#$G$9!#e(B
redmine e$B$,$J$+$@$5$s$N%a!<%k$r=&$$Mn$H$7$F$$$k$N$G!“5-O?$N$?$a$Ke(B
e$B%Q%C%A$N$”$k$H$3$@$1E=$C$F$*$-$^$9!#e(B
e$B$G!":F8=%3!<%I$,$J$$$N$G3NG’$O$G$-$J$$$N$G$9$,!"e(B#2386
e$B$b$3$l$G$Oe(B
e$B$J$$$+$H;W$$$^$7$?!#e(B
marshal_dump + GC e$B$C$]$$$H$3$m$,;w$F$$$k$h$&$J!#e(B
e$B6a1J$5$se(B GJ e$B$G$9!#e(B
e$B$J$+$@$G$9!#e(B
At Wed, 23 Jun 2010 09:27:11 +0900,
Tomoyuki C. wrote in [ruby-dev:41677]:
finaliser_at_exite$B$N;~E@$G$O!"?7$7$$%*%V%8%'%/%H$,3d$jEv$F$i$l$ke(B
e$B$3$H$O9M$($J$/$F$b$$$$$s$8$c$J$$$+$H;W$$$^$9$,!#e(B
clear_dump_arg e$B$Ke(B arg->str e$B$Ne(B flags e$B$,e(B 0 e$B$GMh$F$?;~$O!"2<$N$h$&$Je(B
e$B%3!<%k%9%?%C%/$G$7$?!#IaDL$K%a%=%C%I8F$S=P$7$N4V$KCY1d$5$l$?e(B
free e$B4X?t$N8F$S=P$7$,64$_9~$^$l$F$$$k$h$&$G$9!#e(B
e$B$&$C$+$j$7$F$^$7$?!#e(B
e$B$H$3$m$G!"C1$K6=L#$+$i?V$$$F$$?$$$N$G$9$,!"$J$<$3$N$h$&$Ke(B
T_DATAe$B7?%*%V%8%'%/%H$N2rJ|$OCY1d$5$l$F$k$s$G$7$g$&!#e(B
GC e$B$G$NDd;;~4V$rJ,;6$5$;$k$?$a$G$7$g$&$+!)e(B
dfreee$B4X?t$N8F$S=P$7Cf$K%*%V%8%'%/%H$N3d$jEv$F$r$9$k3HD%%i%$%V%ie(B
e$B%j$,$"$C$?$N$G!"e(Bmark phasee$B$HJ,N%$7$?$s$G$7$?!#e(B
e$B$D$$$G$K!"e(BTAINTEDe$B$He(BUNTRUSTEDe$B$r$R$H$^$H$a$K07$&$h$&$K$7$F$_$^$7$?!#e(B
e$B$3$l$G$I$&$G$7$g$&!#e(B
diff --git a/marshal.c b/marshal.c
index fa91afa…3263a57 100644
— a/marshal.c
+++ b/marshal.c
@@ -131,14 +131,16 @@ rb_marshal_define_compat(VALUE newclass, VALUE
oldclass, VALUE (*dumper)(VALUE),
st_insert(compat_allocator_tbl, (st_data_t)allocator,
(st_data_t)compat);
}
+#define MARSHAL_INFECTION (FL_TAINT|FL_UNTRUSTED)
+typedef char ruby_check_marshal_viral_flags[MARSHAL_INFECTION ==
(int)MARSHAL_INFECTION ? 1 : -1];
+
struct dump_arg {
VALUE str, dest;
st_table *symbols;
st_table *data;
- int taint;
- int untrust;
st_table *compat_tbl;
st_table *encodings;
- int infection;
};
struct dump_call_arg {
@@ -224,9 +226,8 @@ w_nbyte(const char *s, long n, struct dump_arg *arg)
{
VALUE buf = arg->str;
rb_str_buf_cat(buf, s, n);
- RBASIC(buf)->flags |= arg->infection;
if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
- if (arg->taint) OBJ_TAINT(buf);
- if (arg->untrust) OBJ_UNTRUST(buf);
rb_io_write(arg->dest, buf);
rb_str_resize(buf, 0);
}
@@ -636,8 +637,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
w_symbol(SYM2ID(obj), arg);
}
else { - if (OBJ_TAINTED(obj)) arg->taint = TRUE;
- if (OBJ_UNTRUSTED(obj)) arg->untrust = TRUE;
-
arg->infection |= FL_TEST(obj, MARSHAL_INFECTION);
if (rb_respond_to(obj, s_mdump)) {
volatile VALUE v;
@@ -856,12 +856,6 @@ clear_dump_arg(struct dump_arg *arg)
st_free_table(arg->encodings);
arg->encodings = 0;
}
- if (arg->taint) {
- OBJ_TAINT(arg->str);
- }
- if (arg->untrust) {
- OBJ_UNTRUST(arg->str);
- }
}
/*
@@ -922,8 +916,7 @@ marshal_dump(int argc, VALUE *argv)
arg->dest = 0;
arg->symbols = st_init_numtable();
arg->data = st_init_numtable();
- arg->taint = FALSE;
- arg->untrust = FALSE;
- arg->infection = 0;
arg->compat_tbl = st_init_numtable();
arg->encodings = 0;
arg->str = rb_str_buf_new(0);
@@ -962,9 +955,8 @@ struct load_arg {
st_table *symbols;
st_table *data;
VALUE proc;
- int taint;
- int untrust;
st_table *compat_tbl;
- int infection;
};
static void
@@ -1118,8 +1110,7 @@ r_bytes0(long len, struct load_arg *arg)
if (NIL_P(str)) goto too_short;
StringValue(str);
if (RSTRING_LEN(str) != len) goto too_short;
- if (OBJ_TAINTED(str)) arg->taint = TRUE;
- if (OBJ_UNTRUSTED(str)) arg->untrust = TRUE;
- arg->infection |= FL_TEST(str, MARSHAL_INFECTION);
}
return str;
}
@@ -1220,15 +1211,10 @@ r_entry0(VALUE v, st_index_t num, struct
load_arg *arg)
else {
st_insert(arg->data, num, (st_data_t)v);
}
- if (arg->taint) {
-
OBJ_TAINT(v);
-
if ((VALUE)real_obj != Qundef)
-
OBJ_TAINT((VALUE)real_obj);
- }
- if (arg->untrust) {
-
OBJ_UNTRUST(v);
-
if ((VALUE)real_obj != Qundef)
-
OBJ_UNTRUST((VALUE)real_obj);
- if (arg->infection) {
- FL_SET(v, arg->infection);
- if ((VALUE)real_obj != Qundef)
-
}FL_SET((VALUE)real_obj, arg->infection);
return v;
}
@@ -1765,7 +1751,7 @@ static VALUE
marshal_load(int argc, VALUE *argv)
{
VALUE port, proc;
- int major, minor, taint = FALSE;
- int major, minor, infection = 0;
VALUE v;
volatile VALUE wrapper;
struct load_arg *arg;
@@ -1773,21 +1759,20 @@ marshal_load(int argc, VALUE *argv)
rb_scan_args(argc, argv, “11”, &port, &proc);
v = rb_check_string_type(port);
if (!NIL_P(v)) {
- taint = OBJ_TAINTED(port); /* original taintedness */
- infection = FL_TEST(port, MARSHAL_INFECTION); /* original taintedness
*/
port = v;
}
else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port,
s_read)) {
if (rb_respond_to(port, s_binmode)) {
rb_funcall2(port, s_binmode, 0, 0);
}
- taint = TRUE;
- infection = FL_TAINT | FL_TEST(port, FL_UNTRUSTED);;
}
else {
rb_raise(rb_eTypeError, “instance of IO needed”);
}
wrapper = TypedData_Make_Struct(rb_cData, struct load_arg,
&load_arg_data, arg);
- arg->taint = taint;
- arg->untrust = OBJ_UNTRUSTED(port);
- arg->infection = infection;
arg->src = port;
arg->offset = 0;
arg->symbols = st_init_numtable();