diff --git a/package-lock.json b/package-lock.json index 8f6d371f1..c7d1af86b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2824,11 +2824,6 @@ "platform": "^1.3.3" } }, - "big-number": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/big-number/-/big-number-1.0.0.tgz", - "integrity": "sha1-oCd2B6CtsGSS0wmVRu8NVHeF3xg=" - }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -2922,7 +2917,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "builtin-modules": { @@ -3265,7 +3260,7 @@ }, "conventional-changelog-angular": { "version": "1.6.6", - "resolved": "http://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", "integrity": "sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==", "dev": true, "requires": { @@ -3330,7 +3325,7 @@ }, "conventional-commits-parser": { "version": "2.1.7", - "resolved": "http://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz", "integrity": "sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ==", "dev": true, "requires": { @@ -3691,7 +3686,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -3774,7 +3769,7 @@ "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", "dev": true, "requires": { "is-arrayish": "^0.2.1" @@ -4469,7 +4464,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -5510,7 +5505,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", "dev": true }, "inquirer": { @@ -6015,6 +6010,11 @@ "esprima": "^4.0.0" } }, + "jsbi": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.1.tgz", + "integrity": "sha512-+HQESPaV0mRiH614z4JPVPAftcRC2p53x92lySPzUzFwJbJTMpzHz8OYUkcXPN3fOcHUe0NdVcHnCtX/1+eCrA==" + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -6029,7 +6029,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=", "dev": true }, "json-schema": { @@ -6528,7 +6528,7 @@ "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", "dev": true, "requires": { "arrify": "^1.0.1", @@ -10704,14 +10704,14 @@ }, "p-is-promise": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", "dev": true }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "integrity": "sha1-uGvV8MJWkJEcdZD8v8IBDVSzzLg=", "dev": true, "requires": { "p-try": "^1.0.0" @@ -10877,7 +10877,7 @@ "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=", "dev": true, "requires": { "pify": "^3.0.0" @@ -11073,7 +11073,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -12143,7 +12143,7 @@ "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -12178,7 +12178,7 @@ "split2": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", "dev": true, "requires": { "through2": "^2.0.2" @@ -12240,7 +12240,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -12487,7 +12487,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -12843,7 +12843,7 @@ "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=", "dev": true, "requires": { "spdx-correct": "^3.0.0", diff --git a/package.json b/package.json index f27c0dfb0..a2eacbca3 100644 --- a/package.json +++ b/package.json @@ -42,10 +42,10 @@ "dependencies": { "@azure/ms-rest-nodeauth": "2.0.2", "@types/node": "^12.7.11", - "big-number": "1.0.0", "bl": "^3.0.0", "depd": "^2.0.0", "iconv-lite": "^0.5.0", + "jsbi": "^3.1.1", "native-duplexpair": "^1.0.0", "punycode": "^2.1.0", "readable-stream": "^3.4.0", diff --git a/src/ntlm-payload.ts b/src/ntlm-payload.ts index 5bab19a62..f79a19f92 100644 --- a/src/ntlm-payload.ts +++ b/src/ntlm-payload.ts @@ -1,9 +1,6 @@ import WritableTrackingBuffer from './tracking-buffer/writable-tracking-buffer'; import * as crypto from 'crypto'; - -const BigInteger = require('big-number'); - -const hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; +import JSBI from 'jsbi'; type Options = { domain: string, @@ -111,24 +108,15 @@ class NTLMResponsePayload { } createTimestamp(time: number) { - const tenthsOfAMicrosecond = BigInteger(time).plus(11644473600).multiply(10000000); - const hexArray = []; - - let pair = []; - while (tenthsOfAMicrosecond.val() !== '0') { - const idx = tenthsOfAMicrosecond.mod(16); - pair.unshift(hex[idx]); - if (pair.length === 2) { - hexArray.push(pair.join('')); - pair = []; - } - } + const tenthsOfAMicrosecond = JSBI.multiply(JSBI.add(JSBI.BigInt(time), JSBI.BigInt(11644473600)), JSBI.BigInt(10000000)); - if (pair.length > 0) { - hexArray.push(pair[0] + '0'); - } + const lo = JSBI.toNumber(JSBI.bitwiseAnd(tenthsOfAMicrosecond, JSBI.BigInt(0xffffffff))); + const hi = JSBI.toNumber(JSBI.bitwiseAnd(JSBI.signedRightShift(tenthsOfAMicrosecond, JSBI.BigInt(32)), JSBI.BigInt(0xffffffff))); - return Buffer.from(hexArray.join(''), 'hex'); + const result = Buffer.alloc(8); + result.writeUInt32LE(lo, 0); + result.writeUInt32LE(hi, 4); + return result; } lmv2Response(domain: string, user: string, password: string, serverNonce: Buffer, clientNonce: Buffer) { diff --git a/src/token/done-token-parser.ts b/src/token/done-token-parser.ts index 9ae96a34c..d1630cb65 100644 --- a/src/token/done-token-parser.ts +++ b/src/token/done-token-parser.ts @@ -1,3 +1,5 @@ +import JSBI from 'jsbi'; + import Parser from './stream-parser'; import { ColumnMetadata } from './colmetadata-token-parser'; import { InternalConnectionOptions } from '../connection'; @@ -33,7 +35,7 @@ function parseToken(parser: Parser, options: InternalConnectionOptions, callback const serverError = !!(status & STATUS.SRVERROR); parser.readUInt16LE((curCmd) => { - (options.tdsVersion < '7_2' ? parser.readUInt32LE : parser.readUInt64LE).call(parser, (rowCount) => { + const next = (rowCount: number) => { callback({ more: more, sqlError: sqlError, @@ -42,7 +44,15 @@ function parseToken(parser: Parser, options: InternalConnectionOptions, callback rowCount: rowCountValid ? rowCount : undefined, curCmd: curCmd }); - }); + }; + + if (options.tdsVersion < '7_2') { + parser.readUInt32LE(next); + } else { + parser.readBigUInt64LE((rowCount) => { + next(JSBI.toNumber(rowCount)); + }); + } }); }); } diff --git a/src/token/stream-parser.ts b/src/token/stream-parser.ts index 9f0e46ae9..cd0577c97 100644 --- a/src/token/stream-parser.ts +++ b/src/token/stream-parser.ts @@ -1,5 +1,6 @@ import Debug from '../debug'; import { InternalConnectionOptions } from '../connection'; +import JSBI from 'jsbi'; const Transform = require('readable-stream').Transform; import { TYPE, Token, EndOfMessageToken, ColMetadataToken } from './token'; @@ -212,6 +213,32 @@ class Parser extends Transform { }); } + readBigInt64LE(callback: (data: JSBI) => void) { + this.awaitData(8, () => { + const result = JSBI.add( + JSBI.leftShift( + JSBI.BigInt( + this.buffer[this.position + 4] + + this.buffer[this.position + 5] * 2 ** 8 + + this.buffer[this.position + 6] * 2 ** 16 + + (this.buffer[this.position + 7] << 24) // Overflow + ), + JSBI.BigInt(32) + ), + JSBI.BigInt( + this.buffer[this.position] + + this.buffer[this.position + 1] * 2 ** 8 + + this.buffer[this.position + 2] * 2 ** 16 + + this.buffer[this.position + 3] * 2 ** 24 + ) + ); + + this.position += 8; + + callback(result); + }); + } + readInt64LE(callback: (data: number) => void) { this.awaitData(8, () => { const data = Math.pow(2, 32) * this.buffer.readInt32LE(this.position + 4) + ((this.buffer[this.position + 4] & 0x80) === 0x80 ? 1 : -1) * this.buffer.readUInt32LE(this.position); @@ -228,6 +255,17 @@ class Parser extends Transform { }); } + readBigUInt64LE(callback: (data: JSBI) => void) { + this.awaitData(8, () => { + const low = JSBI.BigInt(this.buffer.readUInt32LE(this.position)); + const high = JSBI.BigInt(this.buffer.readUInt32LE(this.position + 4)); + + this.position += 8; + + callback(JSBI.add(low, JSBI.leftShift(high, JSBI.BigInt(32)))); + }); + } + readUInt64LE(callback: (data: number) => void) { this.awaitData(8, () => { const data = Math.pow(2, 32) * this.buffer.readUInt32LE(this.position + 4) + this.buffer.readUInt32LE(this.position); diff --git a/src/tracking-buffer/bigint.ts b/src/tracking-buffer/bigint.ts deleted file mode 100644 index 01b401e70..000000000 --- a/src/tracking-buffer/bigint.ts +++ /dev/null @@ -1,83 +0,0 @@ -function isZero(array: number[]) { - for (let j = 0, len = array.length; j < len; j++) { - const byte = array[j]; - if (byte !== 0) { - return false; - } - } - return true; -} - -function getNextRemainder(array: number[]) { - let remainder = 0; - - for (let i = array.length - 1; i >= 0; i--) { - const s = (remainder * 256) + array[i]; - array[i] = Math.floor(s / 10); - remainder = s % 10; - } - - return remainder; -} - -function invert(array: number[]) { - // Invert bits - const len = array.length; - - for (let i = 0; i < len; i++) { - array[i] = array[i] ^ 0xFF; - } - - for (let i = 0; i < len; i++) { - array[i] = array[i] + 1; - - if (array[i] > 255) { - array[i] = 0; - } else { - break; - } - } -} - -export function convertLEBytesToString(buffer: Buffer) { - const array = Array.prototype.slice.call(buffer, 0, buffer.length); - if (isZero(array)) { - return '0'; - } else { - let sign; - if (array[array.length - 1] & 0x80) { - sign = '-'; - invert(array); - } else { - sign = ''; - } - let result = ''; - while (!isZero(array)) { - const t = getNextRemainder(array); - result = t + result; - } - return sign + result; - } -} - -export function numberToInt64LE(num: number) { - // adapted from https://github.com/broofa/node-int64 - const negate = num < 0; - let hi = Math.abs(num); - let lo = hi % 0x100000000; - hi = (hi / 0x100000000) | 0; - const buf = Buffer.alloc(8, 0); - for (let i = 0; i <= 7; i++) { - buf[i] = lo & 0xff; - lo = i === 3 ? hi : lo >>> 8; - } - if (negate) { - let carry = 1; - for (let i = 0; i <= 7; i++) { - const v = (buf[i] ^ 0xff) + carry; - buf[i] = v & 0xff; - carry = v >> 8; - } - } - return buf; -} diff --git a/src/tracking-buffer/writable-tracking-buffer.ts b/src/tracking-buffer/writable-tracking-buffer.ts index 50f646a08..c5d9139ac 100644 --- a/src/tracking-buffer/writable-tracking-buffer.ts +++ b/src/tracking-buffer/writable-tracking-buffer.ts @@ -1,4 +1,4 @@ -import { numberToInt64LE } from './bigint'; +import JSBI from 'jsbi'; const SHIFT_LEFT_32 = (1 << 16) * (1 << 16); const SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32; @@ -106,9 +106,36 @@ class WritableTrackingBuffer { this.position += length; } + writeBigInt64LE(value: JSBI) { + this.writeBigU_Int64LE(value); + } + + private writeBigU_Int64LE(value: JSBI) { + this.makeRoomFor(8); + + let lo = JSBI.toNumber(JSBI.bitwiseAnd(value, JSBI.BigInt(0xffffffff))); + + this.buffer[this.position++] = lo; + lo = lo >> 8; + this.buffer[this.position++] = lo; + lo = lo >> 8; + this.buffer[this.position++] = lo; + lo = lo >> 8; + this.buffer[this.position++] = lo; + + let hi = JSBI.toNumber(JSBI.bitwiseAnd(JSBI.signedRightShift(value, JSBI.BigInt(32)), JSBI.BigInt(0xffffffff))); + + this.buffer[this.position++] = hi; + hi = hi >> 8; + this.buffer[this.position++] = hi; + hi = hi >> 8; + this.buffer[this.position++] = hi; + hi = hi >> 8; + this.buffer[this.position++] = hi; + } + writeInt64LE(value: number) { - const buf = numberToInt64LE(value); - this.copyFrom(buf); + this.writeBigInt64LE(JSBI.BigInt(value)); } writeUInt32BE(value: number) { @@ -125,8 +152,11 @@ class WritableTrackingBuffer { } writeUInt64LE(value: number) { - this.writeInt32LE(value & -1); - this.writeUInt32LE(Math.floor(value * SHIFT_RIGHT_32)); + this.writeBigUInt64LE(JSBI.BigInt(value)); + } + + writeBigUInt64LE(value: JSBI) { + this.writeBigU_Int64LE(value); } writeInt8(value: number) { diff --git a/src/value-parser.ts b/src/value-parser.ts index 5809b188c..68a5e3292 100644 --- a/src/value-parser.ts +++ b/src/value-parser.ts @@ -7,8 +7,6 @@ const iconv = require('iconv-lite'); const sprintf = require('sprintf-js').sprintf; import { bufferToLowerCaseGuid, bufferToUpperCaseGuid } from './guid-parser'; -const convertLEBytesToString = require('./tracking-buffer/bigint').convertLEBytesToString; - const NULL = (1 << 16) - 1; const MAX = (1 << 16) - 1; const THREE_AND_A_THIRD = 3 + (1 / 3); @@ -30,8 +28,8 @@ function readInt(parser: Parser, callback: (value: unknown) => void) { } function readBigInt(parser: Parser, callback: (value: unknown) => void) { - parser.readBuffer(8, (buffer) => { - callback(convertLEBytesToString(buffer)); + parser.readBigInt64LE((value) => { + callback(value.toString()); }); } diff --git a/test/integration/datatypes-in-results-test.js b/test/integration/datatypes-in-results-test.js index 620139636..46cd31954 100644 --- a/test/integration/datatypes-in-results-test.js +++ b/test/integration/datatypes-in-results-test.js @@ -127,6 +127,10 @@ describe('Datatypes in results test', function() { execSql(done, 'select cast(8 as bigint)', '8'); }); + it('should test negative big int', function(done) { + execSql(done, 'select cast(-8 as bigint)', '-8'); + }); + it('should test big int null', function(done) { execSql(done, 'select cast(null as bigint)', null); }); diff --git a/test/integration/rpc-test.js b/test/integration/rpc-test.js index 4212ab063..e55efad3f 100644 --- a/test/integration/rpc-test.js +++ b/test/integration/rpc-test.js @@ -201,6 +201,18 @@ describe('RPC test', function() { testProc(done, TYPES.SmallInt, 'smallint', null); }); + it('should exec proc bigint', function(done) { + testProc(done, TYPES.BigInt, 'bigint', '3'); + }); + + it('should exec proc negative bigint', function(done) { + testProc(done, TYPES.BigInt, 'bigint', '-3'); + }); + + it('should exec proc bigint null', function(done) { + testProc(done, TYPES.BigInt, 'bigint', null); + }); + it('should exec proc int', function(done) { testProc(done, TYPES.Int, 'int', 3); }); diff --git a/test/unit/tracking-buffer/bigint-test.js b/test/unit/tracking-buffer/bigint-test.js deleted file mode 100644 index 3dab31601..000000000 --- a/test/unit/tracking-buffer/bigint-test.js +++ /dev/null @@ -1,171 +0,0 @@ -const convertLEBytesToString = require('../../../src/tracking-buffer/bigint').convertLEBytesToString; -const numberToInt64LE = require('../../../src/tracking-buffer/bigint').numberToInt64LE; -const assert = require('chai').assert; - - -function assertBuffer(actual, expected) { - for (var i = 0, end = actual.length; i < end; i++) { - if (actual[i] !== expected[i]) { - console.log('actual ', actual); - console.log('expected', Buffer.from(expected)); - assert.isOk(false); - } - } -} - -describe('Bigint Test', () => { - it('should be zero', () => { - assert.strictEqual( - '0', - convertLEBytesToString(Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])) - ); - }); - - it('should be small positive', () => { - assert.strictEqual( - '1', - convertLEBytesToString(Buffer.from([1, 0, 0, 0, 0, 0, 0, 0])) - ); - assert.strictEqual( - '2', - convertLEBytesToString(Buffer.from([2, 0, 0, 0, 0, 0, 0, 0])) - ); - }); - - it('should be small negative', () => { - assert.strictEqual( - '-1', - convertLEBytesToString(Buffer.from([255, 255, 255, 255, 255, 255, 255, 255])) - ); - assert.strictEqual( - '-2', - convertLEBytesToString(Buffer.from([254, 255, 255, 255, 255, 255, 255, 255])) - ); - }); - - it('should be big positive', () => { - assert.strictEqual( - '9223372036854775807', - convertLEBytesToString(Buffer.from([255, 255, 255, 255, 255, 255, 255, 127])) - ); - }); - - it('should be big negative', () => { - assert.strictEqual( - '-9223372036854775808', - convertLEBytesToString(Buffer.from([0, 0, 0, 0, 0, 0, 0, 128])) - ); - }); - - it('should be powersOf10', () => { - assert.strictEqual( - '10', - convertLEBytesToString(Buffer.from([10, 0, 0, 0, 0, 0, 0, 0])) - ); - assert.strictEqual( - '100', - convertLEBytesToString(Buffer.from([100, 0, 0, 0, 0, 0, 0, 0])) - ); - assert.strictEqual( - '1000', - convertLEBytesToString(Buffer.from([232, 3, 0, 0, 0, 0, 0, 0])) - ); - assert.strictEqual( - '10000', - convertLEBytesToString(Buffer.from([16, 39, 0, 0, 0, 0, 0, 0])) - ); - }); - - it('should be toInt64LE', () => { - assertBuffer(numberToInt64LE(-3500000000), [ - 0x00, - 0x3d, - 0x62, - 0x2f, - 0xff, - 0xff, - 0xff, - 0xff - ]); - assertBuffer(numberToInt64LE(3500000000), [ - 0x00, - 0xc3, - 0x9d, - 0xd0, - 0x00, - 0x00, - 0x00, - 0x00 - ]); - assertBuffer(numberToInt64LE(-2), [ - 0xfe, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff - ]); - assertBuffer(numberToInt64LE(2), [ - 0x02, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 - ]); - assertBuffer(numberToInt64LE(0), [ - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 - ]); - assertBuffer(numberToInt64LE(-5000000000), [ - 0x00, - 0x0e, - 0xfa, - 0xd5, - 0xfe, - 0xff, - 0xff, - 0xff - ]); - assertBuffer(numberToInt64LE(5000000000), [ - 0x00, - 0xf2, - 0x05, - 0x2a, - 0x01, - 0x00, - 0x00, - 0x00 - ]); - assertBuffer(numberToInt64LE(5201683247893), [ - 0x15, - 0x73, - 0x7b, - 0x1c, - 0xbb, - 0x04, - 0x00, - 0x00 - ]); - assertBuffer(numberToInt64LE(-5201683247893), [ - 0xeb, - 0x8c, - 0x84, - 0xe3, - 0x44, - 0xfb, - 0xff, - 0xff - ]); - }); -}); diff --git a/test/unit/tracking-buffer/writable-tracking-buffer-test.js b/test/unit/tracking-buffer/writable-tracking-buffer-test.js index 221bc9010..0b758db59 100644 --- a/test/unit/tracking-buffer/writable-tracking-buffer-test.js +++ b/test/unit/tracking-buffer/writable-tracking-buffer-test.js @@ -1,5 +1,6 @@ const TrackingBuffer = require('../../../src/tracking-buffer/writable-tracking-buffer'); const assert = require('chai').assert; +const JSBI = require('jsbi'); function assertBuffer(actual, expected) { actual = actual.data; @@ -115,6 +116,22 @@ describe('Wrtiable Tracking Buffer', () => { assertBuffer(buffer, [0x03, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00]); }); + it('should write 64-bit signed JSBIs', () => { + const buffer = new TrackingBuffer(8); + + buffer.writeBigInt64LE(JSBI.BigInt('0x0807060504030201')); + + assertBuffer(buffer, [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + }); + + it('should write 64-bit unsigned JSBIs', () => { + const buffer = new TrackingBuffer(8); + + buffer.writeBigUInt64LE(JSBI.BigInt('0xdecafafecacefade')); + + assertBuffer(buffer, [0xde, 0xfa, 0xce, 0xca, 0xfe, 0xfa, 0xca, 0xde]); + }); + it('should copyFrom', () => { const buffer = new TrackingBuffer(10); const source = Buffer.from([0x01, 0x02, 0x03, 0x04]);