| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3a6bd9c commit e8a07f2
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3012,6 +3012,15 @@ category. | |||
| 3012 | 3012 | The `node:trace_events` module could not be loaded because Node.js was compiled | |
| 3013 | 3013 | with the `--without-v8-platform` flag. | |
| 3014 | 3014 | ||
| 3015 | + <a id="ERR_TRAILING_JUNK_AFTER_STREAM_END"></a> | ||
| 3016 | + | ||
| 3017 | + ### `ERR_TRAILING_JUNK_AFTER_STREAM_END` | ||
| 3018 | + | ||
| 3019 | + Trailing junk found after the end of the compressed stream. | ||
| 3020 | + This error is thrown when extra, unexpected data is detected | ||
| 3021 | + after the end of a compressed stream (for example, in zlib | ||
| 3022 | + or gzip decompression). | ||
| 3023 | + | ||
| 3015 | 3024 | <a id="ERR_TRANSFORM_ALREADY_TRANSFORMING"></a> | |
| 3016 | 3025 | ||
| 3017 | 3026 | ### `ERR_TRANSFORM_ALREADY_TRANSFORMING` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1803,6 +1803,8 @@ E('ERR_TRACE_EVENTS_CATEGORY_REQUIRED', | |||
| 1803 | 1803 | 'At least one category is required', TypeError); | |
| 1804 | 1804 | E('ERR_TRACE_EVENTS_UNAVAILABLE', 'Trace events are unavailable', Error); | |
| 1805 | 1805 | ||
| 1806 | + E('ERR_TRAILING_JUNK_AFTER_STREAM_END', 'Trailing junk found after the end of the compressed stream', TypeError); | ||
| 1807 | + | ||
| 1806 | 1808 | // This should probably be a `RangeError`. | |
| 1807 | 1809 | E('ERR_TTY_INIT_FAILED', 'TTY initialization failed', SystemError); | |
| 1808 | 1810 | 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); | |
@@ -570,6 +573,14 @@ function processCallback() { | |||
| 570 | 573 | // stream has ended early. | |
| 571 | 574 | // This applies to streams where we don't check data past the end of | |
| 572 | 575 | // what was consumed; that is, everything except Gunzip/Unzip. | |
| 576 | + | ||
| 577 | + if (self._rejectGarbageAfterEnd) { | ||
| 578 | + const err = new ERR_TRAILING_JUNK_AFTER_STREAM_END(); | ||
| 579 | + self.destroy(err); | ||
| 580 | + this.cb(err); | ||
| 581 | + return; | ||
| 582 | + } | ||
| 583 | + | ||
| 573 | 584 | self.push(null); | |
| 574 | 585 | } | |
| 575 | 586 | ||
@@ -662,6 +673,7 @@ function Zlib(opts, mode) { | |||
| 662 | 673 | ||
| 663 | 674 | this._level = level; | |
| 664 | 675 | this._strategy = strategy; | |
| 676 | + this._mode = mode; | ||
| 665 | 677 | } | |
| 666 | 678 | ObjectSetPrototypeOf(Zlib.prototype, ZlibBase.prototype); | |
| 667 | 679 | 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