Skip to content

Commit 4f20aed

Browse files
[fix] Handle oversized messages with designated error (#2285)
Ensure that the correct error is surfaced when the max message size is exceeded.
1 parent aa998e3 commit 4f20aed

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

lib/permessage-deflate.js

+14
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,14 @@ function inflateOnData(chunk) {
494494
this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';
495495
this[kError][kStatusCode] = 1009;
496496
this.removeListener('data', inflateOnData);
497+
498+
//
499+
// The choice to employ `zlib.reset()` over `zlib.close()` is dictated by the
500+
// fact that in Node.js versions prior to 13.10.0, the callback for
501+
// `zlib.flush()` is not called if `zlib.close()` is used. Utilizing
502+
// `zlib.reset()` ensures that either the callback is invoked or an error is
503+
// emitted.
504+
//
497505
this.reset();
498506
}
499507

@@ -509,6 +517,12 @@ function inflateOnError(err) {
509517
// closed when an error is emitted.
510518
//
511519
this[kPerMessageDeflate]._inflate = null;
520+
521+
if (this[kError]) {
522+
this[kCallback](this[kError]);
523+
return;
524+
}
525+
512526
err[kStatusCode] = 1007;
513527
this[kCallback](err);
514528
}

test/permessage-deflate.test.js

+20-2
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,27 @@ describe('PerMessageDeflate', () => {
590590
});
591591
});
592592

593-
it("doesn't call the callback twice when `maxPayload` is exceeded", (done) => {
593+
it('calls the callback when `maxPayload` is exceeded (1/2)', (done) => {
594594
const perMessageDeflate = new PerMessageDeflate({}, false, 25);
595-
const buf = Buffer.from('A'.repeat(50));
595+
const buf = Buffer.alloc(50, 'A');
596+
597+
perMessageDeflate.accept([{}]);
598+
perMessageDeflate.compress(buf, true, (err, data) => {
599+
if (err) return done(err);
600+
601+
perMessageDeflate.decompress(data, true, (err) => {
602+
assert.ok(err instanceof RangeError);
603+
assert.strictEqual(err.message, 'Max payload size exceeded');
604+
done();
605+
});
606+
});
607+
});
608+
609+
it('calls the callback when `maxPayload` is exceeded (2/2)', (done) => {
610+
// A copy of the previous test but with a larger input. See
611+
// https://github.com/websockets/ws/pull/2285.
612+
const perMessageDeflate = new PerMessageDeflate({}, false, 25);
613+
const buf = Buffer.alloc(1024 * 1024, 'A');
596614

597615
perMessageDeflate.accept([{}]);
598616
perMessageDeflate.compress(buf, true, (err, data) => {

0 commit comments

Comments
 (0)