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

ruby-changes:54630

From: naruse <ko1@a...>
Date: Fri, 18 Jan 2019 06:36:24 +0900 (JST)
Subject: [ruby-changes:54630] naruse:r66845 (ruby_2_6): merge revision(s) 66760, 66761, 66824: [Backport #15460]

naruse	2019-01-18 06:36:17 +0900 (Fri, 18 Jan 2019)

  New Revision: 66845

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66845

  Log:
    merge revision(s) 66760,66761,66824: [Backport #15460]
    
    Follow behaviour of IO#ungetbyte
    
    see r65802 and [Bug #14359]
    
    * expand tabs.
    
    setbyte / ungetbyte allow out-of-range integers
    
    * string.c: String#setbyte to accept arbitrary integers [Bug #15460]
    
    * io.c: ditto for IO#ungetbyte
    
    * ext/strringio/stringio.c: ditto for StringIO#ungetbyte

  Modified directories:
    branches/ruby_2_6/
  Modified files:
    branches/ruby_2_6/ext/stringio/stringio.c
    branches/ruby_2_6/io.c
    branches/ruby_2_6/spec/ruby/core/io/ungetbyte_spec.rb
    branches/ruby_2_6/string.c
    branches/ruby_2_6/test/ruby/test_m17n.rb
    branches/ruby_2_6/test/stringio/test_stringio.rb
    branches/ruby_2_6/version.h
Index: ruby_2_6/string.c
===================================================================
--- ruby_2_6/string.c	(revision 66844)
+++ ruby_2_6/string.c	(revision 66845)
@@ -5411,7 +5411,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_6/string.c#L5411
 rb_str_setbyte(VALUE str, VALUE index, VALUE value)
 {
     long pos = NUM2LONG(index);
-    int byte = NUM2INT(value);
     long len = RSTRING_LEN(str);
     char *head, *left = 0;
     unsigned char *ptr;
@@ -5422,10 +5421,10 @@ rb_str_setbyte(VALUE str, VALUE index, V https://github.com/ruby/ruby/blob/trunk/ruby_2_6/string.c#L5421
         rb_raise(rb_eIndexError, "index %ld out of string", pos);
     if (pos < 0)
         pos += len;
-    if (byte < 0)
-        rb_raise(rb_eRangeError, "integer %d too small to convert into `unsigned char'", byte);
-    if (UCHAR_MAX < byte)
-        rb_raise(rb_eRangeError, "integer %d too big to convert into `unsigned char'", byte);
+
+    VALUE v = rb_to_int(value);
+    VALUE w = rb_int_modulo(v, INT2FIX(256));
+    unsigned char byte = NUM2INT(w) & 0xFF;
 
     if (!str_independent(str))
 	str_make_independent(str);
Index: ruby_2_6/test/ruby/test_m17n.rb
===================================================================
--- ruby_2_6/test/ruby/test_m17n.rb	(revision 66844)
+++ ruby_2_6/test/ruby/test_m17n.rb	(revision 66845)
@@ -1526,13 +1526,13 @@ class TestM17N < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_6/test/ruby/test_m17n.rb#L1526
 
   def test_setbyte_range
     s = u("\xE3\x81\x82\xE3\x81\x84")
-    assert_raise(RangeError) { s.setbyte(0, -1) }
-    assert_nothing_raised    { s.setbyte(0, 0x00) }
-    assert_nothing_raised    { s.setbyte(0, 0x7F) }
-    assert_nothing_raised    { s.setbyte(0, 0x80) }
-    assert_nothing_raised    { s.setbyte(0, 0xff) }
-    assert_raise(RangeError) { s.setbyte(0, 0x100) }
-    assert_raise(RangeError) { s.setbyte(0, 0x4f7574206f6620636861722072616e6765) }
+    assert_nothing_raised { s.setbyte(0, -1) }
+    assert_nothing_raised { s.setbyte(0, 0x00) }
+    assert_nothing_raised { s.setbyte(0, 0x7F) }
+    assert_nothing_raised { s.setbyte(0, 0x80) }
+    assert_nothing_raised { s.setbyte(0, 0xff) }
+    assert_nothing_raised { s.setbyte(0, 0x100) }
+    assert_nothing_raised { s.setbyte(0, 0x4f7574206f6620636861722072616e6765) }
   end
 
   def test_compatible
Index: ruby_2_6/test/stringio/test_stringio.rb
===================================================================
--- ruby_2_6/test/stringio/test_stringio.rb	(revision 66844)
+++ ruby_2_6/test/stringio/test_stringio.rb	(revision 66845)
@@ -452,6 +452,10 @@ class TestStringIO < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/ruby_2_6/test/stringio/test_stringio.rb#L452
     t.ungetbyte("\u{30eb 30d3 30fc}")
     assert_equal(0, t.pos)
     assert_equal("\u{30eb 30d3 30fc}\u7d05\u7389bar\n", s)
+
+    assert_nothing_raised {t.ungetbyte(-1)}
+    assert_nothing_raised {t.ungetbyte(256)}
+    assert_nothing_raised {t.ungetbyte(1<<64)}
   end
 
   def test_ungetc
Index: ruby_2_6/io.c
===================================================================
--- ruby_2_6/io.c	(revision 66844)
+++ ruby_2_6/io.c	(revision 66845)
@@ -4258,23 +4258,17 @@ rb_io_ungetbyte(VALUE io, VALUE b) https://github.com/ruby/ruby/blob/trunk/ruby_2_6/io.c#L4258
 
     GetOpenFile(io, fptr);
     rb_io_check_byte_readable(fptr);
-    if (NIL_P(b)) return Qnil;
-    if (FIXNUM_P(b)) {
-        int i = FIX2INT(b);
-        if (0 <= i && i <= UCHAR_MAX) {
-            unsigned char cc = i & 0xFF;
-            b = rb_str_new((const char *)&cc, 1);
-        }
-        else {
-            rb_raise(rb_eRangeError,
-                "integer %d too big to convert into `unsigned char'", i);
-        }
-    }
-    else if (RB_TYPE_P(b, T_BIGNUM)) {
-        rb_raise(rb_eRangeError, "bignum too big to convert into `unsigned char'");
-    }
-    else {
-	SafeStringValue(b);
+    switch (TYPE(b)) {
+      case T_NIL:
+        return Qnil;
+      case T_FIXNUM:
+      case T_BIGNUM: ;
+        VALUE v = rb_int_modulo(b, INT2FIX(256));
+        unsigned char c = NUM2INT(v) & 0xFF;
+        b = rb_str_new((const char *)&c, 1);
+        break;
+      default:
+        SafeStringValue(b);
     }
     io_ungetbyte(b, fptr);
     return Qnil;
Index: ruby_2_6/version.h
===================================================================
--- ruby_2_6/version.h	(revision 66844)
+++ ruby_2_6/version.h	(revision 66845)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_6/version.h#L1
 #define RUBY_VERSION "2.6.0"
 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 14
+#define RUBY_PATCHLEVEL 15
 
 #define RUBY_RELEASE_YEAR 2019
 #define RUBY_RELEASE_MONTH 1
Index: ruby_2_6/spec/ruby/core/io/ungetbyte_spec.rb
===================================================================
--- ruby_2_6/spec/ruby/core/io/ungetbyte_spec.rb	(revision 66844)
+++ ruby_2_6/spec/ruby/core/io/ungetbyte_spec.rb	(revision 66845)
@@ -49,13 +49,21 @@ describe "IO#ungetbyte" do https://github.com/ruby/ruby/blob/trunk/ruby_2_6/spec/ruby/core/io/ungetbyte_spec.rb#L49
     end
   end
 
-  ruby_version_is '2.6' do
+  ruby_version_is '2.6'...'2.7' do
     it "is an RangeError if the integer is not in 8bit" do
       for i in [4095, 0x4f7574206f6620636861722072616e6765] do
         lambda { @io.ungetbyte(i) }.should raise_error(RangeError)
       end
     end
   end
+
+  ruby_version_is '2.7' do
+    it "never raises RangeError" do
+      for i in [4095, 0x4f7574206f6620636861722072616e6765] do
+        lambda { @io.ungetbyte(i) }.should_not raise_error
+      end
+    end
+  end
 
   it "raises an IOError if the IO is closed" do
     @io.close
Index: ruby_2_6/ext/stringio/stringio.c
===================================================================
--- ruby_2_6/ext/stringio/stringio.c	(revision 66844)
+++ ruby_2_6/ext/stringio/stringio.c	(revision 66845)
@@ -803,24 +803,28 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_6/ext/stringio/stringio.c#L803
 strio_ungetbyte(VALUE self, VALUE c)
 {
     struct StringIO *ptr = readable(self);
-    char buf[1], *cp = buf;
-    long cl = 1;
 
     check_modifiable(ptr);
-    if (NIL_P(c)) return Qnil;
-    if (FIXNUM_P(c)) {
-	buf[0] = (char)FIX2INT(c);
-	return strio_unget_bytes(ptr, buf, 1);
-    }
-    else {
-	SafeStringValue(c);
-	cp = RSTRING_PTR(c);
-	cl = RSTRING_LEN(c);
-	if (cl == 0) return Qnil;
-	strio_unget_bytes(ptr, cp, cl);
-	RB_GC_GUARD(c);
-	return Qnil;
+    switch (TYPE(c)) {
+      case T_NIL:
+        return Qnil;
+      case T_FIXNUM:
+      case T_BIGNUM: ;
+        /* rb_int_modulo() not visible from exts */
+        VALUE v = rb_funcall(c, rb_intern("modulo"), 1, INT2FIX(256));
+        unsigned char cc = NUM2INT(v) & 0xFF;
+        c = rb_str_new((const char *)&cc, 1);
+        break;
+      default:
+        SafeStringValue(c);
     }
+
+    const char *cp = RSTRING_PTR(c);
+    long cl = RSTRING_LEN(c);
+    if (cl == 0) return Qnil;
+    strio_unget_bytes(ptr, cp, cl);
+    RB_GC_GUARD(c);
+    return Qnil;
 }
 
 static VALUE
Index: ruby_2_6
===================================================================
--- ruby_2_6	(revision 66844)
+++ ruby_2_6	(revision 66845)

Property changes on: ruby_2_6
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r66760-66761,66824

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

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