[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]