ruby-changes:24928
From: nobu <ko1@a...>
Date: Sun, 16 Sep 2012 11:39:35 +0900 (JST)
Subject: [ruby-changes:24928] nobu:r36980 (trunk): io.c: io_set_read_length
nobu 2012-09-16 11:39:18 +0900 (Sun, 16 Sep 2012) New Revision: 36980 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36980 Log: io.c: io_set_read_length * io.c (io_set_read_length): if the read length equals to the buffer string size then nothing to do. or ensure the string modifiable before setting the length only when the former is shorter. based on the patch in [ruby-core:47541] by Hiroshi Shirosaki. [ruby-core:46586] [Bug #6764] Modified files: trunk/ChangeLog trunk/io.c trunk/test/ruby/test_io.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 36979) +++ ChangeLog (revision 36980) @@ -1,3 +1,11 @@ +Sun Sep 16 11:39:12 2012 Nobuyoshi Nakada <nobu@r...> + + * io.c (io_set_read_length): if the read length equals to the buffer + string size then nothing to do. or ensure the string modifiable + before setting the length only when the former is shorter. based on + the patch in [ruby-core:47541] by Hiroshi Shirosaki. + [ruby-core:46586] [Bug #6764] + Sun Sep 16 08:57:52 2012 Nobuyoshi Nakada <nobu@r...> * configure.in (strict_warnflags): separate strict flags from Index: io.c =================================================================== --- io.c (revision 36979) +++ io.c (revision 36980) @@ -2158,6 +2158,15 @@ rb_str_modify_expand(*str, len); } +static void +io_set_read_length(VALUE str, long n) +{ + if (RSTRING_LEN(str) != n) { + rb_str_modify(str); + rb_str_set_len(str, n); + } +} + static VALUE read_all(rb_io_t *fptr, long siz, VALUE str) { @@ -2281,7 +2290,7 @@ rb_sys_fail_path(fptr->pathv); } } - rb_str_set_len(str, n); + io_set_read_length(str, n); if (n == 0) return Qnil; @@ -2602,7 +2611,7 @@ previous_mode = set_binary_mode_with_seek_cur(fptr); #endif n = io_fread(str, 0, len, fptr); - rb_str_set_len(str, n); + io_set_read_length(str, n); #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) if (previous_mode == O_TEXT) { setmode(fptr->fd, O_TEXT); @@ -4390,7 +4399,7 @@ if (n == -1) { rb_sys_fail_path(fptr->pathv); } - rb_str_set_len(str, n); + io_set_read_length(str, n); if (n == 0 && ilen > 0) { rb_eof_error(); } Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 36979) +++ test/ruby/test_io.rb (revision 36980) @@ -2446,5 +2446,54 @@ assert_raise(Errno::ESPIPE, Errno::EINVAL) { w.advise(:willneed) } end end + + def assert_buffer_not_raise_shared_string_error + bug6764 = '[ruby-core:46586]' + size = 28 + data = [*"a".."z", *"A".."Z"].shuffle.join("") + t = Tempfile.new("test_io") + t.write(data) + t.close + w = Tempfile.new("test_io") + assert_nothing_raised(RuntimeError, bug6764) do + File.open(t.path, "r") do |r| + buf = '' + while yield(r, size, buf) + w << buf + end + end + end + w.close + assert_equal(data, w.open.read, bug6764) + ensure + t.close! + w.close! + end + + def test_read_buffer_not_raise_shared_string_error + assert_buffer_not_raise_shared_string_error do |r, size, buf| + r.read(size, buf) + end + end + + def test_sysread_buffer_not_raise_shared_string_error + assert_buffer_not_raise_shared_string_error do |r, size, buf| + begin + r.sysread(size, buf) + rescue EOFError + nil + end + end + end + + def test_readpartial_buffer_not_raise_shared_string_error + assert_buffer_not_raise_shared_string_error do |r, size, buf| + begin + r.readpartial(size, buf) + rescue EOFError + nil + end + end + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/