{"record":{"id":"7c3fa70e197cf3b9","repo":"vercel-labs/skills","slug":"invalid-zip-archive-label-exceeds-the-safe-int","errorCode":null,"errorMessage":"Invalid zip archive: ${label} exceeds the safe integer range","messagePattern":"Invalid zip archive: (.+?) exceeds the safe integer range","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/archive.ts","lineNumber":62,"sourceCode":"\nfunction findEndOfCentralDirectory(buffer: Buffer): number {\n  const minOffset = Math.max(0, buffer.length - ZIP_MAX_COMMENT_SIZE - ZIP_END_MIN_SIZE);\n  for (let offset = buffer.length - ZIP_END_MIN_SIZE; offset >= minOffset; offset--) {\n    if (buffer.readUInt32LE(offset) !== ZIP_END_OF_CENTRAL_DIRECTORY) continue;\n\n    const commentLength = buffer.readUInt16LE(offset + 20);\n    if (offset + ZIP_END_MIN_SIZE + commentLength === buffer.length) {\n      return offset;\n    }\n  }\n  return -1;\n}\n\nfunction readUInt64AsNumber(buffer: Buffer, offset: number, label: string): number {\n  ensureRange(buffer, offset, 8, label);\n  const value = buffer.readBigUInt64LE(offset);\n  if (value > BigInt(Number.MAX_SAFE_INTEGER)) {\n    throw new Error(`Invalid zip archive: ${label} exceeds the safe integer range`);\n  }\n  return Number(value);\n}\n\nfunction readCentralDirectory(\n  buffer: Buffer,\n  endOffset: number\n): {\n  entries: number;\n  offset: number;\n  size: number;\n  trailerOffset: number;\n} {\n  const diskNumber = buffer.readUInt16LE(endOffset + 4);\n  const centralDirectoryDisk = buffer.readUInt16LE(endOffset + 6);\n  const entriesOnDisk = buffer.readUInt16LE(endOffset + 8);\n  const totalEntries = buffer.readUInt16LE(endOffset + 10);\n  const size = buffer.readUInt32LE(endOffset + 12);","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/vercel-labs/skills/blob/435076e78988e1e6ec40d00b0b1d76bdbbc5419a/src/archive.ts#L44-L80","documentation":"The parser reads 64-bit zip fields with Buffer.readBigUInt64LE and converts them to JavaScript numbers. Zip64 fields can hold values up to 2^64-1, but a JS number only safely represents integers up to Number.MAX_SAFE_INTEGER (2^53-1). When a zip64 field (e.g. the zip64 end-of-central-directory offset, record size, or entry counts) exceeds that limit, this error is thrown rather than silently losing precision.","triggerScenarios":"Parsing a zip64 archive whose end-of-central-directory offset, record size, or total-entries field is a 64-bit value larger than 2^53-1; corrupt or fuzzed zip64 records containing huge values; buffers whose random bytes are misinterpreted as a zip64 locator/record because the real structure is missing.","commonSituations":"Fuzz tests feeding random bytes that land on the zip64 parsing path; a corrupted archive where a 64-bit field overflows; extremely large synthetic archives (exabytes) that no real tool produces — in practice this signals corruption, not a legitimate file.","solutions":["Treat the input as corrupt: re-obtain the archive and verify it with `unzip -t` or `zip -T`.","If you generate zips yourself, confirm your zip tool produces well-formed zip64 records (update Python zipfile / Info-ZIP / your zip library to the latest version).","Validate buffer size first: if the buffer is smaller than the claimed 64-bit offset/size, the archive is truncated or garbage — reject it before parsing.","Sanity-check that the buffer length itself is within a plausible range before calling the parser."],"exampleFix":"// before\nconst zip = readZipArchive(buffer); // throws 'exceeds the safe integer range' on fuzzed input\n\n// after\nif (buffer.length > Number.MAX_SAFE_INTEGER) {\n  throw new Error('Archive implausibly large');\n}\ntry {\n  const zip = readZipArchive(buffer);\n} catch (e) {\n  throw new Error(`Corrupt archive: ${(e as Error).message}`);\n}","handlingStrategy":"try-catch","validationCode":"if (buffer.length > Number.MAX_SAFE_INTEGER) {\n  throw new Error('Implausible archive size');\n}","typeGuard":"null","tryCatchPattern":"try {\n  const zip = readZipArchive(buffer);\n} catch (e) {\n  if ((e as Error).message.includes('safe integer range')) {\n    // corrupt zip64 field: quarantine the file\n  }\n  throw e;\n}","preventionTips":["Treat values > 2^53 in zip64 fields as corruption; real archives never reach exabyte sizes.","Validate buffer size plausibility before parsing.","Fuzz-test your pipeline to ensure corrupt inputs are rejected, not crashed on."],"tags":["zip","zip64","safe-integer","bigint","corrupt-file"],"backgroundTag":"corrupt-archive-file","analyzedSha":"435076e78988e1e6ec40d00b0b1d76bdbbc5419a","analyzedAt":"2026-08-28T17:47:53.369Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}