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

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

Attach filesAttach ScreenshotAdd voteVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    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

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned
            teodor@gamingtribe.com Teodor Atroshenko

            Dates

              Created:
              Updated:

              Time Tracking

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

                Slack

                  Issue deployment