Skip to content

Commit 3fdfdac

Browse files
committed
dgram: fix send with out of bounds offset + length
fix Socket.prototype.send sending garbage when the message is a string, or Buffer and offset+length is out of bounds. Fixes: #40491
1 parent 89c0577 commit 3fdfdac

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

lib/dgram.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const { guessHandleType } = internalBinding('util');
4242
const {
4343
ERR_INVALID_ARG_TYPE,
4444
ERR_MISSING_ARGS,
45+
ERR_OUT_OF_RANGE,
4546
ERR_SOCKET_ALREADY_BOUND,
4647
ERR_SOCKET_BAD_BUFFER_SIZE,
4748
ERR_SOCKET_BUFFER_SIZE,
@@ -488,6 +489,18 @@ function sliceBuffer(buffer, offset, length) {
488489
offset = offset >>> 0;
489490
length = length >>> 0;
490491

492+
// TypedArray and DataView bounds are checked in Buffer.from
493+
if (Buffer.isBuffer(buffer)) {
494+
if (offset > buffer.byteLength) {
495+
throw new ERR_OUT_OF_RANGE('offset', `<= ${buffer.byteLength}`, offset);
496+
}
497+
498+
if (offset + length > buffer.byteLength) {
499+
throw new ERR_OUT_OF_RANGE('length',
500+
`<= ${buffer.byteLength - offset}`, length);
501+
}
502+
}
503+
491504
return Buffer.from(buffer.buffer, buffer.byteOffset + offset, length);
492505
}
493506

test/parallel/test-dgram-send-bad-arguments.js

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,71 @@ function checkArgs(connected) {
7777
message: 'Already connected'
7878
}
7979
);
80+
81+
for (const input of ['hello', Buffer.from('hello'),
82+
Buffer.from('hello world').subarray(0, 5),
83+
Buffer.from('hello world').subarray(6)]) {
84+
assert.throws(
85+
() => { sock.send(input, 6, 0); },
86+
{
87+
code: 'ERR_OUT_OF_RANGE',
88+
name: 'RangeError',
89+
message: 'The value of "offset" is out of range. ' +
90+
'It must be <= 5. Received 6'
91+
}
92+
);
93+
94+
assert.throws(
95+
() => { sock.send(input, 0, 6); },
96+
{
97+
code: 'ERR_OUT_OF_RANGE',
98+
name: 'RangeError',
99+
message: 'The value of "length" is out of range. ' +
100+
'It must be <= 5. Received 6'
101+
}
102+
);
103+
104+
assert.throws(
105+
() => { sock.send(input, 3, 4); },
106+
{
107+
code: 'ERR_OUT_OF_RANGE',
108+
name: 'RangeError',
109+
message: 'The value of "length" is out of range. ' +
110+
'It must be <= 2. Received 4'
111+
}
112+
);
113+
}
114+
115+
for (const input of [new Uint8Array([1, 2, 3, 4, 5]),
116+
new DataView(new ArrayBuffer(5), 0),
117+
new DataView(new ArrayBuffer(6), 2)]) {
118+
assert.throws(
119+
() => { sock.send(input, 6, 0); },
120+
{
121+
code: 'ERR_BUFFER_OUT_OF_BOUNDS',
122+
name: 'RangeError',
123+
message: '"offset" is outside of buffer bounds',
124+
}
125+
);
126+
127+
assert.throws(
128+
() => { sock.send(input, 0, 6); },
129+
{
130+
code: 'ERR_BUFFER_OUT_OF_BOUNDS',
131+
name: 'RangeError',
132+
message: '"length" is outside of buffer bounds',
133+
}
134+
);
135+
136+
assert.throws(
137+
() => { sock.send(input, 3, 4); },
138+
{
139+
code: 'ERR_BUFFER_OUT_OF_BOUNDS',
140+
name: 'RangeError',
141+
message: '"length" is outside of buffer bounds',
142+
}
143+
);
144+
}
80145
} else {
81146
assert.throws(() => { sock.send(buf, 1, 1, -1, host); }, RangeError);
82147
assert.throws(() => { sock.send(buf, 1, 1, 0, host); }, RangeError);
@@ -90,7 +155,7 @@ function checkArgs(connected) {
90155
code: 'ERR_INVALID_ARG_TYPE',
91156
name: 'TypeError',
92157
message: 'The "buffer" argument must be of type string or an instance ' +
93-
'of Buffer, TypedArray, or DataView. Received type number (23)'
158+
'of Buffer, TypedArray, or DataView. Received type number (23)'
94159
}
95160
);
96161

@@ -101,8 +166,8 @@ function checkArgs(connected) {
101166
code: 'ERR_INVALID_ARG_TYPE',
102167
name: 'TypeError',
103168
message: 'The "buffer list arguments" argument must be of type string ' +
104-
'or an instance of Buffer, TypedArray, or DataView. ' +
105-
'Received an instance of Array'
169+
'or an instance of Buffer, TypedArray, or DataView. ' +
170+
'Received an instance of Array'
106171
}
107172
);
108173
}

0 commit comments

Comments
 (0)