mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix corruption in ARGF.inplace
Extension string stored in `ARGF.inplace` is created using an api designed for C string constants to create a Ruby string that points at another Ruby string. When the original string is swept, the extension string gets corrupted. Reproduction script (on MacOS): ```ruby #!/usr/bin/ruby -pi.bak BEGIN { GC.start(full_mark: true) arr = [] 1000000.times do |x| arr << "fooo#{x}" end } puts "hello" ``` Co-Authored-By: Matt Valentine-House <31869+eightbitraptor@users.noreply.github.com>
This commit is contained in:
parent
e79cdcf61b
commit
166cacc505
Notes:
git
2020-08-12 17:54:40 +09:00
Merged: https://github.com/ruby/ruby/pull/3409 Merged-By: nobu <nobu@ruby-lang.org>
2 changed files with 16 additions and 1 deletions
2
io.c
2
io.c
|
@ -12988,7 +12988,7 @@ opt_i_set(VALUE val, ID id, VALUE *var)
|
|||
void
|
||||
ruby_set_inplace_mode(const char *suffix)
|
||||
{
|
||||
ARGF.inplace = !suffix ? Qfalse : !*suffix ? Qnil : rb_fstring_cstr(suffix);
|
||||
ARGF.inplace = !suffix ? Qfalse : !*suffix ? Qnil : rb_str_new(suffix, strlen(suffix));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -387,6 +387,21 @@ class TestArgf < Test::Unit::TestCase
|
|||
assert_equal("foo", File.read(name+suffix))
|
||||
end
|
||||
|
||||
def test_inplace_bug_17117
|
||||
assert_in_out_err(["-", @t1.path], "#{<<~"{#"}#{<<~'};'}")
|
||||
{#
|
||||
#!/usr/bin/ruby -pi.bak
|
||||
BEGIN {
|
||||
GC.start
|
||||
arr = []
|
||||
1000000.times { |x| arr << "fooo#{x}" }
|
||||
}
|
||||
puts "hello"
|
||||
};
|
||||
assert_equal("hello\n1\nhello\n2\n", File.read(@t1.path))
|
||||
assert_equal("1\n2\n", File.read("#{@t1.path}.bak"))
|
||||
end
|
||||
|
||||
def test_encoding
|
||||
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
|
||||
{#
|
||||
|
|
Loading…
Add table
Reference in a new issue