From 98ec000e621f11b39773ff0cc654e3947f12545e Mon Sep 17 00:00:00 2001 From: MP GOWTHAM Date: Fri, 14 Aug 2026 18:54:45 +0530 Subject: [PATCH] XPRESS: fix empty-output EOD underflow, raise output cap to 32 MiB The mid-stream end-of-data-as-match(3,1) fallback indexed out[-1] when the output was still empty, pushing undefined into the result; guard it the same way the Go and C ports now do. Also raise MAX_DECOMPRESSED from 1 MiB to 32 MiB (WIM chunks can be up to 32 MiB; WOF is 1 MiB) and update the author tags to the real email. Found by the FuzzXpress target added to klauspost/compress. --- src/core/lib/XPRESS.mjs | 9 +++++---- src/core/operations/XPRESSDecompress.mjs | 2 +- src/core/operations/XPRESSHuffmanDecompress.mjs | 2 +- tests/operations/tests/XPRESS.mjs | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/lib/XPRESS.mjs b/src/core/lib/XPRESS.mjs index 9cfc748f..00a34a82 100644 --- a/src/core/lib/XPRESS.mjs +++ b/src/core/lib/XPRESS.mjs @@ -1,7 +1,7 @@ /** * XPRESS (MS-XCA) decompression. * - * @author MP Gowtham [mpgowtham@users.noreply.github.com] + * @author MP Gowtham [gowthamrockerzzz@gmail.com] * @copyright Crown Copyright 2026 * @license Apache-2.0 * @@ -15,8 +15,9 @@ import OperationError from "../errors/OperationError.mjs"; -/** Maximum output per call (Windows limits XPRESS blocks to 1 MiB). */ -const MAX_DECOMPRESSED = 1000000; +/** Maximum output per call (Windows sizes XPRESS blocks at up to + * 32 MiB for WIM chunks and up to 1 MiB for WOF chunks). */ +const MAX_DECOMPRESSED = 32 * 1024 * 1024; /** * Decompress an XPRESS plain-LZ77 stream. @@ -200,7 +201,7 @@ export function decompressHuffman(input, decompressedSize) { // End of data; mid-stream it decodes as a match(3, 1). if (out.length === decompressedSize) break; - if (decompressedSize - out.length < 3) + if (out.length === 0 || decompressedSize - out.length < 3) throw new OperationError("XPRESS: corrupt end-of-data marker"); const start = out.length - 1; for (let j = 0; j < 3; j++) diff --git a/src/core/operations/XPRESSDecompress.mjs b/src/core/operations/XPRESSDecompress.mjs index 6b94fc1a..a8167d37 100644 --- a/src/core/operations/XPRESSDecompress.mjs +++ b/src/core/operations/XPRESSDecompress.mjs @@ -1,5 +1,5 @@ /** - * @author MP Gowtham [mpgowtham@users.noreply.github.com] + * @author MP Gowtham [gowthamrockerzzz@gmail.com] * @copyright Crown Copyright 2026 * @license Apache-2.0 */ diff --git a/src/core/operations/XPRESSHuffmanDecompress.mjs b/src/core/operations/XPRESSHuffmanDecompress.mjs index 34b938e9..0b667dcb 100644 --- a/src/core/operations/XPRESSHuffmanDecompress.mjs +++ b/src/core/operations/XPRESSHuffmanDecompress.mjs @@ -1,5 +1,5 @@ /** - * @author MP Gowtham [mpgowtham@users.noreply.github.com] + * @author MP Gowtham [gowthamrockerzzz@gmail.com] * @copyright Crown Copyright 2026 * @license Apache-2.0 */ diff --git a/tests/operations/tests/XPRESS.mjs b/tests/operations/tests/XPRESS.mjs index 0df3b629..0da54e6d 100644 --- a/tests/operations/tests/XPRESS.mjs +++ b/tests/operations/tests/XPRESS.mjs @@ -1,7 +1,7 @@ /** * XPRESS tests. * - * @author MP Gowtham [mpgowtham@users.noreply.github.com] + * @author MP Gowtham [gowthamrockerzzz@gmail.com] * @copyright Crown Copyright 2026 * @license Apache-2.0 */