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

            People

            • Assignee:
              Unassigned
              Reporter:
              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

                  Issue deployment