Uploaded image for project: 'Thrift'
  1. Thrift
  2. THRIFT-4214

map<i64,value> key treated as hex value in JavaScript

    XMLWordPrintableJSON

Details

    Description

      The service is defined with the following function:

      map<i64,double> someFunctionName()
      

      The --gen js:node code:

      output.writeFieldBegin('success', Thrift.Type.MAP, 0);
      output.writeMapBegin(Thrift.Type.I64, Thrift.Type.DOUBLE, Thrift.objectLength(this.success));
      for (var kiter18 in this.success)
      {
        if (this.success.hasOwnProperty(kiter18))
        {
          var viter19 = this.success[kiter18];
          output.writeI64(kiter18);
          output.writeDouble(viter19);
        }
      }
      output.writeMapEnd();
      output.writeFieldEnd();
      

      String kiter18 is passed to output.writeI64. Only TBinaryProtocol is affected by this. The function defenition:

      TBinaryProtocol.prototype.writeI64 = function(i64) {
        if (i64.buffer) {
          this.trans.write(i64.buffer);
        } else {
          this.trans.write(new Int64(i64).buffer);
        }
      };
      

      Int64 constructor accepts the following arguments:

      • new Int64(buffer[, offset=0]) - Existing Buffer with byte offset
      • new Int64(Uint8Array[, offset=0]) - Existing Uint8Array with a byte offset
      • new Int64(string) - Hex string (throws if n is outside int64 range)
      • new Int64(number) - Number (throws if n is outside int64 range)
      • new Int64(hi, lo) - Raw bits as two 32-bit values

      What happens, is that JavaScript object keys are always Strings, so the generated function passes the object key as-is (in String representation) and Int64 library assumes it's a hex string and converts it to a different 64-bit integer.

      For example "4398046511580" becomes [Int64 value:1189123005158784 octets:00 04 39 80 46 51 15 80]

      This also happens when returning list<i64>, however in lists it can be bypassed by calling Number() on all Array elements before passing it to Thrift's result() function.

      To solve this, the compiler can be adding Number() around everything that is a decimal number that is passed to writeI64; and if writeI64 will never be called with an actual hex string, then js library can be updated to include the Number() call around Int64 constructor argument.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              teodor@gamingtribe.com Teodor Atroshenko
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 0.5h
                  0.5h