pack bug on 64-bit ruby

Ask a Question related to Ruby, Design and Development.

  1. #1

    Default pack bug on 64-bit ruby

    Hi all,

    Solaris 9
    >/opt/bin/ruby -v
    ruby 1.8.1 (2003-10-31) [sparc-solaris2.9]
    >file /opt/bin/ruby
    /opt/bin/ruby: ELF 64-bit MSB executable SPARCV9 Version 1, UltraSPARC1
    Extensions Required, dynamically linked, not stripped

    Looks like there's a 64-bit related bug in pack():

    irb(main):007:0> [-1].pack("V")
    RangeError: integer 18446744073709551615 too big to convert to `unsigned
    int'
    from (irb):7:in `pack'
    from (irb):7

    Regards,

    Dan


    Daniel Berger Guest

  2. Similar Questions and Discussions

    1. [ba-rb] BA-rb ( Bay Area Ruby Users Group ) - 'Generating Code in Ruby' by Jack Herrington.
      Count me in again, too. -- Jos Backus _/ _/_/_/ Sunnyvale, CA _/ _/ _/ _/ _/_/_/ _/ _/ _/ _/ jos at...
    2. BA-rb ( Bay Area Ruby Users Group ) - 'Generating Code in Ruby' by Jack Herrington.
      BA-rb (Bay Area Ruby language Users Group) is pleased to announce that it will begin meeting again. The topic for the first meeting will be a...
    3. ruby-talk: 80813 (Rite/Ruby2.0 & Ruby vs OCaml)
      Hope nobody finds this annoying. Somehow I missed this message when it was originally sent, but I thought my reply might be useful to sombody. ...
    4. RubyConf, Ruby Central, Ruby Garden temporary outage
      Hi -- Just to let everyone know that there's a network outage at the host for the RubyConf registration, which also affects Ruby Garden and Ruby...
    5. [ANN] ruby-freedb, ruby-serialport, ruby-mp3info moved to Rubyforge
      http://ruby-freedb.rubyforge.org/ http://ruby-serialport.rubyforge.org/ http://ruby-mp3info.rubyforge.org/ bye! --...
  3. #2

    Default Re: pack bug on 64-bit ruby

    Daniel Berger wrote:
    > Looks like there's a 64-bit related bug in pack():
    >
    > irb(main):007:0> [-1].pack("V")
    > RangeError: integer 18446744073709551615 too big to convert to `unsigned
    > int'
    > from (irb):7:in `pack'
    > from (irb):7
    If Array#pack is supposed to output a four-character string for the
    *unsigned* long value, I think maybe this shouldn't work for 64-bit.
    You're passing in a value of -1, which is 2**64 - 1 when represented as
    an unsigned long on a 64-bit machine. You can't pack that into four
    characters (bytes).

    Out of curiosity, what happens if you instead try this?

    [-1].pack("L_")

    Note the trailing underscore. If I read the code right, this should do
    the right thing.

    Lyle Johnson Guest

  4. #3

    Default Re: pack bug on 64-bit ruby

    > -----Original Message-----
    > From: Lyle Johnson [mailto:lyle@users.sourceforge.net]
    > Sent: Monday, November 17, 2003 2:47 PM
    > To: ruby-talk ML
    > Subject: Re: pack bug on 64-bit ruby
    >
    >
    > Daniel Berger wrote:
    >
    > > Looks like there's a 64-bit related bug in pack():
    > >
    > > irb(main):007:0> [-1].pack("V")
    > > RangeError: integer 18446744073709551615 too big to convert to
    > > `unsigned int'
    > > from (irb):7:in `pack'
    > > from (irb):7
    >
    > If Array#pack is supposed to output a four-character string for the
    > *unsigned* long value, I think maybe this shouldn't work for 64-bit.
    > You're passing in a value of -1, which is 2**64 - 1 when
    > represented as
    > an unsigned long on a 64-bit machine. You can't pack that into four
    > characters (bytes).
    >
    > Out of curiosity, what happens if you instead try this?
    >
    > [-1].pack("L_")
    >
    > Note the trailing underscore. If I read the code right, this
    > should do
    > the right thing.
    Thanks Lyle - that seems to work although (as expected I think) it does
    it in 8 bytes.

    The question I have now then is, if I've got code that uses
    [-1].pack("V"), how should I handle this on 64 bit platforms? Is there
    a way to tell the bit-ness of Ruby from within Ruby? Perhaps a
    RUBY_BITNESS constant? Or is there some sort of "cross-bitness"
    approach I can use?

    Regards,

    Dan

    Berger, Daniel Guest

  5. #4

    Default Re: pack bug on 64-bit ruby

    Hi,

    At Tue, 18 Nov 2003 07:03:54 +0900,
    Berger, Daniel wrote:
    > The question I have now then is, if I've got code that uses
    > [-1].pack("V"), how should I handle this on 64 bit platforms? Is there
    > a way to tell the bit-ness of Ruby from within Ruby? Perhaps a
    > RUBY_BITNESS constant? Or is there some sort of "cross-bitness"
    > approach I can use?
    [-1].pack("v") gently gives "\377\377" on 32 bit platforms, so
    it might be better to just mask, like as Perl.


    * pack.c (pack_pack): mask for lower bits. [ruby-talk:85377]

    Index: pack.c
    ================================================== =================
    RCS file: /cvs/ruby/src/ruby/pack.c,v
    retrieving revision 1.57
    diff -u -2 -p -r1.57 pack.c
    --- pack.c 9 Oct 2003 17:45:52 -0000 1.57
    +++ pack.c 18 Nov 2003 00:45:32 -0000
    @@ -676,4 +676,5 @@ pack_pack(ary, fmt)
    if (NIL_P(from)) s = 0;
    else {
    + from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
    s = NUM2INT(from);
    }
    @@ -690,5 +691,6 @@ pack_pack(ary, fmt)
    if (NIL_P(from)) l = 0;
    else {
    - l = NATINT_U32(from);
    + from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
    + l = NUM2ULONG(from);
    }
    l = htonl(l);
    @@ -704,4 +706,5 @@ pack_pack(ary, fmt)
    if (NIL_P(from)) s = 0;
    else {
    + from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
    s = NUM2INT(from);
    }
    @@ -718,5 +721,6 @@ pack_pack(ary, fmt)
    if (NIL_P(from)) l = 0;
    else {
    - l = NATINT_U32(from);
    + from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
    + l = NUM2ULONG(from);
    }
    l = htovl(l);


    --
    Nobu Nakada


    nobu.nokada@softhome.net Guest

  6. #5

    Default Re: pack bug on 64-bit ruby

    [email]nobu.nokada@softhome.net[/email] wrote:
    >
    > Hi,
    >
    > At Tue, 18 Nov 2003 07:03:54 +0900,
    > Berger, Daniel wrote:
    > > The question I have now then is, if I've got code that uses
    > > [-1].pack("V"), how should I handle this on 64 bit platforms? Is there
    > > a way to tell the bit-ness of Ruby from within Ruby? Perhaps a
    > > RUBY_BITNESS constant? Or is there some sort of "cross-bitness"
    > > approach I can use?
    >
    > [-1].pack("v") gently gives "\377\377" on 32 bit platforms, so
    > it might be better to just mask, like as Perl.
    >
    > * pack.c (pack_pack): mask for lower bits. [ruby-talk:85377]
    >
    > Index: pack.c
    > ================================================== =================
    > RCS file: /cvs/ruby/src/ruby/pack.c,v
    > retrieving revision 1.57
    > diff -u -2 -p -r1.57 pack.c
    > --- pack.c 9 Oct 2003 17:45:52 -0000 1.57
    > +++ pack.c 18 Nov 2003 00:45:32 -0000
    > @@ -676,4 +676,5 @@ pack_pack(ary, fmt)
    > if (NIL_P(from)) s = 0;
    > else {
    > + from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
    > s = NUM2INT(from);
    > }
    > @@ -690,5 +691,6 @@ pack_pack(ary, fmt)
    > if (NIL_P(from)) l = 0;
    > else {
    > - l = NATINT_U32(from);
    > + from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
    > + l = NUM2ULONG(from);
    > }
    > l = htonl(l);
    > @@ -704,4 +706,5 @@ pack_pack(ary, fmt)
    > if (NIL_P(from)) s = 0;
    > else {
    > + from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
    > s = NUM2INT(from);
    > }
    > @@ -718,5 +721,6 @@ pack_pack(ary, fmt)
    > if (NIL_P(from)) l = 0;
    > else {
    > - l = NATINT_U32(from);
    > + from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
    > + l = NUM2ULONG(from);
    > }
    > l = htovl(l);
    >
    > --
    > Nobu Nakada
    Forgive my ignorance, but does this just mean that pack("V") is always
    32 bits, as in Perl?

    Dan


    Daniel Berger Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139