[ 
https://issues.apache.org/jira/browse/PROTON-2241?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ivo Wever updated PROTON-2241:
------------------------------
    Description: 
h4. Observation
Attempting to set a number between 2\*\*31 - 1 and 2\*\*62 - 1 as e.g. the 
message-id in Ruby 2.6.5 (and probably any other recent Ruby) results in the 
number mod 2**32.

Example (pry is a Ruby repl):
{code}
[1] pry(main)> m = Qpid::Proton::Message.new('body')
=> Message{body="body"}
[2] pry(main)> m.id = 2**61 + 2**30
=> 2305843010287435776
[3] pry(main)> m.id
=> 1073741824
{code}

h4. Analysis
The SWIG bindings contain the following snippet (lines 115-123)
{code}
        case T_FIXNUM:
          $1.type = PN_INT;
          $1.u.as_int = FIX2LONG($input);
          break;

        case T_BIGNUM:
          $1.type = PN_LONG;
          $1.u.as_long = NUM2LL($input);
          break;
{code}

Integer instances <= 2**62 - 1 will hit the T_FIXNUM case, as Ruby fixnums are 
63 bits (1 bit is used to indicate they are fixnums to speed up arithmetic). 
Subsequently the number is converted into a 32 bit C long, discarding the 32 
highest bits.

h4. Further notes
The T_BIGNUM case takes care of correctly setting the value for numbers between 
2**62 and 2**63-1, as thos numbers can be converted into a 64 bit C long long

The T_BIGNUM case will fail for all larger numbers, with
{code}
RangeError: bignum too big to convert into `long long'
{code}
This is probably OK.

Note that the autoconversion of a pn_atom_t to an int or long is not useful for 
e.g. the message-id property, as it needs to be passed as a ulong (when 
numeric, disregarding the uuid, string, binary alternatives). Proton doesn't 
enforce this and naively setting {{message.id = 1}} results in sending a 
message that is invalid with respect to the specification, as the type of the 
message-id will be an int.

  was:
h4. Observation
Attempting to set a number between 2**31 - 1 and 2**62 - 1 as e.g. the 
message-id in Ruby 2.6.5 (and probably any other recent Ruby) results in the 
number mod 2**32.

Example (pry is a Ruby repl):
{code}
[1] pry(main)> m = Qpid::Proton::Message.new('body')
=> Message{body="body"}
[2] pry(main)> m.id = 2**61 + 2**30
=> 2305843010287435776
[3] pry(main)> m.id
=> 1073741824
{code}

h4. Analysis
The SWIG bindings contain the following snippet (lines 115-123)
{code}
        case T_FIXNUM:
          $1.type = PN_INT;
          $1.u.as_int = FIX2LONG($input);
          break;

        case T_BIGNUM:
          $1.type = PN_LONG;
          $1.u.as_long = NUM2LL($input);
          break;
{code}

Integer instances <= 2**62 - 1 will hit the T_FIXNUM case, as Ruby fixnums are 
63 bits (1 bit is used to indicate they are fixnums to speed up arithmetic). 
Subsequently the number is converted into a 32 bit C long, discarding the 32 
highest bits.

h4. Further notes
The T_BIGNUM case takes care of correctly setting the value for numbers between 
2**62 and 2**63-1, as thos numbers can be converted into a 64 bit C long long

The T_BIGNUM case will fail for all larger numbers, with
{code}
RangeError: bignum too big to convert into `long long'
{code}
This is probably OK.

Note that the autoconversion of a pn_atom_t to an int or long is not useful for 
e.g. the message-id property, as it needs to be passed as a ulong (when 
numeric, disregarding the uuid, string, binary alternatives). Proton doesn't 
enforce this and naively setting {{message.id = 1}} results in sending a 
message that is invalid with respect to the specification, as the type of the 
message-id will be an int.


> Cannot pass integer values between 2**31 - 1 and 2**62 - 1 for pn_atom_t 
> variables
> ----------------------------------------------------------------------------------
>
>                 Key: PROTON-2241
>                 URL: https://issues.apache.org/jira/browse/PROTON-2241
>             Project: Qpid Proton
>          Issue Type: Bug
>          Components: ruby-binding
>    Affects Versions: proton-c-0.30.0
>            Reporter: Ivo Wever
>            Assignee: Alan Conway
>            Priority: Major
>
> h4. Observation
> Attempting to set a number between 2\*\*31 - 1 and 2\*\*62 - 1 as e.g. the 
> message-id in Ruby 2.6.5 (and probably any other recent Ruby) results in the 
> number mod 2**32.
> Example (pry is a Ruby repl):
> {code}
> [1] pry(main)> m = Qpid::Proton::Message.new('body')
> => Message{body="body"}
> [2] pry(main)> m.id = 2**61 + 2**30
> => 2305843010287435776
> [3] pry(main)> m.id
> => 1073741824
> {code}
> h4. Analysis
> The SWIG bindings contain the following snippet (lines 115-123)
> {code}
>         case T_FIXNUM:
>           $1.type = PN_INT;
>           $1.u.as_int = FIX2LONG($input);
>           break;
>         case T_BIGNUM:
>           $1.type = PN_LONG;
>           $1.u.as_long = NUM2LL($input);
>           break;
> {code}
> Integer instances <= 2**62 - 1 will hit the T_FIXNUM case, as Ruby fixnums 
> are 63 bits (1 bit is used to indicate they are fixnums to speed up 
> arithmetic). Subsequently the number is converted into a 32 bit C long, 
> discarding the 32 highest bits.
> h4. Further notes
> The T_BIGNUM case takes care of correctly setting the value for numbers 
> between 2**62 and 2**63-1, as thos numbers can be converted into a 64 bit C 
> long long
> The T_BIGNUM case will fail for all larger numbers, with
> {code}
> RangeError: bignum too big to convert into `long long'
> {code}
> This is probably OK.
> Note that the autoconversion of a pn_atom_t to an int or long is not useful 
> for e.g. the message-id property, as it needs to be passed as a ulong (when 
> numeric, disregarding the uuid, string, binary alternatives). Proton doesn't 
> enforce this and naively setting {{message.id = 1}} results in sending a 
> message that is invalid with respect to the specification, as the type of the 
> message-id will be an int.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to