diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | numeric.c | 6 |
2 files changed, 12 insertions, 1 deletions
@@ -1,3 +1,10 @@ +Mon Apr 1 21:10:56 2013 Tanaka Akira <akr@fsij.org> + + * 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@fsij.org> * ext/-test-/num2int/num2int.c: Return string for result, instead of @@ -2001,7 +2001,9 @@ rb_num2ulong_internal(VALUE val, int *wrap_p) 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) 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 { |