From 2152188f41bf2a5067e84a4404b48b2282a9dd55 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 7 Oct 2010 19:56:57 -0700 Subject: trywrite: fix stupid off-by-one error causing corrupt writes Oops! --- ext/kgio/read_write.c | 2 +- test/lib_read_write.rb | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/ext/kgio/read_write.c b/ext/kgio/read_write.c index 47160d6..0ee7866 100644 --- a/ext/kgio/read_write.c +++ b/ext/kgio/read_write.c @@ -233,7 +233,7 @@ done: a->ptr = RSTRING_PTR(a->buf) + written; return -1; } else if (written > 0) { - a->buf = rb_str_new(a->ptr + n, a->len - n); + a->buf = rb_str_new(a->ptr, a->len); } else { a->buf = mKgio_WaitWritable; } diff --git a/test/lib_read_write.rb b/test/lib_read_write.rb index 146c222..e147566 100644 --- a/test/lib_read_write.rb +++ b/test/lib_read_write.rb @@ -1,5 +1,7 @@ +# -*- encoding: binary -*- require 'test/unit' require 'io/nonblock' +require 'digest/sha1' $-w = true require 'kgio' @@ -58,6 +60,41 @@ module LibReadWriteTest assert false, "should never get here (line:#{__LINE__})" end + def test_trywrite_full + buf = "\302\251" * 1024 * 1024 + buf2 = "" + dig = Digest::SHA1.new + t = Thread.new do + sleep 1 + nr = 0 + begin + dig.update(@rd.readpartial(4096, buf2)) + nr += buf2.size + rescue EOFError + break + rescue => e + end while true + dig.hexdigest + end + 50.times do + wr = buf + begin + rv = @wr.kgio_trywrite(wr) + case rv + when String + wr = rv + when Kgio::WaitWritable + IO.select(nil, [ @wr ]) + else + wr = false + end + end while wr + end + @wr.close + t.join + assert_equal '8ff79d8115f9fe38d18be858c66aa08a1cc27a66', t.value + end + def test_write_conv assert_equal nil, @wr.kgio_write(10) assert_equal "10", @rd.kgio_read(2) -- cgit v1.2.3-24-ge0c7