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

ruby-changes:53588

From: shyouhei <ko1@a...>
Date: Mon, 19 Nov 2018 18:52:52 +0900 (JST)
Subject: [ruby-changes:53588] shyouhei:r65804 (trunk): string.c: setbyte silently ignores upper bits

shyouhei	2018-11-19 18:52:46 +0900 (Mon, 19 Nov 2018)

  New Revision: 65804

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

  Log:
    string.c: setbyte silently ignores upper bits
    
    The behaviour of String#setbyte has been depending on the width
    of int, which is not portable.  Must check explicitly.

  Modified files:
    trunk/string.c
    trunk/test/ruby/test_m17n.rb
Index: test/ruby/test_m17n.rb
===================================================================
--- test/ruby/test_m17n.rb	(revision 65803)
+++ test/ruby/test_m17n.rb	(revision 65804)
@@ -1524,6 +1524,17 @@ class TestM17N < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_m17n.rb#L1524
     }
   end
 
+  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) }
+  end
+
   def test_compatible
     assert_nil Encoding.compatible?("",0)
     assert_equal(Encoding::UTF_8, Encoding.compatible?(u(""), ua("abc")))
Index: string.c
===================================================================
--- string.c	(revision 65803)
+++ string.c	(revision 65804)
@@ -5413,7 +5413,8 @@ rb_str_setbyte(VALUE str, VALUE index, V https://github.com/ruby/ruby/blob/trunk/string.c#L5413
     long pos = NUM2LONG(index);
     int byte = NUM2INT(value);
     long len = RSTRING_LEN(str);
-    char *head, *ptr, *left = 0;
+    char *head, *left = 0;
+    unsigned char *ptr;
     rb_encoding *enc;
     int cr = ENC_CODERANGE_UNKNOWN, width, nlen;
 
@@ -5421,17 +5422,21 @@ rb_str_setbyte(VALUE str, VALUE index, V https://github.com/ruby/ruby/blob/trunk/string.c#L5422
         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);
 
     if (!str_independent(str))
 	str_make_independent(str);
     enc = STR_ENC_GET(str);
     head = RSTRING_PTR(str);
-    ptr = &head[pos];
+    ptr = (unsigned char *)&head[pos];
     if (!STR_EMBED_P(str)) {
 	cr = ENC_CODERANGE(str);
 	switch (cr) {
 	  case ENC_CODERANGE_7BIT:
-	    left = ptr;
+            left = (char *)ptr;
 	    *ptr = byte;
 	    if (ISASCII(byte)) goto end;
 	    nlen = rb_enc_precise_mbclen(left, head+len, enc);

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

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