Bugs: Browse | Submit New | Admin

[#1823] NUM2UINT and rb_num2ull do not rase RangeError for negative Fixnum

Date:
2005-04-22 18:34
Priority:
3
Submitted By:
Michael Schonberg (mschonberg)
Assigned To:
Shyouhei Urabe (shyouhei)
Category:
Language / Runtime / Core Libraries
State:
Open
Platform:
 
Summary:
NUM2UINT and rb_num2ull do not rase RangeError for negative Fixnum

Detailed description
NUM2UINT does not rase RangError for negative Fixnum. If a Fixnum is < 0, NUM2UINT(value) should raise a RangeError
since an unsigned int can not be negative.

Adding the following to my code fixed the problem:
    if( FIXNUM_P(val) && ( val & 0x04000000 ) )
    {
        rb_raise( rb_eRangeError, "unsigned int can not be less than 0" );
    }

I believe that changing rb_num2ulong to:

    unsigned long
    rb_num2ulong(val)
        VALUE val;
    {
        if (TYPE(val) == T_BIGNUM) {
	    return rb_big2ulong(val);
        }
        else if (FIXNUM_P(val) && (val & 0x04000000)) {
            rb_raise(rb_eRangeError, "unsigned int can not be < 0")
        }
        return (unsigned long)rb_num2long(val);
    }
in numeric.c will fix the problem. I am not certain if the same problem exists when SIZEOF_INT < SIZEOF_LONG.

Add A Comment: Notepad

Please login


Followup

Message
Date: 2007-08-03 15:57
Sender: Neil Roberts

I stumbled across this bug too. I've just tried it in the latest
SVN trunk build and it's still there. Here is an example Ruby
extension to illustrate:

#include <ruby.h>

static VALUE
to_uint_and_back (VALUE self, VALUE num)
{
  // Convert the argument to an unsigned integer
  unsigned int intval = NUM2UINT (num);
  // Convert it back to a Ruby number
  return UINT2NUM (intval);
}

void
Init_numtest ()
{
  rb_define_global_function ("to_uint_and_back",
to_uint_and_back, 1);
}

The extension defines a global function called 'to_uint_and_back'
which just converts its parameter to an unsigned integer and
then returns it back again as a Ruby value. Here is an example
using the extension:

irb(main):001:0> require 'numtest'
=> true
irb(main):002:0> to_uint_and_back(3) # this works fine
=> 3
irb(main):003:0> to_uint_and_back(-1) # this should throw
an exception
=> 4294967295

The -1 just gets interpreted as a large number but it should
throw an exception.
Date: 2006-11-02 07:19
Sender: Ryan Davis

I'm closing this bug due to its age / staleness. I simply can't
triage them all and I have
to cut corners somewhere. If you believe this bug still exists
in the latest version of
ruby 1.8.x, please reopen it and, if you can, attach a minimally
reproducible test case
to help us repro it in 1.8.x (where x >= 5).

Thank you for your support. Things will get better.

Ryan Davis.
Date: 2005-04-22 22:32
Sender: Michael Schonberg

Logged In: YES 
user_id=2406

The same problem/fix applies to rb_num2ull.

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

Field Old Value Date By
assigned_tonone2007-08-03 19:16zenspider
category_idNone2007-08-03 19:16zenspider
status_idClosed2007-08-03 19:16zenspider
close_date2006-11-02 07:192006-11-02 07:19zenspider
status_idOpen2006-11-02 07:19zenspider
resolution_idNone2006-11-02 07:19zenspider
summaryNUM2UINT does not rase RangeError for negative Fixnum2005-04-22 22:32mschonberg
summaryNUM2UINT does not rase RangError for negative Fixnum2005-04-22 18:37mschonberg