* 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
This commit is contained in:
nobu 2012-09-16 02:39:18 +00:00
Родитель 4a906510a2
Коммит 59383b1f9c
3 изменённых файлов: 69 добавлений и 3 удалений

Просмотреть файл

@ -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

15
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();
}

Просмотреть файл

@ -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