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

ruby-changes:15564

From: akr <ko1@a...>
Date: Sat, 24 Apr 2010 14:43:09 +0900 (JST)
Subject: [ruby-changes:15564] Ruby:r27470 (trunk): * io.c: raise IOError when byte oriented operations occur with

akr	2010-04-24 14:42:50 +0900 (Sat, 24 Apr 2010)

  New Revision: 27470

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27470

  Log:
    * io.c: raise IOError when byte oriented operations occur with
      non-empty character buffer.
      [ruby-dev:40493] [ruby-dev:40506]

  Modified files:
    trunk/ChangeLog
    trunk/io.c
    trunk/test/ruby/test_io_m17n.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27469)
+++ ChangeLog	(revision 27470)
@@ -1,3 +1,9 @@
+Sat Apr 24 14:40:20 2010  Tanaka Akira  <akr@f...>
+
+	* io.c: raise IOError when byte oriented operations occur with
+	  non-empty character buffer.
+	  [ruby-dev:40493] [ruby-dev:40506]
+
 Sat Apr 24 13:06:57 2010  Nobuyoshi Nakada  <nobu@r...>
 
 	* ruby.c (get_arglen): skip the last terminator of argv before
Index: io.c
===================================================================
--- io.c	(revision 27469)
+++ io.c	(revision 27470)
@@ -180,6 +180,8 @@
 #define READ_DATA_PENDING_PTR(fptr) ((fptr)->rbuf+(fptr)->rbuf_off)
 #define READ_DATA_BUFFERED(fptr) READ_DATA_PENDING(fptr)
 
+#define READ_CHAR_PENDING(fptr) ((fptr)->cbuf_len)
+
 #if defined(_WIN32)
 #define WAIT_FD_IN_WIN32(fptr) rb_thread_wait_fd((fptr)->fd);
 #else
@@ -401,7 +403,7 @@
 #define FMODE_SYNCWRITE (FMODE_SYNC|FMODE_WRITABLE)
 
 void
-rb_io_check_readable(rb_io_t *fptr)
+rb_io_check_char_readable(rb_io_t *fptr)
 {
     rb_io_check_closed(fptr);
     if (!(fptr->mode & FMODE_READABLE)) {
@@ -419,6 +421,21 @@
     }
 }
 
+void
+rb_io_check_byte_readable(rb_io_t *fptr)
+{
+    rb_io_check_char_readable(fptr);
+    if (READ_CHAR_PENDING(fptr)) {
+	rb_raise(rb_eIOError, "byte oriented read for character buffered IO");
+    }
+}
+
+void
+rb_io_check_readable(rb_io_t *fptr)
+{
+    rb_io_check_byte_readable(fptr);
+}
+
 static rb_encoding*
 io_read_encoding(rb_io_t *fptr)
 {
@@ -452,6 +469,9 @@
 int
 rb_io_read_pending(rb_io_t *fptr)
 {
+    /* This function is used for bytes and chars.  Confusing. */
+    if (READ_CHAR_PENDING(fptr))
+        return 1; /* should raise? */
     return READ_DATA_PENDING(fptr);
 }
 
@@ -1242,8 +1262,9 @@
     rb_io_t *fptr;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
 
+    if (READ_CHAR_PENDING(fptr)) return Qfalse;
     if (READ_DATA_PENDING(fptr)) return Qfalse;
     READ_CHECK(fptr);
     if (io_fillbuf(fptr) < 0) {
@@ -1814,7 +1835,7 @@
     OBJ_TAINT(str);
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_byte_readable(fptr);
 
     if (len == 0)
 	return str;
@@ -2133,7 +2154,7 @@
     if (NIL_P(length)) {
 	if (!NIL_P(str)) StringValue(str);
 	GetOpenFile(io, fptr);
-	rb_io_check_readable(fptr);
+	rb_io_check_char_readable(fptr);
 	return read_all(fptr, remain_size(fptr), str);
     }
     len = NUM2LONG(length);
@@ -2151,7 +2172,7 @@
     }
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_byte_readable(fptr);
     if (len == 0) return str;
 
     READ_CHECK(fptr);
@@ -2385,7 +2406,7 @@
     rb_encoding *enc;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
     if (NIL_P(rs) && limit < 0) {
 	str = read_all(fptr, 0, Qnil);
 	if (RSTRING_LEN(str) == 0) return Qnil;
@@ -2550,7 +2571,7 @@
     rb_io_t *fptr;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
     return INT2NUM(fptr->lineno);
 }
 
@@ -2577,7 +2598,7 @@
     rb_io_t *fptr;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
     fptr->lineno = NUM2INT(lineno);
     return lineno;
 }
@@ -2722,7 +2743,7 @@
 	    p++;
 	    errno = 0;
 	}
-	rb_io_check_readable(fptr);
+	rb_io_check_byte_readable(fptr);
 	READ_CHECK(fptr);
 	if (io_fillbuf(fptr) < 0) {
 	    break;
@@ -2859,7 +2880,7 @@
 
     RETURN_ENUMERATOR(io, 0, 0);
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
 
     enc = io_input_encoding(fptr);
     READ_CHECK(fptr);
@@ -2899,7 +2920,7 @@
 
     RETURN_ENUMERATOR(io, 0, 0);
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
 
     READ_CHECK(fptr);
     if (NEED_READCONV(fptr)) {
@@ -2989,7 +3010,7 @@
     rb_encoding *enc;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
 
     enc = io_input_encoding(fptr);
     READ_CHECK(fptr);
@@ -3038,7 +3059,7 @@
     int c;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_byte_readable(fptr);
     READ_CHECK(fptr);
     if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && TYPE(rb_stdout) == T_FILE) {
         rb_io_t *ofp;
@@ -3098,7 +3119,7 @@
     rb_io_t *fptr;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_byte_readable(fptr);
     io_unset_eof(fptr);
     if (NIL_P(b)) return Qnil;
     if (FIXNUM_P(b)) {
@@ -3135,7 +3156,7 @@
     long len;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_char_readable(fptr);
     io_unset_eof(fptr);
     if (NIL_P(c)) return Qnil;
     if (FIXNUM_P(c)) {
@@ -3739,7 +3760,8 @@
     }
     pos = NUM2OFFT(offset);
     GetOpenFile(io, fptr);
-    if ((fptr->mode & FMODE_READABLE) && READ_DATA_BUFFERED(fptr)) {
+    if ((fptr->mode & FMODE_READABLE) &&
+        (READ_DATA_BUFFERED(fptr) || READ_CHAR_PENDING(fptr))) {
 	rb_raise(rb_eIOError, "sysseek for buffered IO");
     }
     if ((fptr->mode & FMODE_WRITABLE) && fptr->wbuf_len) {
@@ -3830,7 +3852,7 @@
     if (ilen == 0) return str;
 
     GetOpenFile(io, fptr);
-    rb_io_check_readable(fptr);
+    rb_io_check_byte_readable(fptr);
 
     if (READ_DATA_BUFFERED(fptr)) {
 	rb_raise(rb_eIOError, "sysread for buffered IO");
@@ -8387,7 +8409,7 @@
             stp->close_src = 1;
         }
         GetOpenFile(src_io, src_fptr);
-        rb_io_check_readable(src_fptr);
+        rb_io_check_byte_readable(src_fptr);
         src_fd = src_fptr->fd;
     }
     stp->src_fd = src_fd;
Index: test/ruby/test_io_m17n.rb
===================================================================
--- test/ruby/test_io_m17n.rb	(revision 27469)
+++ test/ruby/test_io_m17n.rb	(revision 27470)
@@ -1741,5 +1741,38 @@
       end
     }
   end
+
+  def test_cbuf
+    with_tmpdir {
+      fn = "tst"
+      open(fn, "w") {|f| f.print "foo" }
+      open(fn, "r+t") {|f|
+        f.ungetc(f.getc)
+        assert_raise(IOError, "[ruby-dev:40493]") { f.readpartial(2) }
+        assert_raise(IOError) { f.read(2) }
+        assert_raise(IOError) { f.each_byte {|c| } }
+        assert_raise(IOError) { f.getbyte }
+        assert_raise(IOError) { f.ungetbyte(0) }
+        assert_raise(IOError) { f.sysread(2) }
+        assert_raise(IOError) { IO.copy_stream(f, "tmpout") }
+        assert_raise(IOError) { f.sysseek(2) }
+      }
+      open(fn, "r+t") {|f|
+        f.ungetc(f.getc)
+        assert_equal("foo", f.read)
+      }
+    }
+  end
+
+  def test_text_mode_ungetc_eof
+    with_tmpdir {
+      open("ff", "w") {|f| }
+      open("ff", "rt") {|f|
+        f.ungetc "a"
+        assert(!f.eof?, "[ruby-dev:40506] (3)")
+      }
+    }
+  end
+
 end
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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