Skip to content

Commit 333adf6

Browse files
committed
crypto: fix error handling
This fixes multiple cases where the wrong error was returned in case of e.g. a overflow / wrong type. PR-URL: nodejs#19445 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent c1278e5 commit 333adf6

File tree

2 files changed

+111
-269
lines changed

2 files changed

+111
-269
lines changed

lib/internal/crypto/random.js

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,44 @@ const {
1313

1414
const { kMaxLength } = require('buffer');
1515
const kMaxUint32 = Math.pow(2, 32) - 1;
16+
const kMaxPossibleLength = Math.min(kMaxLength, kMaxUint32);
1617

17-
function assertOffset(offset, length) {
18-
if (typeof offset !== 'number' || Number.isNaN(offset)) {
19-
throw new ERR_INVALID_ARG_TYPE('offset', 'number');
18+
function assertOffset(offset, elementSize, length) {
19+
if (typeof offset !== 'number') {
20+
throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
2021
}
2122

22-
if (offset > kMaxUint32 || offset < 0) {
23-
throw new ERR_INVALID_ARG_TYPE('offset', 'uint32');
24-
}
23+
offset *= elementSize;
2524

26-
if (offset > kMaxLength || offset > length) {
27-
throw new ERR_OUT_OF_RANGE('offset');
25+
const maxLength = Math.min(length, kMaxPossibleLength);
26+
if (Number.isNaN(offset) || offset > maxLength || offset < 0) {
27+
throw new ERR_OUT_OF_RANGE('offset', `>= 0 && <= ${maxLength}`, offset);
2828
}
29+
30+
return offset;
2931
}
3032

31-
function assertSize(size, offset = 0, length = Infinity) {
32-
if (typeof size !== 'number' || Number.isNaN(size)) {
33-
throw new ERR_INVALID_ARG_TYPE('size', 'number');
33+
function assertSize(size, elementSize, offset, length) {
34+
if (typeof size !== 'number') {
35+
throw new ERR_INVALID_ARG_TYPE('size', 'number', size);
3436
}
3537

36-
if (size > kMaxUint32 || size < 0) {
37-
throw new ERR_INVALID_ARG_TYPE('size', 'uint32');
38+
size *= elementSize;
39+
40+
if (Number.isNaN(size) || size > kMaxPossibleLength || size < 0) {
41+
throw new ERR_OUT_OF_RANGE('size',
42+
`>= 0 && <= ${kMaxPossibleLength}`, size);
3843
}
3944

40-
if (size + offset > length || size > kMaxLength) {
41-
throw new ERR_OUT_OF_RANGE('size');
45+
if (size + offset > length) {
46+
throw new ERR_OUT_OF_RANGE('size + offset', `<= ${length}`, size + offset);
4247
}
48+
49+
return size;
4350
}
4451

4552
function randomBytes(size, cb) {
46-
assertSize(size);
53+
assertSize(size, 1, 0, Infinity);
4754
if (cb !== undefined && typeof cb !== 'function')
4855
throw new ERR_INVALID_CALLBACK();
4956
return _randomBytes(size, cb);
@@ -56,17 +63,14 @@ function randomFillSync(buf, offset = 0, size) {
5663

5764
const elementSize = buf.BYTES_PER_ELEMENT || 1;
5865

59-
offset *= elementSize;
60-
assertOffset(offset, buf.byteLength);
66+
offset = assertOffset(offset, elementSize, buf.byteLength);
6167

6268
if (size === undefined) {
6369
size = buf.byteLength - offset;
6470
} else {
65-
size *= elementSize;
71+
size = assertSize(size, elementSize, offset, buf.byteLength);
6672
}
6773

68-
assertSize(size, offset, buf.byteLength);
69-
7074
return _randomFill(buf, offset, size);
7175
}
7276

@@ -83,20 +87,19 @@ function randomFill(buf, offset, size, cb) {
8387
size = buf.bytesLength;
8488
} else if (typeof size === 'function') {
8589
cb = size;
86-
offset *= elementSize;
8790
size = buf.byteLength - offset;
8891
} else if (typeof cb !== 'function') {
8992
throw new ERR_INVALID_CALLBACK();
9093
}
94+
95+
offset = assertOffset(offset, elementSize, buf.byteLength);
96+
9197
if (size === undefined) {
9298
size = buf.byteLength - offset;
9399
} else {
94-
size *= elementSize;
100+
size = assertSize(size, elementSize, offset, buf.byteLength);
95101
}
96102

97-
assertOffset(offset, buf.byteLength);
98-
assertSize(size, offset, buf.byteLength);
99-
100103
return _randomFill(buf, offset, size, cb);
101104
}
102105

0 commit comments

Comments
 (0)