Skip to content

Commit f1e2b4a

Browse files
author
Tony Crisci
committed
make jsbi code paths optional
1 parent 369173a commit f1e2b4a

File tree

5 files changed

+144
-39
lines changed

5 files changed

+144
-39
lines changed

lib/constants.js

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,48 @@ MessageFlag.NO_REPLY_EXPECTED = 1;
205205
*/
206206
MessageFlag.NO_AUTO_START = 2;
207207

208+
const MAX_INT64_STR = '9223372036854775807';
209+
const MIN_INT64_STR = '-9223372036854775807';
210+
const MAX_UINT64_STR = '18446744073709551615';
211+
const MIN_UINT64_STR = '0';
212+
213+
const _JSBIConstants = {};
214+
215+
function _getJSBIConstants () {
216+
if (Object.keys(_JSBIConstants).length !== 0) {
217+
return _JSBIConstants;
218+
}
219+
220+
const JSBI = require('jsbi');
221+
222+
_JSBIConstants.MAX_INT64 = JSBI.BigInt(MAX_INT64_STR);
223+
_JSBIConstants.MIN_INT64 = JSBI.BigInt(MIN_INT64_STR);
224+
_JSBIConstants.MAX_UINT64 = JSBI.BigInt(MAX_UINT64_STR);
225+
_JSBIConstants.MIN_UINT64 = JSBI.BigInt(MIN_UINT64_STR);
226+
227+
return _JSBIConstants;
228+
}
229+
230+
const _BigIntConstants = {};
231+
232+
function _getBigIntConstants () {
233+
if (Object.keys(_BigIntConstants).length !== 0) {
234+
return _BigIntConstants;
235+
}
236+
237+
_BigIntConstants.MAX_INT64 = BigInt(MAX_INT64_STR);
238+
_BigIntConstants.MIN_INT64 = BigInt(MIN_INT64_STR);
239+
_BigIntConstants.MAX_UINT64 = BigInt(MAX_UINT64_STR);
240+
_BigIntConstants.MIN_UINT64 = BigInt(MIN_UINT64_STR);
241+
242+
return _BigIntConstants;
243+
}
244+
208245
module.exports = {
209-
MAX_INT64_STR: '9223372036854775807',
210-
MIN_INT64_STR: '-9223372036854775807',
211-
MAX_UINT64_STR: '18446744073709551615',
212-
MIN_UINT64_STR: '0',
246+
MAX_INT64_STR: MAX_INT64_STR,
247+
MIN_INT64_STR: MIN_INT64_STR,
248+
MAX_UINT64_STR: MAX_UINT64_STR,
249+
MIN_UINT64_STR: MIN_UINT64_STR,
213250

214251
NameFlag: NameFlag,
215252
RequestNameReply: RequestNameReply,
@@ -256,5 +293,7 @@ module.exports = {
256293
be: 66
257294
},
258295
messageSignature: 'yyyyuua(yv)',
259-
defaultAuthMethods: ['EXTERNAL', 'DBUS_COOKIE_SHA1', 'ANONYMOUS']
296+
defaultAuthMethods: ['EXTERNAL', 'DBUS_COOKIE_SHA1', 'ANONYMOUS'],
297+
_getJSBIConstants: _getJSBIConstants,
298+
_getBigIntConstants: _getBigIntConstants
260299
};

lib/marshallers.js

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
const Buffer = require('safe-buffer').Buffer;
22
const align = require('./align').align;
33
const { parseSignature } = require('../lib/signature');
4-
const JSBI = require('jsbi');
54
const Long = require('long');
5+
const { getBigIntCompat } = require('./library-options');
6+
const JSBI = require('jsbi');
67

78
const {
8-
MAX_INT64_STR, MIN_INT64_STR,
9-
MAX_UINT64_STR, MIN_UINT64_STR
9+
_getJSBIConstants, _getBigIntConstants
1010
} = require('./constants');
1111

1212
/*
@@ -184,10 +184,9 @@ var MakeSimpleMarshaller = function (signature) {
184184
};
185185
marshaller.marshall = function (ps, data) {
186186
data = this.check(data);
187-
const long = Long.fromString(data.toString(), true);
188187
align(ps, 8);
189-
ps.word32le(long.low);
190-
ps.word32le(long.high);
188+
ps.word32le(data.low);
189+
ps.word32le(data.high);
191190
ps._offset += 8;
192191
};
193192
break;
@@ -198,10 +197,9 @@ var MakeSimpleMarshaller = function (signature) {
198197
};
199198
marshaller.marshall = function (ps, data) {
200199
data = this.check(data);
201-
const long = Long.fromString(data.toString(), false);
202200
align(ps, 8);
203-
ps.word32le(long.low);
204-
ps.word32le(long.high);
201+
ps.word32le(data.low);
202+
ps.word32le(data.high);
205203
ps._offset += 8;
206204
};
207205
break;
@@ -251,17 +249,10 @@ var checkBoolean = function (data) {
251249
if (!(typeof data === 'boolean' || data === 0 || data === 1)) { throw new Error(`Data: ${data} was not of type boolean`); }
252250
};
253251

254-
const MAX_INT64 = JSBI.BigInt(MAX_INT64_STR);
255-
const MIN_INT64 = JSBI.BigInt(MIN_INT64_STR);
256-
const MAX_UINT64 = JSBI.BigInt(MAX_UINT64_STR);
257-
const MIN_UINT64 = JSBI.BigInt(MIN_UINT64_STR);
252+
const checkJSBILong = function (data, signed) {
253+
const { MAX_INT64, MIN_INT64, MAX_UINT64, MIN_UINT64 } = _getJSBIConstants();
258254

259-
var checkLong = function (data, signed) {
260-
if (typeof data === 'bigint') {
261-
data = JSBI.BigInt(data.toString());
262-
} else {
263-
data = JSBI.BigInt(data);
264-
}
255+
data = JSBI.BigInt(data.toString());
265256

266257
if (signed) {
267258
if (JSBI.greaterThan(data, MAX_INT64)) {
@@ -277,5 +268,39 @@ var checkLong = function (data, signed) {
277268
}
278269
}
279270

280-
return data;
271+
return Long.fromString(data.toString(), true);
272+
};
273+
274+
const checkBigIntLong = function (data, signed) {
275+
const { MAX_INT64, MIN_INT64, MAX_UINT64, MIN_UINT64 } = _getBigIntConstants();
276+
277+
if (typeof data !== 'bigint') {
278+
data = BigInt(data.toString());
279+
}
280+
281+
if (signed) {
282+
if (data > MAX_INT64) {
283+
throw new Error('data was out of range (greater than max int64)');
284+
} else if (data < MIN_INT64) {
285+
throw new Error('data was out of range (less than min int64)');
286+
}
287+
} else {
288+
if (data > MAX_UINT64) {
289+
throw new Error('data was out of range (greater than max uint64)');
290+
} else if (data < MIN_UINT64) {
291+
throw new Error('data was out of range (less than min uint64)');
292+
}
293+
}
294+
295+
return Long.fromString(data.toString(), true);
296+
};
297+
298+
var checkLong = function (data, signed) {
299+
const compat = getBigIntCompat();
300+
301+
if (compat) {
302+
return checkJSBILong(data, signed);
303+
} else {
304+
return checkBigIntLong(data, signed);
305+
}
281306
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
"unit": "jest ./test/*.test.js",
7070
"test": "dbus-run-session -- jest",
7171
"doc": "jsdoc --verbose -c jsdoc.conf --readme README.md -r lib index.js -d doc",
72-
"format": "cd lib && semistandard --fix && cd ../test && semistandard --env jest --parser babel-eslint --global BigInt --fix"
72+
"format": "cd lib && semistandard --global BigInt --fix && cd ../test && semistandard --env jest --parser babel-eslint --global BigInt --fix"
7373
},
7474
"jest": {
7575
"testEnvironment": "node",

test/integration/long-compat.test.js

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,9 @@ const {
1010
} = dbus.interface;
1111

1212
const {
13-
MAX_INT64_STR, MIN_INT64_STR,
14-
MAX_UINT64_STR, MIN_UINT64_STR
13+
_getJSBIConstants
1514
} = require('../../lib/constants');
1615

17-
const MAX_INT64 = JSBI.BigInt(MAX_INT64_STR);
18-
const MIN_INT64 = JSBI.BigInt(MIN_INT64_STR);
19-
const MAX_UINT64 = JSBI.BigInt(MAX_UINT64_STR);
20-
const MIN_UINT64 = JSBI.BigInt(MIN_UINT64_STR);
21-
2216
const TEST_NAME = 'org.test.long_compat';
2317
const TEST_PATH = '/org/test/path';
2418
const TEST_IFACE = 'org.test.iface';
@@ -59,6 +53,7 @@ afterAll(() => {
5953
});
6054

6155
test('test long type works correctly in compatibility mode', async () => {
56+
const { MAX_INT64, MIN_INT64, MAX_UINT64, MIN_UINT64 } = _getJSBIConstants();
6257
const object = await bus.getProxyObject(TEST_NAME, TEST_PATH);
6358
const test = object.getInterface(TEST_IFACE);
6459

@@ -81,21 +76,47 @@ test('test long type works correctly in compatibility mode', async () => {
8176
expect(result.prototype).toEqual(JSBI.BigInt.prototype);
8277
expect(JSBI.equal(result, what)).toEqual(true);
8378

79+
expect((async () => {
80+
result = await test.EchoSigned(JSBI.add(what, JSBI.BigInt(1)));
81+
return result.toString();
82+
})()).rejects.toThrow();
83+
8484
// int64 min
8585
what = MIN_INT64;
8686
result = await test.EchoSigned(what);
8787
expect(result.prototype).toEqual(JSBI.BigInt.prototype);
8888
expect(JSBI.equal(result, what)).toEqual(true);
8989

90+
await expect((async () => {
91+
result = await test.EchoSigned(JSBI.subtract(what, JSBI.BigInt(1)));
92+
return result.toString();
93+
})()).rejects.toThrow();
94+
9095
// uint64 max
9196
what = MAX_UINT64;
9297
result = await test.EchoUnsigned(what);
9398
expect(result.prototype).toEqual(JSBI.BigInt.prototype);
9499
expect(JSBI.equal(result, what)).toEqual(true);
95100

101+
await expect((async () => {
102+
result = await test.EchoUnsigned(JSBI.add(what, JSBI.BigInt(1)));
103+
return result.toString();
104+
})()).rejects.toThrow();
105+
96106
// uint64 min
97107
what = MIN_UINT64;
98108
result = await test.EchoUnsigned(what);
99109
expect(result.prototype).toEqual(JSBI.BigInt.prototype);
100110
expect(JSBI.equal(result, what)).toEqual(true);
111+
112+
await expect((async () => {
113+
result = await test.EchoUnsigned(JSBI.subtract(what, JSBI.BigInt(1)));
114+
return result.toString();
115+
})()).rejects.toThrow();
116+
117+
// int conversion
118+
what = 500;
119+
result = await test.EchoUnsigned(what);
120+
expect(result.prototype).toEqual(JSBI.BigInt.prototype);
121+
expect(JSBI.equal(result, JSBI.BigInt(what))).toEqual(true);
101122
});

test/integration/long.test.js

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@ if (typeof BigInt !== 'function') {
88
}
99

1010
const dbus = require('../../');
11+
const DBusError = dbus.DBusError;
1112

1213
const {
1314
Interface, method
1415
} = dbus.interface;
1516

1617
const {
17-
MAX_INT64_STR, MIN_INT64_STR,
18-
MAX_UINT64_STR, MIN_UINT64_STR
18+
_getBigIntConstants
1919
} = require('../../lib/constants');
2020

2121
const TEST_NAME = 'org.test.long';
2222
const TEST_PATH = '/org/test/path';
2323
const TEST_IFACE = 'org.test.iface';
24+
const TEST_ERROR_PATH = 'org.test.name.error';
2425

2526
const bus = dbus.sessionBus();
2627
bus.on('error', (err) => {
@@ -30,11 +31,17 @@ bus.on('error', (err) => {
3031
class LongInterface extends Interface {
3132
@method({ inSignature: 'x', outSignature: 'x' })
3233
EchoSigned (what) {
34+
if (typeof what !== 'bigint') {
35+
throw new DBusError(TEST_ERROR_PATH, 'interface with long expected a BigInt for type x');
36+
}
3337
return what;
3438
}
3539

3640
@method({ inSignature: 't', outSignature: 't' })
3741
EchoUnsigned (what) {
42+
if (typeof what !== 'bigint') {
43+
throw new DBusError(TEST_ERROR_PATH, 'interface with long expected a BigInt for type t');
44+
}
3845
return what;
3946
}
4047
}
@@ -51,10 +58,7 @@ afterAll(() => {
5158
});
5259

5360
testIfHasBigInt('test long type works correctly', async () => {
54-
const MAX_INT64 = BigInt(MAX_INT64_STR);
55-
const MIN_INT64 = BigInt(MIN_INT64_STR);
56-
const MAX_UINT64 = BigInt(MAX_UINT64_STR);
57-
const MIN_UINT64 = BigInt(MIN_UINT64_STR);
61+
const { MAX_INT64, MIN_INT64, MAX_UINT64, MIN_UINT64 } = _getBigIntConstants();
5862

5963
const object = await bus.getProxyObject(TEST_NAME, TEST_PATH);
6064
const test = object.getInterface(TEST_IFACE);
@@ -76,18 +80,34 @@ testIfHasBigInt('test long type works correctly', async () => {
7680
result = await test.EchoSigned(what);
7781
expect(result === what).toEqual(true);
7882

83+
expect((async () => {
84+
return await test.EchoSigned(what + 1n);
85+
})()).rejects.toThrow();
86+
7987
// int64 min
8088
what = MIN_INT64;
8189
result = await test.EchoSigned(what);
8290
expect(result === what).toEqual(true);
8391

92+
expect((async () => {
93+
return await test.EchoSigned(what - 1n);
94+
})()).rejects.toThrow();
95+
8496
// uint64 max
8597
what = MAX_UINT64;
8698
result = await test.EchoUnsigned(what);
8799
expect(result === what).toEqual(true);
88100

101+
expect((async () => {
102+
return await test.EchoUnsigned(what + 1n);
103+
})()).rejects.toThrow();
104+
89105
// uint64 min
90106
what = MIN_UINT64;
91107
result = await test.EchoUnsigned(what);
92108
expect(result === what).toEqual(true);
109+
110+
expect((async () => {
111+
return await test.EchoUnsigned(what - 1n);
112+
})()).rejects.toThrow();
93113
});

0 commit comments

Comments
 (0)