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

ruby-changes:14487

From: nobu <ko1@a...>
Date: Thu, 14 Jan 2010 12:50:57 +0900 (JST)
Subject: [ruby-changes:14487] Ruby:r26324 (trunk): * string.c (rb_str_concat): fixed range check for Fixnum, and

nobu	2010-01-14 12:50:39 +0900 (Thu, 14 Jan 2010)

  New Revision: 26324

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

  Log:
    * string.c (rb_str_concat): fixed range check for Fixnum, and
      added checks for integer overflow and invalid char code.

  Modified files:
    trunk/ChangeLog
    trunk/string.c
    trunk/test/ruby/test_string.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26323)
+++ ChangeLog	(revision 26324)
@@ -1,3 +1,8 @@
+Thu Jan 14 12:50:37 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* string.c (rb_str_concat): fixed range check for Fixnum, and
+	  added checks for integer overflow and invalid char code.
+
 Thu Jan 14 09:34:31 2010  NARUSE, Yui  <naruse@r...>
 
 	* string.c (rb_str_concat): raise RangeError when the argument is
Index: string.c
===================================================================
--- string.c	(revision 26323)
+++ string.c	(revision 26324)
@@ -1983,24 +1983,35 @@
 VALUE
 rb_str_concat(VALUE str1, VALUE str2)
 {
+    SIGNED_VALUE lc;
+
     if (FIXNUM_P(str2)) {
-	if (NEGFIXABLE(str2))
+	lc = FIX2LONG(str2);
+	if (lc < 0)
 	    rb_raise(rb_eRangeError, "negative argument");
     }
     else if (TYPE(str2) == T_BIGNUM) {
 	if (!RBIGNUM_SIGN(str2))
 	    rb_raise(rb_eRangeError, "negative argument");
+	lc = rb_big2ulong(str2);
     }
     else {
 	return rb_str_append(str1, str2);
     }
+#if SIZEOF_INT < SIZEOF_VALUE
+    if ((VALUE)lc > UINT_MAX) {
+	rb_raise(rb_eRangeError, "%"PRIuVALUE" out of char range", lc);
+    }
+#endif
     {
 	rb_encoding *enc = STR_ENC_GET(str1);
-	unsigned int c = NUM2UINT(str2);
 	long pos = RSTRING_LEN(str1);
-	int len = rb_enc_codelen(c, enc);
 	int cr = ENC_CODERANGE(str1);
+	int c, len;
 
+	if ((len = rb_enc_codelen(c = (int)lc, enc)) <= 0) {
+	    rb_raise(rb_eRangeError, "%u invalid char", c);
+	}
 	rb_str_resize(str1, pos+len);
 	rb_enc_mbcput(c, RSTRING_PTR(str1)+pos, enc);
 	ENC_CODERANGE_SET(str1, cr);
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb	(revision 26323)
+++ test/ruby/test_string.rb	(revision 26324)
@@ -218,6 +218,13 @@
     l = s.size
     s << "bar"
     assert_equal(l + 3, s.size)
+
+    bug = '[ruby-core:27583]'
+    assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << -3}
+    assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << -2}
+    assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << -1}
+    assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << 0x81308130}
+    assert_nothing_raised {S("a".force_encoding(Encoding::GB18030)) << 0x81308130}
   end
 
   def test_MATCH # '=~'

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

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