2007-06-27 20:26:31 +04:00
|
|
|
assert_equal %q{ok}, %q{
|
|
|
|
def m
|
|
|
|
a = :ok
|
|
|
|
$b = binding
|
|
|
|
end
|
|
|
|
m
|
|
|
|
eval('a', $b)
|
|
|
|
}
|
|
|
|
assert_equal %q{[:ok, :ok2]}, %q{
|
|
|
|
def m
|
|
|
|
a = :ok
|
|
|
|
$b = binding
|
|
|
|
end
|
|
|
|
m
|
|
|
|
eval('b = :ok2', $b)
|
|
|
|
eval('[a, b]', $b)
|
|
|
|
}
|
|
|
|
assert_equal %q{[nil, 1]}, %q{
|
|
|
|
$ans = []
|
|
|
|
def m
|
|
|
|
$b = binding
|
|
|
|
end
|
|
|
|
m
|
|
|
|
$ans << eval(%q{
|
|
|
|
$ans << eval(%q{
|
|
|
|
a
|
|
|
|
}, $b)
|
|
|
|
a = 1
|
|
|
|
}, $b)
|
|
|
|
$ans
|
|
|
|
}
|
|
|
|
assert_equal %q{C}, %q{
|
|
|
|
Const = :top
|
|
|
|
class C
|
|
|
|
Const = :C
|
|
|
|
def m
|
|
|
|
binding
|
|
|
|
end
|
|
|
|
end
|
|
|
|
eval('Const', C.new.m)
|
|
|
|
}
|
|
|
|
assert_equal %q{top}, %q{
|
|
|
|
Const = :top
|
|
|
|
a = 1
|
|
|
|
class C
|
|
|
|
Const = :C
|
|
|
|
def m
|
|
|
|
eval('Const', TOPLEVEL_BINDING)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
C.new.m
|
|
|
|
}
|
|
|
|
assert_equal %q{:ok
|
|
|
|
ok}, %q{
|
|
|
|
class C
|
|
|
|
$b = binding
|
|
|
|
end
|
|
|
|
eval %q{
|
|
|
|
def m
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
}, $b
|
|
|
|
p C.new.m
|
|
|
|
}
|
|
|
|
assert_equal %q{ok}, %q{
|
|
|
|
b = proc{
|
|
|
|
a = :ok
|
|
|
|
binding
|
|
|
|
}.call
|
|
|
|
a = :ng
|
|
|
|
eval("a", b)
|
|
|
|
}
|
|
|
|
assert_equal %q{C}, %q{
|
|
|
|
class C
|
|
|
|
def foo
|
|
|
|
binding
|
|
|
|
end
|
|
|
|
end
|
|
|
|
C.new.foo.eval("self.class.to_s")
|
|
|
|
}
|
|
|
|
assert_equal %q{1}, %q{
|
|
|
|
eval('1')
|
|
|
|
}
|
|
|
|
assert_equal %q{1}, %q{
|
|
|
|
eval('a=1; a')
|
|
|
|
}
|
|
|
|
assert_equal %q{1}, %q{
|
|
|
|
a = 1
|
|
|
|
eval('a')
|
|
|
|
}
|
|
|
|
assert_equal %q{ok}, %q{
|
2007-11-04 23:36:20 +03:00
|
|
|
__send__ :eval, %{
|
2007-06-27 20:26:31 +04:00
|
|
|
:ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_equal %q{ok}, %q{
|
2007-11-04 23:36:20 +03:00
|
|
|
1.__send__ :instance_eval, %{
|
2007-06-27 20:26:31 +04:00
|
|
|
:ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_equal %q{1}, %q{
|
|
|
|
1.instance_eval{
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_equal %q{foo}, %q{
|
|
|
|
'foo'.instance_eval{
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_equal %q{1}, %q{
|
Use Integer instead of Fixnum and Bignum.
* object.c, numeric.c, enum.c, ext/-test-/bignum/mul.c,
lib/rexml/quickpath.rb, lib/rexml/text.rb, lib/rexml/xpath_parser.rb,
lib/rubygems/specification.rb, lib/uri/generic.rb,
bootstraptest/test_eval.rb, basictest/test.rb,
test/-ext-/bignum/test_big2str.rb, test/-ext-/bignum/test_div.rb,
test/-ext-/bignum/test_mul.rb, test/-ext-/bignum/test_str2big.rb,
test/csv/test_data_converters.rb, test/date/test_date.rb,
test/json/test_json_generate.rb, test/minitest/test_minitest_mock.rb,
test/openssl/test_cipher.rb, test/rexml/test_jaxen.rb,
test/ruby/test_array.rb, test/ruby/test_basicinstructions.rb,
test/ruby/test_bignum.rb, test/ruby/test_case.rb,
test/ruby/test_class.rb, test/ruby/test_complex.rb,
test/ruby/test_enum.rb, test/ruby/test_eval.rb,
test/ruby/test_iseq.rb, test/ruby/test_literal.rb,
test/ruby/test_math.rb, test/ruby/test_module.rb,
test/ruby/test_numeric.rb, test/ruby/test_range.rb,
test/ruby/test_rational.rb, test/ruby/test_refinement.rb,
test/ruby/test_rubyvm.rb, test/ruby/test_struct.rb,
test/ruby/test_variable.rb, test/rubygems/test_gem_specification.rb,
test/thread/test_queue.rb: Use Integer instead of Fixnum and Bignum.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55029 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-17 16:15:57 +03:00
|
|
|
class Integer
|
2007-06-27 20:26:31 +04:00
|
|
|
Const = 1
|
|
|
|
end
|
|
|
|
1.instance_eval %{
|
|
|
|
Const
|
|
|
|
}
|
|
|
|
}
|
2021-12-03 02:53:39 +03:00
|
|
|
assert_equal %q{1}, %q{
|
|
|
|
class TrueClass
|
|
|
|
Const = 1
|
|
|
|
end
|
|
|
|
true.instance_eval %{
|
|
|
|
Const
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_equal %q{[:Const]}, %q{
|
|
|
|
mod = Module.new
|
|
|
|
mod.instance_eval %{
|
|
|
|
Const = 1
|
|
|
|
}
|
|
|
|
raise if defined?(Module::Const)
|
|
|
|
mod.singleton_class.constants
|
|
|
|
}
|
|
|
|
assert_equal %q{can't define singleton}, %q{
|
|
|
|
begin
|
|
|
|
123.instance_eval %{
|
|
|
|
Const = 1
|
|
|
|
}
|
|
|
|
"bad"
|
|
|
|
rescue TypeError => e
|
|
|
|
raise "bad" if defined?(Integer::Const)
|
|
|
|
e.message
|
|
|
|
end
|
|
|
|
}
|
2009-12-04 10:09:21 +03:00
|
|
|
assert_equal %q{top}, %q{
|
2007-06-27 20:26:31 +04:00
|
|
|
Const = :top
|
|
|
|
class C
|
|
|
|
Const = :C
|
|
|
|
end
|
|
|
|
C.module_eval{
|
|
|
|
Const
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_equal %q{C}, %q{
|
|
|
|
Const = :top
|
|
|
|
class C
|
|
|
|
Const = :C
|
|
|
|
end
|
|
|
|
C.class_eval %{
|
|
|
|
def m
|
|
|
|
Const
|
|
|
|
end
|
|
|
|
}
|
|
|
|
C.new.m
|
|
|
|
}
|
2011-03-31 11:52:40 +04:00
|
|
|
assert_equal %q{top}, %q{
|
2007-06-27 20:26:31 +04:00
|
|
|
Const = :top
|
|
|
|
class C
|
|
|
|
Const = :C
|
|
|
|
end
|
|
|
|
C.class_eval{
|
|
|
|
def m
|
|
|
|
Const
|
|
|
|
end
|
|
|
|
}
|
|
|
|
C.new.m
|
|
|
|
}
|
|
|
|
assert_equal %q{[:top, :C, :top, :C]}, %q{
|
|
|
|
Const = :top
|
|
|
|
class C
|
|
|
|
Const = :C
|
|
|
|
end
|
|
|
|
$nest = false
|
|
|
|
$ans = []
|
|
|
|
def m
|
|
|
|
$ans << Const
|
|
|
|
C.module_eval %{
|
|
|
|
$ans << Const
|
|
|
|
Boo = false unless defined? Boo
|
|
|
|
unless $nest
|
|
|
|
$nest = true
|
|
|
|
m
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
m
|
|
|
|
$ans
|
|
|
|
}
|
|
|
|
assert_equal %q{[10, main]}, %q{
|
|
|
|
$nested = false
|
|
|
|
$ans = []
|
|
|
|
$pr = proc{
|
|
|
|
$ans << self
|
|
|
|
unless $nested
|
|
|
|
$nested = true
|
|
|
|
$pr.call
|
|
|
|
end
|
|
|
|
}
|
|
|
|
class C
|
|
|
|
def initialize &b
|
|
|
|
10.instance_eval(&b)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
C.new(&$pr)
|
|
|
|
$ans
|
|
|
|
}
|
2007-12-18 17:53:55 +03:00
|
|
|
|
2007-12-19 19:10:54 +03:00
|
|
|
%w[break next redo].each do |keyword|
|
2019-10-22 19:05:14 +03:00
|
|
|
assert_match %r"Can't escape from eval with #{keyword}\b", %{
|
2021-12-13 10:48:57 +03:00
|
|
|
$stderr = STDOUT
|
2007-12-19 19:10:54 +03:00
|
|
|
begin
|
|
|
|
eval "0 rescue #{keyword}"
|
|
|
|
rescue SyntaxError => e
|
|
|
|
e.message
|
|
|
|
end
|
|
|
|
}, '[ruby-dev:31372]'
|
|
|
|
end
|
2008-01-03 13:48:35 +03:00
|
|
|
|
2023-12-22 03:01:16 +03:00
|
|
|
assert_normal_exit %{
|
|
|
|
$stderr = STDOUT
|
|
|
|
5000.times do
|
|
|
|
begin
|
|
|
|
eval "0 rescue break"
|
|
|
|
rescue SyntaxError
|
|
|
|
end
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
2008-01-03 13:48:35 +03:00
|
|
|
assert_normal_exit %q{
|
2021-12-13 10:48:57 +03:00
|
|
|
$stderr = STDOUT
|
2008-01-03 13:48:35 +03:00
|
|
|
class Foo
|
|
|
|
def self.add_method
|
|
|
|
class_eval("def some-bad-name; puts 'hello' unless @some_variable.some_function(''); end")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Foo.add_method
|
|
|
|
}, '[ruby-core:14556] reported by Frederick Cheung'
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-19 07:08:50 +04:00
|
|
|
|
|
|
|
assert_equal 'ok', %q{
|
|
|
|
class Module
|
|
|
|
def my_module_eval(&block)
|
|
|
|
module_eval(&block)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class String
|
|
|
|
Integer.my_module_eval do
|
|
|
|
def hoge; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) &&
|
|
|
|
!String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge)
|
|
|
|
:ok
|
|
|
|
else
|
|
|
|
:ng
|
|
|
|
end
|
|
|
|
}, "[ruby-dev:34236]"
|
2008-05-19 09:20:21 +04:00
|
|
|
|
|
|
|
assert_equal 'ok', %q{
|
|
|
|
begin
|
|
|
|
eval("class nil::Foo; end")
|
|
|
|
:ng
|
|
|
|
rescue Exception
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
}
|
2008-05-19 22:47:56 +04:00
|
|
|
|
|
|
|
assert_equal 'ok', %q{
|
|
|
|
begin
|
|
|
|
0.instance_eval { def m() :m end }
|
|
|
|
1.m
|
|
|
|
:ng
|
|
|
|
rescue Exception
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
}, '[ruby-dev:34579]'
|
|
|
|
|
|
|
|
assert_equal 'ok', %q{
|
|
|
|
begin
|
2020-03-28 01:08:52 +03:00
|
|
|
class A
|
|
|
|
12.instance_eval { @@a }
|
|
|
|
end
|
2008-05-19 22:47:56 +04:00
|
|
|
rescue NameError
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
}, '[ruby-core:16794]'
|
|
|
|
|
|
|
|
assert_equal 'ok', %q{
|
|
|
|
begin
|
2020-03-28 01:08:52 +03:00
|
|
|
class A
|
|
|
|
12.instance_exec { @@a }
|
|
|
|
end
|
2008-05-19 22:47:56 +04:00
|
|
|
rescue NameError
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
}, '[ruby-core:16794]'
|
|
|
|
|
|
|
|
assert_equal 'ok', %q{
|
2012-08-06 19:31:13 +04:00
|
|
|
nil.instance_eval {
|
|
|
|
def defd_using_instance_eval() :ok end
|
|
|
|
}
|
|
|
|
nil.defd_using_instance_eval
|
|
|
|
}, '[ruby-core:28324]'
|
2008-05-19 22:47:56 +04:00
|
|
|
|
|
|
|
assert_equal 'ok', %q{
|
2012-08-06 19:31:13 +04:00
|
|
|
nil.instance_exec {
|
|
|
|
def defd_using_instance_exec() :ok end
|
|
|
|
}
|
|
|
|
nil.defd_using_instance_exec
|
|
|
|
}, '[ruby-core:28324]'
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-11 01:46:43 +04:00
|
|
|
|
|
|
|
assert_normal_exit %q{
|
|
|
|
eval("", method(:proc).call {}.binding)
|
|
|
|
}
|
2008-12-27 04:15:56 +03:00
|
|
|
|
2010-05-09 22:41:51 +04:00
|
|
|
assert_equal "", %q{
|
2008-12-27 04:15:56 +03:00
|
|
|
b = binding
|
|
|
|
10.times{
|
|
|
|
eval('', b)
|
|
|
|
}
|
|
|
|
begin
|
|
|
|
eval('1.times{raise}', b)
|
|
|
|
rescue => e
|
|
|
|
e.message
|
|
|
|
end
|
2009-08-26 07:37:08 +04:00
|
|
|
}, '[ruby-dev:35392]'
|
2008-12-27 04:15:56 +03:00
|
|
|
|
2009-08-26 07:37:08 +04:00
|
|
|
assert_equal "[:x]", %q{
|
|
|
|
def kaboom!
|
|
|
|
yield.eval("local_variables")
|
|
|
|
end
|
|
|
|
|
|
|
|
for x in enum_for(:kaboom!)
|
|
|
|
binding
|
|
|
|
end
|
|
|
|
}, '[ruby-core:25125]'
|
2009-09-23 06:28:08 +04:00
|
|
|
|
|
|
|
assert_normal_exit %q{
|
|
|
|
hash = {}
|
|
|
|
("aaaa".."matz").each_with_index do |s, i|
|
|
|
|
hash[s] = i
|
|
|
|
end
|
|
|
|
begin
|
|
|
|
eval "class C; @@h = #{hash.inspect}; end"
|
|
|
|
end
|
|
|
|
}, '[ruby-core:25714]'
|
* iseq.c, vm_eval.c: set th->base_block properly.
th->base_block is information for (a) parsing, (b) compiling
and (c) setting up the frame to execute the program passed by
`eval' method. For example, (1) parser need to know up-level
variables to detect it is variable or method without paren.
Befor (a), (b) and (c), VM set th->base_block by passed bindng
(or previous frame information). After execute (a), (b) and (c),
VM should clear th->base_block. However, if (a), (b) or (c)
raises an exception, then th->base_block is not cleared.
Problem is that the uncleared value th->balo_block is used for
irrelevant iseq compilation. It causes SEGV or critical error.
I tried to solve this problem: to clear them before exception,
but finally I found out that it is difficult to do it (Ruby
program can be run in many places).
Because of this background, I set th->base_block before
compiling iseq and restore it after compiling.
Basically, th->base_block is dirty hack (similar to global
variable) and this patch is also dirty.
* bootstraptest/test_eval.rb: add a test for above.
* internal.h: remove unused decl.
* iseq.c (rb_iseq_compile_with_option): add base_block parameter.
set th->base_block before compation and restore it after
compilation.
* ruby.c (require_libraries): pass 0 as base_block instead of
setting th->base_block
* tool/compile_prelude.rb (prelude_eval): apply above changes.
* vm.c, vm_eval.c: ditto.
* vm_core.h: add comments.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36179 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-22 13:32:56 +04:00
|
|
|
|
|
|
|
assert_normal_exit %q{
|
|
|
|
begin
|
|
|
|
eval("# encoding:utf-16le\nfoo")
|
|
|
|
rescue Exception => e
|
|
|
|
p e
|
|
|
|
RubyVM::InstructionSequence.compile("p:hello")
|
|
|
|
end
|
|
|
|
}, 'check escaping the internal value th->base_block'
|
|
|
|
|
2024-03-15 14:38:39 +03:00
|
|
|
assert_equal "false", <<~RUBY, "literal strings are mutable", "--disable-frozen-string-literal"
|
|
|
|
eval("'test'").frozen?
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
assert_equal "false", <<~RUBY, "literal strings are mutable", "--disable-frozen-string-literal", frozen_string_literal: true
|
|
|
|
eval("'test'").frozen?
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
assert_equal "true", <<~RUBY, "literal strings are frozen", "--enable-frozen-string-literal"
|
|
|
|
eval("'test'").frozen?
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
assert_equal "true", <<~RUBY, "literal strings are frozen", "--enable-frozen-string-literal", frozen_string_literal: false
|
|
|
|
eval("'test'").frozen?
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
assert_equal "false", <<~RUBY, "__FILE__ is mutable", "--disable-frozen-string-literal"
|
|
|
|
eval("__FILE__").frozen?
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
assert_equal "false", <<~RUBY, "__FILE__ is mutable", "--disable-frozen-string-literal", frozen_string_literal: true
|
|
|
|
eval("__FILE__").frozen?
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
assert_equal "true", <<~RUBY, "__FILE__ is frozen", "--enable-frozen-string-literal"
|
|
|
|
eval("__FILE__").frozen?
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
assert_equal "true", <<~RUBY, "__FILE__ is frozen", "--enable-frozen-string-literal", frozen_string_literal: false
|
|
|
|
eval("__FILE__").frozen?
|
|
|
|
RUBY
|