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

ruby-changes:27985

From: akr <ko1@a...>
Date: Mon, 1 Apr 2013 21:14:41 +0900 (JST)
Subject: [ruby-changes:27985] akr:r40037 (trunk): * numeric.c (rb_num2ulong_internal): Don't cast a negative double value

akr	2013-04-01 21:14:30 +0900 (Mon, 01 Apr 2013)

  New Revision: 40037

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

  Log:
    * numeric.c (rb_num2ulong_internal): Don't cast a negative double value
      into unsigned long, which is undefined behavior.
      (rb_num2ull): Don't cast a value bigger than LLONG_MAX into
      long long, which is undefined behavior.

  Modified files:
    trunk/ChangeLog
    trunk/numeric.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 40036)
+++ ChangeLog	(revision 40037)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Apr  1 21:10:56 2013  Tanaka Akira  <akr@f...>
+
+	* numeric.c (rb_num2ulong_internal): Don't cast a negative double value
+	  into unsigned long, which is undefined behavior.
+	  (rb_num2ull): Don't cast a value bigger than LLONG_MAX into
+	  long long, which is undefined behavior.
+
 Mon Apr  1 20:57:57 2013  Tanaka Akira  <akr@f...>
 
 	* ext/-test-/num2int/num2int.c: Return string for result, instead of
Index: numeric.c
===================================================================
--- numeric.c	(revision 40036)
+++ numeric.c	(revision 40037)
@@ -2001,7 +2001,9 @@ rb_num2ulong_internal(VALUE val, int *wr https://github.com/ruby/ruby/blob/trunk/numeric.c#L2001
            double d = RFLOAT_VALUE(val);
            if (wrap_p)
                *wrap_p = d <= -1.0; /* NUM2ULONG(v) uses v.to_int conceptually.  */
-           return (unsigned long)d;
+           if (0 <= d)
+               return (unsigned long)d;
+           return (unsigned long)(long)d;
        }
        else {
            char buf[24];
@@ -2273,6 +2275,8 @@ rb_num2ull(VALUE val) https://github.com/ruby/ruby/blob/trunk/numeric.c#L2275
       case T_FLOAT:
 	if (RFLOAT_VALUE(val) < ULLONG_MAX_PLUS_ONE
             && LLONG_MIN_MINUS_ONE_IS_LESS_THAN(RFLOAT_VALUE(val))) {
+            if (0 <= RFLOAT_VALUE(val))
+                return (unsigned LONG_LONG)(RFLOAT_VALUE(val));
 	    return (unsigned LONG_LONG)(LONG_LONG)(RFLOAT_VALUE(val));
 	}
 	else {

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

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