{"record":{"id":"26824b09f51f3562","repo":"can1357/oh-my-pi","slug":"invalid-compress-z-output-limit","errorCode":null,"errorMessage":"Invalid compress (.Z) output limit","messagePattern":"Invalid compress \\(\\.Z\\) output limit","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/lzw.ts","lineNumber":98,"sourceCode":"\t\tif (!Number.isSafeInteger(needed) || needed > this.#limit) {\n\t\t\tthrow new ArchiveError(`Compress (.Z) output exceeds the ${this.#limit}-byte limit`);\n\t\t}\n\t\tif (needed <= this.#bytes.byteLength) {\n\t\t\treturn;\n\t\t}\n\t\tlet capacity = Math.max(needed, Math.min(this.#limit, Math.max(64, this.#bytes.byteLength * 2)));\n\t\tif (capacity > this.#limit) {\n\t\t\tcapacity = this.#limit;\n\t\t}\n\t\tconst grown = new Uint8Array(capacity);\n\t\tgrown.set(this.#bytes.subarray(0, this.#length));\n\t\tthis.#bytes = grown;\n\t}\n}\n\nfunction decode(bytes: Uint8Array, maxOutput: number): Uint8Array {\n\tif (!Number.isSafeInteger(maxOutput) || maxOutput < 0) {\n\t\tthrow new ArchiveError(\"Invalid compress (.Z) output limit\");\n\t}\n\tif (bytes.byteLength < 3) {\n\t\tthrow new ArchiveError(\"Truncated compress (.Z) header\");\n\t}\n\tif (bytes[0] !== 0x1f || bytes[1] !== 0x9d) {\n\t\tthrow new ArchiveError(\"Invalid compress (.Z) header\");\n\t}\n\n\tconst flags = bytes[2]!;\n\tif ((flags & 0x60) !== 0) {\n\t\tthrow new ArchiveError(\"Unsupported compress (.Z) header flags\");\n\t}\n\tconst maxBits = flags & 0x1f;\n\tif (maxBits < MIN_BITS || maxBits > MAX_BITS) {\n\t\tthrow new ArchiveError(`Invalid compress (.Z) maximum code width ${maxBits}`);\n\t}\n\tconst blockMode = (flags & 0x80) !== 0;\n\tconst dictionaryLimit = 2 ** maxBits;","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/lzw.ts#L80-L116","documentation":"decode() validates its maxOutput parameter before touching the stream: it must be a non-negative safe integer. This is an argument-validation error — the caller passed an invalid bound (negative, NaN, non-integer, or > Number.MAX_SAFE_INTEGER), not a data problem.","triggerScenarios":"Calling lzwDecompress(data, maxOutput) with maxOutput = -1, NaN, a float, undefined coerced oddly, or an unsafe integer computed from bad metadata.","commonSituations":"maxOutput read from a config file or env var without parsing validation; a NaN from a failed parseInt/Number conversion; arithmetic overflow producing Infinity before the call.","solutions":["Validate maxOutput at the call site: a non-negative safe integer before calling lzwDecompress.","Fix the source of the value — check parseInt/Number conversions for NaN and config parsing for missing fields.","Provide a sensible default (e.g. 256MB) when the configured limit is absent.","Guard with Number.isSafeInteger(maxOutput) && maxOutput >= 0 before calling."],"exampleFix":"// before: unparsed config\nconst max = Number(config.maxZOutput);\nlzwDecompress(bytes, max);\n// after\nconst max = Number(config.maxZOutput);\nif (!Number.isSafeInteger(max) || max < 0) throw new Error(\"Invalid maxZOutput config\");\nlzwDecompress(bytes, max);","handlingStrategy":"validation","validationCode":"function assertValidMaxOutput(maxOutput: number): void {\n  if (!Number.isSafeInteger(maxOutput) || maxOutput < 0) {\n    throw new Error(`maxOutput must be a non-negative safe integer, got ${maxOutput}`);\n  }\n}","typeGuard":"function isValidMaxOutput(v: unknown): v is number {\n  return typeof v === \"number\" && Number.isSafeInteger(v) && v >= 0;\n}","tryCatchPattern":"try {\n  return lzwDecompress(bytes, maxOutput);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"output limit\")) {\n    throw new Error(`Bad maxOutput argument: ${maxOutput}`, { cause: err });\n  }\n  throw err;\n}","preventionTips":["Check Number.isSafeInteger(v) && v >= 0 on any configured limit before calling.","Guard parseInt/Number conversions against NaN at the config boundary.","Centralize limit parsing in one validated helper.","Provide safe defaults when config values are missing."],"tags":["archive","lzw","argument-validation"],"backgroundTag":"invalid-argument","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}