| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9d8677b commit 5bd99e4
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2978,6 +2978,15 @@ category. | |||
| 2978 | 2978 | The `node:trace_events` module could not be loaded because Node.js was compiled | |
| 2979 | 2979 | with the `--without-v8-platform` flag. | |
| 2980 | 2980 | ||
| 2981 | + <a id="ERR_TRAILING_JUNK_AFTER_STREAM_END"></a> | ||
| 2982 | + | ||
| 2983 | + ### `ERR_TRAILING_JUNK_AFTER_STREAM_END` | ||
| 2984 | + | ||
| 2985 | + Trailing junk found after the end of the compressed stream. | ||
| 2986 | + This error is thrown when extra, unexpected data is detected | ||
| 2987 | + after the end of a compressed stream (for example, in zlib | ||
| 2988 | + or gzip decompression). | ||
| 2989 | + | ||
| 2981 | 2990 | <a id="ERR_TRANSFORM_ALREADY_TRANSFORMING"></a> | |
| 2982 | 2991 | ||
| 2983 | 2992 | ### `ERR_TRANSFORM_ALREADY_TRANSFORMING` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1806,6 +1806,8 @@ E('ERR_TRACE_EVENTS_CATEGORY_REQUIRED', | |||
| 1806 | 1806 | 'At least one category is required', TypeError); | |
| 1807 | 1807 | E('ERR_TRACE_EVENTS_UNAVAILABLE', 'Trace events are unavailable', Error); | |
| 1808 | 1808 | ||
| 1809 | + E('ERR_TRAILING_JUNK_AFTER_STREAM_END', 'Trailing junk found after the end of the compressed stream', TypeError); | ||
| 1810 | + | ||
| 1809 | 1811 | // This should probably be a `RangeError`. | |
| 1810 | 1812 | E('ERR_TTY_INIT_FAILED', 'TTY initialization failed', SystemError); | |
| 1811 | 1813 | E('ERR_UNAVAILABLE_DURING_EXIT', 'Cannot call function in process exit ' + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,16 +99,28 @@ class DecompressionStream { | |||
| 99 | 99 | }); | |
| 100 | 100 | switch (format) { | |
| 101 | 101 | case 'deflate': | |
| 102 | - this.#handle = lazyZlib().createInflate(); | ||
| 102 | + this.#handle = lazyZlib().createInflate({ | ||
| 103 | + rejectGarbageAfterEnd: true, | ||
| 104 | + }); | ||
| 103 | 105 | break; | |
| 104 | 106 | case 'deflate-raw': | |
| 105 | 107 | this.#handle = lazyZlib().createInflateRaw(); | |
| 106 | 108 | break; | |
| 107 | 109 | case 'gzip': | |
| 108 | - this.#handle = lazyZlib().createGunzip(); | ||
| 110 | + this.#handle = lazyZlib().createGunzip({ | ||
| 111 | + rejectGarbageAfterEnd: true, | ||
| 112 | + }); | ||
| 109 | 113 | break; | |
| 110 | 114 | } | |
| 111 | 115 | this.#transform = newReadableWritablePairFromDuplex(this.#handle); | |
| 116 | + | ||
| 117 | + this.#handle.on('error', (err) => { | ||
| 118 | + if (this.#transform?.writable && | ||
| 119 | + !this.#transform.writable.locked && | ||
| 120 | + typeof this.#transform.writable.abort === 'function') { | ||
| 121 | + this.#transform.writable.abort(err); | ||
| 122 | + } | ||
| 123 | + }); | ||
| 112 | 124 | } | |
| 113 | 125 | ||
| 114 | 126 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,6 +42,7 @@ const { | |||
| 42 | 42 | ERR_BUFFER_TOO_LARGE, | |
| 43 | 43 | ERR_INVALID_ARG_TYPE, | |
| 44 | 44 | ERR_OUT_OF_RANGE, | |
| 45 | + ERR_TRAILING_JUNK_AFTER_STREAM_END, | ||
| 45 | 46 | ERR_ZSTD_INVALID_PARAM, | |
| 46 | 47 | }, | |
| 47 | 48 | genericNodeError, | |
@@ -266,6 +267,8 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) { | |||
| 266 | 267 | this._defaultFullFlushFlag = fullFlush; | |
| 267 | 268 | this._info = opts?.info; | |
| 268 | 269 | this._maxOutputLength = maxOutputLength; | |
| 270 | + | ||
| 271 | + this._rejectGarbageAfterEnd = opts?.rejectGarbageAfterEnd === true; | ||
| 269 | 272 | } | |
| 270 | 273 | ObjectSetPrototypeOf(ZlibBase.prototype, Transform.prototype); | |
| 271 | 274 | ObjectSetPrototypeOf(ZlibBase, Transform); | |
@@ -588,6 +591,14 @@ function processCallback() { | |||
| 588 | 591 | // stream has ended early. | |
| 589 | 592 | // This applies to streams where we don't check data past the end of | |
| 590 | 593 | // what was consumed; that is, everything except Gunzip/Unzip. | |
| 594 | + | ||
| 595 | + if (self._rejectGarbageAfterEnd) { | ||
| 596 | + const err = new ERR_TRAILING_JUNK_AFTER_STREAM_END(); | ||
| 597 | + self.destroy(err); | ||
| 598 | + this.cb(err); | ||
| 599 | + return; | ||
| 600 | + } | ||
| 601 | + | ||
| 591 | 602 | self.push(null); | |
| 592 | 603 | } | |
| 593 | 604 | ||
@@ -680,6 +691,7 @@ function Zlib(opts, mode) { | |||
| 680 | 691 | ||
| 681 | 692 | this._level = level; | |
| 682 | 693 | this._strategy = strategy; | |
| 694 | + this._mode = mode; | ||
| 683 | 695 | } | |
| 684 | 696 | ObjectSetPrototypeOf(Zlib.prototype, ZlibBase.prototype); | |
| 685 | 697 | ObjectSetPrototypeOf(Zlib, ZlibBase); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + require('../common'); | ||
| 3 | + const assert = require('assert').strict; | ||
| 4 | + const test = require('node:test'); | ||
| 5 | + const { DecompressionStream } = require('stream/web'); | ||
| 6 | + | ||
| 7 | + async function expectTypeError(promise) { | ||
| 8 | + let threw = false; | ||
| 9 | + try { | ||
| 10 | + await promise; | ||
| 11 | + } catch (err) { | ||
| 12 | + threw = true; | ||
| 13 | + assert(err instanceof TypeError, `Expected TypeError, got ${err}`); | ||
| 14 | + } | ||
| 15 | + assert(threw, 'Expected promise to reject'); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + test('DecompressStream deflat emits error on trailing data', async () => { | ||
| 19 | + const valid = new Uint8Array([120, 156, 75, 4, 0, 0, 98, 0, 98]); // deflate('a') | ||
| 20 | + const empty = new Uint8Array(1); | ||
| 21 | + const invalid = new Uint8Array([...valid, ...empty]); | ||
| 22 | + const double = new Uint8Array([...valid, ...valid]); | ||
| 23 | + | ||
| 24 | + for (const chunk of [[invalid], [valid, empty], [valid, valid], [valid, double]]) { | ||
| 25 | + await expectTypeError( | ||
| 26 | + Array.fromAsync( | ||
| 27 | + new Blob([chunk]).stream().pipeThrough(new DecompressionStream('deflate')) | ||
| 28 | + ) | ||
| 29 | + ); | ||
| 30 | + } | ||
| 31 | + }); | ||
| 32 | + | ||
| 33 | + test('DecompressStream gzip emits error on trailing data', async () => { | ||
| 34 | + const valid = new Uint8Array([31, 139, 8, 0, 0, 0, 0, 0, 0, 19, 75, 4, | ||
| 35 | + 0, 67, 190, 183, 232, 1, 0, 0, 0]); // gzip('a') | ||
| 36 | + const empty = new Uint8Array(1); | ||
| 37 | + const invalid = new Uint8Array([...valid, ...empty]); | ||
| 38 | + const double = new Uint8Array([...valid, ...valid]); | ||
| 39 | + for (const chunk of [[invalid], [valid, empty], [valid, valid], [double]]) { | ||
| 40 | + await expectTypeError( | ||
| 41 | + Array.fromAsync( | ||
| 42 | + new Blob([chunk]).stream().pipeThrough(new DecompressionStream('gzip')) | ||
| 43 | + ) | ||
| 44 | + ); | ||
| 45 | + } | ||
| 46 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,14 +11,6 @@ | |||
| 11 | 11 | "compression-with-detach.tentative.window.js": { | |
| 12 | 12 | "requires": ["crypto"] | |
| 13 | 13 | }, | |
| 14 | - "decompression-corrupt-input.tentative.any.js": { | ||
| 15 | - "fail": { | ||
| 16 | - "expected": [ | ||
| 17 | - "trailing junk for 'deflate' should give an error", | ||
| 18 | - "trailing junk for 'gzip' should give an error" | ||
| 19 | - ] | ||
| 20 | - } | ||
| 21 | - }, | ||
| 22 | 14 | "idlharness-shadowrealm.window.js": { | |
| 23 | 15 | "skip": "ShadowRealm support is not enabled" | |
| 24 | 16 | }, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments