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

ruby-changes:17475

From: naruse <ko1@a...>
Date: Wed, 13 Oct 2010 12:56:41 +0900 (JST)
Subject: [ruby-changes:17475] Ruby:r29480 (trunk): * numeric.c (rb_num_to_uint): added to check the range of arguments.

naruse	2010-10-13 12:56:31 +0900 (Wed, 13 Oct 2010)

  New Revision: 29480

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

  Log:
    * numeric.c (rb_num_to_uint): added to check the range of arguments.
      Mainly for negative value with NUM2UINT on 32bit environment.
    
    * string.c (rb_str_concat): use rb_num_to_uint.

  Modified files:
    trunk/ChangeLog
    trunk/numeric.c
    trunk/string.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 29479)
+++ ChangeLog	(revision 29480)
@@ -1,3 +1,10 @@
+Wed Oct 13 12:53:43 2010  NARUSE, Yui  <naruse@r...>
+
+	* numeric.c (rb_num_to_uint): added to check the range of arguments.
+	  Mainly for negative value with NUM2UINT on 32bit environment.
+
+	* string.c (rb_str_concat): use rb_num_to_uint.
+
 Wed Oct 13 12:10:02 2010  NAKAMURA Usaku  <usa@r...>
 
 	* thread_win32.c (w32_error): get English message first, instead
Index: string.c
===================================================================
--- string.c	(revision 29479)
+++ string.c	(revision 29480)
@@ -2001,6 +2001,7 @@
     return rb_str_buf_append(str, str2);
 }
 
+int rb_num_to_uint(VALUE val, unsigned int *ret);
 
 /*
  *  call-seq:
@@ -2023,12 +2024,16 @@
 {
     unsigned int lc;
 
-    if (FIXNUM_P(str2)) {
-	lc = FIX2UINT(str2);
+    if (FIXNUM_P(str2) || TYPE(str2) == T_BIGNUM) {
+	if (rb_num_to_uint(str2, &lc) == 0) {
+	}
+	else if (FIXNUM_P(str2)) {
+	    rb_raise(rb_eRangeError, "%ld out of char range", FIX2LONG(str2));
+	}
+	else {
+	    rb_raise(rb_eRangeError, "bignum out of char range");
+	}
     }
-    else if (TYPE(str2) == T_BIGNUM) {
-	lc = NUM2UINT(str2);
-    }
     else {
 	return rb_str_append(str1, str2);
     }
Index: numeric.c
===================================================================
--- numeric.c	(revision 29479)
+++ numeric.c	(revision 29480)
@@ -113,7 +113,37 @@
     rb_raise(rb_eZeroDivError, "divided by 0");
 }
 
+/* experimental API */
+int
+rb_num_to_uint(VALUE val, unsigned int *ret)
+{
+#define NUMERR_TYPE     1
+#define NUMERR_NEGATIVE 2
+#define NUMERR_TOOLARGE 3
+    if (FIXNUM_P(val)) {
+	long v = FIX2LONG(val);
+	if (v > UINT_MAX) return NUMERR_TOOLARGE;
+	if (v < 0) return NUMERR_NEGATIVE;
+	*ret = (unsigned int)v;
+	return 0;
+    }
 
+    switch (TYPE(val)) {
+      case T_BIGNUM:
+	if (RBIGNUM_NEGATIVE_P(val)) return NUMERR_NEGATIVE;
+#if SIZEOF_INT < SIZEOF_LONG
+	/* long is 64bit */
+	return NUMERR_TOOLARGE;
+#else
+	/* long is 32bit */
+	if (RBIGNUM_LEN(x) > DIGSPERLONG) return NUMERR_TOOLARGE;
+	*ret = (unsigned int)rb_big2ulong((VALUE)val);
+	return 0;
+#endif
+    }
+    return NUMERR_TYPE;
+}
+
 /*
  *  call-seq:
  *     num.coerce(numeric)  ->  array

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

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