зеркало из https://github.com/github/ruby.git
prism_compile.c: X_STRING should be frozen
The backtick method recieves a frozen string unless it is interpolated. Otherwise the string held in the ISeq could be mutated by a custom backtick method.
This commit is contained in:
Родитель
b2f8de3d9d
Коммит
9183101aa7
|
@ -8352,7 +8352,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
// `foo`
|
||||
// ^^^^^
|
||||
const pm_x_string_node_t *cast = (const pm_x_string_node_t *) node;
|
||||
VALUE value = parse_string_encoded(scope_node, node, &cast->unescaped);
|
||||
VALUE value = rb_fstring(parse_string_encoded(scope_node, node, &cast->unescaped));
|
||||
|
||||
PUSH_INSN(ret, location, putself);
|
||||
PUSH_INSN1(ret, location, putobject, value);
|
||||
|
|
|
@ -5,6 +5,45 @@ describe "``" do
|
|||
ip = 'world'
|
||||
`echo disc #{ip}`.should == "disc world\n"
|
||||
end
|
||||
|
||||
it "can be redefined and receive a frozen string as argument" do
|
||||
called = false
|
||||
runner = Object.new
|
||||
|
||||
runner.singleton_class.define_method(:`) do |str|
|
||||
called = true
|
||||
|
||||
str.should == "test command"
|
||||
str.frozen?.should == true
|
||||
end
|
||||
|
||||
runner.instance_exec do
|
||||
`test command`
|
||||
end
|
||||
|
||||
called.should == true
|
||||
end
|
||||
|
||||
it "the argument isn't frozen if it contains interpolation" do
|
||||
called = false
|
||||
runner = Object.new
|
||||
|
||||
runner.singleton_class.define_method(:`) do |str|
|
||||
called = true
|
||||
|
||||
str.should == "test command"
|
||||
str.frozen?.should == false
|
||||
str << "mutated"
|
||||
end
|
||||
|
||||
2.times do
|
||||
runner.instance_exec do
|
||||
`test #{:command}`
|
||||
end
|
||||
end
|
||||
|
||||
called.should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe "%x" do
|
||||
|
@ -12,4 +51,43 @@ describe "%x" do
|
|||
ip = 'world'
|
||||
%x(echo disc #{ip}).should == "disc world\n"
|
||||
end
|
||||
|
||||
it "can be redefined and receive a frozen string as argument" do
|
||||
called = false
|
||||
runner = Object.new
|
||||
|
||||
runner.singleton_class.define_method(:`) do |str|
|
||||
called = true
|
||||
|
||||
str.should == "test command"
|
||||
str.frozen?.should == true
|
||||
end
|
||||
|
||||
runner.instance_exec do
|
||||
%x{test command}
|
||||
end
|
||||
|
||||
called.should == true
|
||||
end
|
||||
|
||||
it "the argument isn't frozen if it contains interpolation" do
|
||||
called = false
|
||||
runner = Object.new
|
||||
|
||||
runner.singleton_class.define_method(:`) do |str|
|
||||
called = true
|
||||
|
||||
str.should == "test command"
|
||||
str.frozen?.should == false
|
||||
str << "mutated"
|
||||
end
|
||||
|
||||
2.times do
|
||||
runner.instance_exec do
|
||||
%x{test #{:command}}
|
||||
end
|
||||
end
|
||||
|
||||
called.should == true
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче