ruby-changes:62559
From: Peter <ko1@a...>
Date: Wed, 12 Aug 2020 17:54:32 +0900 (JST)
Subject: [ruby-changes:62559] 166cacc505 (master): Fix corruption in ARGF.inplace
https://git.ruby-lang.org/ruby.git/commit/?id=166cacc505 From 166cacc505e5a0d807712e9cb5b6919a7d190a6e Mon Sep 17 00:00:00 2001 From: Peter Zhu <peter@p...> Date: Wed, 12 Aug 2020 04:54:09 -0400 Subject: 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@u...> diff --git a/io.c b/io.c index 2760e6c..5e4fdd5 100644 --- a/io.c +++ b/io.c @@ -12988,7 +12988,7 @@ opt_i_set(VALUE val, ID id, VALUE *var) https://github.com/ruby/ruby/blob/trunk/io.c#L12988 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)); } /* diff --git a/test/ruby/test_argf.rb b/test/ruby/test_argf.rb index 277fa36..4734d5b 100644 --- a/test/ruby/test_argf.rb +++ b/test/ruby/test_argf.rb @@ -387,6 +387,21 @@ class TestArgf < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_argf.rb#L387 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| {# -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/