e$B1sF#$G$9!#e(B
ObjectSpace
e$B$r;H$&$H<o!9$N%j%F%i%k$r=q$-49$($k$3$H$,$G$-$F$7$^$&$h$&$G$9$,!"e(B
e$B;EMM$G$7$g$&$+!#e(B
def foo
“foobarbaz”
end
ObjectSpace.each_object(String) do |s|
s.replace(“evil”) if /foobarbaz/ =~ s && !s.frozen?
end
p foo #=> “evil”
def bar
ls -l
end
ObjectSpace.each_object(String) do |s|
s.replace(“echo rm -rf /”) if /ls -l/ =~ s && !s.frozen?
end
p bar #=> “rm -rf /\n”
e$B%P%0$@$H$7$F!"%j%F%i%k$re(B freeze
e$B$9$k%Q%C%A$r=q$-$^$7$?$,!"e(BIRC e$B$G$Oe(B
- freeze e$B$G2r7h$9$k$N$,@5$7$$$d$jJ}$J$N$+e(B
- freeze e$B$7$F$be(B finalizer e$B$,IU$1BX$($G$-$k$N$G$O$J$$$+e(B
e$B$H$$$&46$8$N;XE&$,$"$j$^$7$?!#$I$&D>$9$N$,$h$$$G$7$g$&!#e(B
Index: compile.c
— compile.c (revision 22217)
+++ compile.c (working copy)
@@ -2120,7 +2120,7 @@
int cnt = 1;
debugp_param("nd_lit", lit);
- ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
-
ADD_INSN1(ret, nd_line(node), putobject,
rb_obj_freeze(node->nd_lit));while (list) {
COMPILE(ret, “each string”, list->nd_head);
@@ -2236,6 +2236,7 @@
rb_ary_push(ary, node->nd_head->nd_lit);
node = node->nd_next;
} -
rb_obj_freeze(ary); iseq_add_mark_object_compile_time(iseq, ary); ADD_INSN1(ret, nd_line(node_root), duparray, ary);
@@ -2708,7 +2709,7 @@
if (estr != 0) {
if (needstr != Qfalse) {
-
VALUE str = rb_str_new2(estr);
-
}VALUE str = rb_obj_freeze(rb_str_new2(estr)); ADD_INSN1(ret, nd_line(node), putstring, str); iseq_add_mark_object_compile_time(iseq, str);
@@ -4353,7 +4354,7 @@
case NODE_STR:{
debugp_param(“nd_lit”, node->nd_lit);
if (!poped) {
-
ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit);
-
ADD_INSN1(ret, nd_line(node), putstring,
rb_obj_freeze(node->nd_lit));
}
break;
}
@@ -4367,7 +4368,7 @@
}
case NODE_XSTR:{
ADD_CALL_RECEIVER(ret, nd_line(node));
- ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
-
ADD_INSN1(ret, nd_line(node), putobject,
rb_obj_freeze(node->nd_lit));
ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));if (poped) {