Skip to content

Commit f2336c2

Browse files
Merge pull request #980 from tediousjs/arthur/jsbi
Use `jsbi` for internal 64bit integer calculations
2 parents d83256f + b969541 commit f2336c2

File tree

12 files changed

+152
-309
lines changed

12 files changed

+152
-309
lines changed

package-lock.json

Lines changed: 23 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@
4242
"dependencies": {
4343
"@azure/ms-rest-nodeauth": "2.0.2",
4444
"@types/node": "^12.7.11",
45-
"big-number": "1.0.0",
4645
"bl": "^3.0.0",
4746
"depd": "^2.0.0",
4847
"iconv-lite": "^0.5.0",
48+
"jsbi": "^3.1.1",
4949
"native-duplexpair": "^1.0.0",
5050
"punycode": "^2.1.0",
5151
"readable-stream": "^3.4.0",

src/ntlm-payload.ts

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import WritableTrackingBuffer from './tracking-buffer/writable-tracking-buffer';
22
import * as crypto from 'crypto';
3-
4-
const BigInteger = require('big-number');
5-
6-
const hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
3+
import JSBI from 'jsbi';
74

85
type Options = {
96
domain: string,
@@ -111,24 +108,15 @@ class NTLMResponsePayload {
111108
}
112109

113110
createTimestamp(time: number) {
114-
const tenthsOfAMicrosecond = BigInteger(time).plus(11644473600).multiply(10000000);
115-
const hexArray = [];
116-
117-
let pair = [];
118-
while (tenthsOfAMicrosecond.val() !== '0') {
119-
const idx = tenthsOfAMicrosecond.mod(16);
120-
pair.unshift(hex[idx]);
121-
if (pair.length === 2) {
122-
hexArray.push(pair.join(''));
123-
pair = [];
124-
}
125-
}
111+
const tenthsOfAMicrosecond = JSBI.multiply(JSBI.add(JSBI.BigInt(time), JSBI.BigInt(11644473600)), JSBI.BigInt(10000000));
126112

127-
if (pair.length > 0) {
128-
hexArray.push(pair[0] + '0');
129-
}
113+
const lo = JSBI.toNumber(JSBI.bitwiseAnd(tenthsOfAMicrosecond, JSBI.BigInt(0xffffffff)));
114+
const hi = JSBI.toNumber(JSBI.bitwiseAnd(JSBI.signedRightShift(tenthsOfAMicrosecond, JSBI.BigInt(32)), JSBI.BigInt(0xffffffff)));
130115

131-
return Buffer.from(hexArray.join(''), 'hex');
116+
const result = Buffer.alloc(8);
117+
result.writeUInt32LE(lo, 0);
118+
result.writeUInt32LE(hi, 4);
119+
return result;
132120
}
133121

134122
lmv2Response(domain: string, user: string, password: string, serverNonce: Buffer, clientNonce: Buffer) {

src/token/done-token-parser.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import JSBI from 'jsbi';
2+
13
import Parser from './stream-parser';
24
import { ColumnMetadata } from './colmetadata-token-parser';
35
import { InternalConnectionOptions } from '../connection';
@@ -33,7 +35,7 @@ function parseToken(parser: Parser, options: InternalConnectionOptions, callback
3335
const serverError = !!(status & STATUS.SRVERROR);
3436

3537
parser.readUInt16LE((curCmd) => {
36-
(options.tdsVersion < '7_2' ? parser.readUInt32LE : parser.readUInt64LE).call(parser, (rowCount) => {
38+
const next = (rowCount: number) => {
3739
callback({
3840
more: more,
3941
sqlError: sqlError,
@@ -42,7 +44,15 @@ function parseToken(parser: Parser, options: InternalConnectionOptions, callback
4244
rowCount: rowCountValid ? rowCount : undefined,
4345
curCmd: curCmd
4446
});
45-
});
47+
};
48+
49+
if (options.tdsVersion < '7_2') {
50+
parser.readUInt32LE(next);
51+
} else {
52+
parser.readBigUInt64LE((rowCount) => {
53+
next(JSBI.toNumber(rowCount));
54+
});
55+
}
4656
});
4757
});
4858
}

src/token/stream-parser.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Debug from '../debug';
22
import { InternalConnectionOptions } from '../connection';
3+
import JSBI from 'jsbi';
34

45
const Transform = require('readable-stream').Transform;
56
import { TYPE, Token, EndOfMessageToken, ColMetadataToken } from './token';
@@ -212,6 +213,32 @@ class Parser extends Transform {
212213
});
213214
}
214215

216+
readBigInt64LE(callback: (data: JSBI) => void) {
217+
this.awaitData(8, () => {
218+
const result = JSBI.add(
219+
JSBI.leftShift(
220+
JSBI.BigInt(
221+
this.buffer[this.position + 4] +
222+
this.buffer[this.position + 5] * 2 ** 8 +
223+
this.buffer[this.position + 6] * 2 ** 16 +
224+
(this.buffer[this.position + 7] << 24) // Overflow
225+
),
226+
JSBI.BigInt(32)
227+
),
228+
JSBI.BigInt(
229+
this.buffer[this.position] +
230+
this.buffer[this.position + 1] * 2 ** 8 +
231+
this.buffer[this.position + 2] * 2 ** 16 +
232+
this.buffer[this.position + 3] * 2 ** 24
233+
)
234+
);
235+
236+
this.position += 8;
237+
238+
callback(result);
239+
});
240+
}
241+
215242
readInt64LE(callback: (data: number) => void) {
216243
this.awaitData(8, () => {
217244
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 {
228255
});
229256
}
230257

258+
readBigUInt64LE(callback: (data: JSBI) => void) {
259+
this.awaitData(8, () => {
260+
const low = JSBI.BigInt(this.buffer.readUInt32LE(this.position));
261+
const high = JSBI.BigInt(this.buffer.readUInt32LE(this.position + 4));
262+
263+
this.position += 8;
264+
265+
callback(JSBI.add(low, JSBI.leftShift(high, JSBI.BigInt(32))));
266+
});
267+
}
268+
231269
readUInt64LE(callback: (data: number) => void) {
232270
this.awaitData(8, () => {
233271
const data = Math.pow(2, 32) * this.buffer.readUInt32LE(this.position + 4) + this.buffer.readUInt32LE(this.position);

0 commit comments

Comments
 (0)