{"record":{"id":"1608c2b419876d0b","repo":"can1357/oh-my-pi","slug":"invalid-zip-archive-size-mismatch-for-memberpa-1608c2","errorCode":null,"errorMessage":"Invalid ZIP archive: size mismatch for '${memberPath}' (expected ${size}, got ${decoded.byteLength})","messagePattern":"Invalid ZIP archive: size mismatch for '(.+?)' \\(expected (.+?), got (.+?)\\)","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/zip.ts","lineNumber":430,"sourceCode":"\t\t\tif (readUInt16LE(header, 8) !== this.#method) {\n\t\t\t\tthrow new ArchiveError(\n\t\t\t\t\t`Invalid ZIP archive: local and central compression methods disagree for '${memberPath}'`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst dataStart = this.#localHeaderOffset + 30 + readUInt16LE(header, 26) + readUInt16LE(header, 28);\n\t\t\tconst dataEnd = checkedEnd(dataStart, this.#compressedSize, this.#source.size, `data for '${memberPath}'`);\n\t\t\tif (this.#method === 0 && this.#compressedSize !== size) {\n\t\t\t\tthrow new ArchiveError(\n\t\t\t\t\t`Invalid ZIP archive: size mismatch for '${memberPath}' (expected ${size}, got ${this.#compressedSize})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst compressed = await this.#source.read(dataStart, dataEnd);\n\t\t\tif (compressed.byteLength !== this.#compressedSize) {\n\t\t\t\tthrow new ArchiveError(`Invalid ZIP archive: truncated data for '${memberPath}'`);\n\t\t\t}\n\t\t\tconst decoded = await decodeMember(compressed, this.#method, size, memberPath);\n\t\t\tif (decoded.byteLength !== size) {\n\t\t\t\tthrow new ArchiveError(\n\t\t\t\t\t`Invalid ZIP archive: size mismatch for '${memberPath}' (expected ${size}, got ${decoded.byteLength})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst actualCrc = crc32(decoded);\n\t\t\tif (actualCrc !== this.#crc) {\n\t\t\t\tthrow new ArchiveError(`Invalid ZIP archive: CRC mismatch for '${memberPath}'`);\n\t\t\t}\n\t\t\treturn decoded;\n\t\t} catch (error) {\n\t\t\tthrow archiveError(error, `Failed to read ZIP member '${memberPath}'`);\n\t\t}\n\t}\n}\n\nfunction parseCentralDirectory(\n\tsource: ByteSource,\n\tdirectory: Uint8Array,\n\tinfo: CentralDirectoryInfo,","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/zip.ts#L412-L448","documentation":"Thrown when a member decompresses successfully but its decoded byte length does not equal the uncompressed size declared in the central directory. The codec output and the metadata disagree, so the result cannot be trusted. ArchiveError reporting expected vs decoded byte counts.","triggerScenarios":"ZipMemberSource read where decodeMember(...) yields decoded.byteLength !== size — corrupted compressed stream producing a different-length payload, inconsistent central-directory size fields, or data altered after compression.","commonSituations":"Bit-flipped or truncated-then-padded deflate streams; zips assembled from mismatched parts; archives produced by buggy compressors writing wrong uncompressed-size fields; malicious zip bombs/malformed entries.","solutions":["Test the archive with `unzip -t` — corruption will be reported; re-obtain a clean copy","Re-extract from the original source and re-zip","If you produce the archive, fix the writer to set the true uncompressed size in the central directory","Treat as untrusted input: reject the file rather than attempting salvage"],"exampleFix":"// before: trusting a repaired-by-concatenation zip\nconst data = await readZipMember(zip, 'a.bin'); // throws 3716\n// after: verify integrity first\n// $ `unzip -t suspect.zip` && unzip -o suspect.zip 'a.bin' -d out/\nconst data = await Bun.file('out/a.bin').bytes();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const data = await zip.read(member);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('size mismatch') && err.message.includes('got')) {\n    throw new Error('decoded payload does not match declared size — archive untrusted/corrupt');\n  }\n  throw err;\n}","preventionTips":["Integrity-check third-party archives (`unzip -t`) before extraction","Reject mismatched-size archives rather than attempting salvage","Ensure custom writers emit accurate uncompressed sizes in the central directory","Treat size-mismatch zips from unknown sources as potentially malicious"],"tags":["zip","size-mismatch","corrupt-archive","decompression"],"backgroundTag":"zip-size-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}