aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-16 02:39:18 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-16 02:39:18 +0000
commit59383b1f9cffc2815d4a213710be253d9b6114d4 (patch)
treee34c754cdde6b80559a115615e98b8747a6f5cf5
parent4a906510a289475bb4baf662a70e07e6b01fad3b (diff)
downloadruby-59383b1f9cffc2815d4a213710be253d9b6114d4.tar.gz
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36980 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog8
-rw-r--r--io.c15
-rw-r--r--test/ruby/test_io.rb49
3 files changed, 69 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 5aed647b40..8ef472344d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sun Sep 16 11:39:12 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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@ruby-lang.org>
* configure.in (strict_warnflags): separate strict flags from
diff --git a/io.c b/io.c
index 24f141c825..e007512135 100644
--- a/io.c
+++ b/io.c
@@ -2158,6 +2158,15 @@ io_setstrbuf(VALUE *str, long len)
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 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
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 @@ io_read(int argc, VALUE *argv, VALUE io)
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 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
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();
}
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index f165c640b1..e266f115ba 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2446,5 +2446,54 @@ End
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