2007年 09月 26日

環境に一切干渉できない eval

#!ruby -Ku

# クラス化して Module.new.instance_eval するようにしてみる。
# まだなんかあるかなぁ……

class SafeEval

	def safe_eval(code, tm=1)
		result = nil
		tg = nil
		th = Thread.start do
			# スレッドグループを作り、
			# 新たなスレッドはすべてこれに所属させる。
			tg = ThreadGroup.new.add(Thread.current)
			$SAFE  = 4
			result = Module.new.instance_eval(code)
		end.join(tm)
		# 生成されたスレッドをすべて削除
		tg.list.each {|t| t.kill }
		raise TimeoutError unless th # タイムアウトした場合 Thread は nil を返す
		result
	end

	alias eval safe_eval

end

if $0 == __FILE__
	require "test/unit"
	class SafeEvalTest < Test::Unit::TestCase

		def setup
			@t = SafeEval.new.taint
		end

		def test_safe
			assert_raise(SecurityError) do
				@t.safe_eval("puts ''")
			end

			assert_raise(SecurityError) do
				@t.safe_eval("$foo = :foo")
			end

			assert_nothing_raised(SecurityError) do
				@t.safe_eval("def hoge; end")
			end

			@t.safe_eval <<-EOS
				def safe_eval(code)
					"Nice boat."
				end
			EOS
			assert_not_equal("Nice boat", @t.safe_eval("nil"))

		end

		def test_safe_access
			assert_raise(NoMethodError) do
				@t.safe_eval("@foo << :bar")
			end
			assert_equal(nil, @t.instance_variable_get(:@foo))

			assert_raise(NameError) do
				@t.safe_eval("@@foo")
			end
		end

	end
end

まだなんかあるかなぁ……
SafeEval クラスは毎回つかいすてる。
インスタンス変数は無名 Module でさよならする。
クラス変数は SafeEval クラスが untaint である限りつくれない。

chokan 更新

Eval はとりあえずオフにしたまま。

とりあえず改行をちゃんととりのぞくように
http://lab.lowreal.net/trac/changeset/879
invite されたときほいほいついていかないように
http://lab.lowreal.net/trac/changeset/880
operator に設定されたマスクからだけ invite をうけるように
http://lab.lowreal.net/trac/changeset/882
@もらったらくれた人の@を奪ってから@を捨てるプラグイン
http://lab.lowreal.net/trac/browser/chokan/trunk/plugins/always_no_op.rb

@うばうのは AutoOP でループしないようにだけど、普通は JOIN で処理してて大丈夫だろうから奪わなくてもいいかもしれない。チャンネル唯一のオペレータが chokan に@あげるとチャンネルのオペがいなくなる。

2時ぐらいからずっと寝てた。仕事しろ。


海岸に近い、三日月型の地域。回りは山で、斜面が結構きつい。鎌倉に近いけど、もっと狭い。街の中心に HMV タワーというのがある。そんなに大きいわけではない。そして、それを新しくしたタワーが建築途中、だったのだけど、中止されて、既にあまり綺麗ではない。中世ヨーロッパっぽい模様のタワーなのだけど、土台のところだけ。
そこそこよく見る、坂道のわかれ道はこの街の少しはずれの場所だった。

なにか大きな大災害がおこる。内容はよく覚えてない。とにかくたくさん人が死ぬ。