From d6daffbbf0350dbb6a164ec6264d5d2ea2f05c25 Mon Sep 17 00:00:00 2001 From: akr Date: Mon, 1 Apr 2013 12:14:30 +0000 Subject: * 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40037 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- numeric.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'numeric.c') diff --git a/numeric.c b/numeric.c index a4eb0dd167..66820eeed1 100644 --- a/numeric.c +++ b/numeric.c @@ -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 { -- cgit v1.2.3