/
andruxakonst
/
MCP-git-reader
Обзор
Документация
Войти
/
andruxakonst
/
MCP-git-reader
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/lib/zip.js
86 строк
3 KB
andruxakonst
Initial commit
26 июн 2026, 18:10
26 июн 2026, 18:10
b091eb8
Код
Авторство
О чём код?
const zlib = require('node:zlib'); const EOCD_SIGNATURE = 0x06054b50; const CENTRAL_DIRECTORY_SIGNATURE = 0x02014b50; const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50; function findEocd(buffer) { const minOffset = Math.max(0, buffer.length - 22 - 0xffff); for (let offset = buffer.length - 22; offset >= minOffset; offset -= 1) { if (buffer.readUInt32LE(offset) === EOCD_SIGNATURE) { return offset; } } throw new Error('Invalid ZIP archive: EOCD not found'); } function listZipEntries(buffer) { const eocdOffset = findEocd(buffer); const centralDirectoryOffset = buffer.readUInt32LE(eocdOffset + 16); const entryCount = buffer.readUInt16LE(eocdOffset + 10); const entries = []; let offset = centralDirectoryOffset; for (let index = 0; index < entryCount; index += 1) { const signature = buffer.readUInt32LE(offset); if (signature !== CENTRAL_DIRECTORY_SIGNATURE) { throw new Error('Invalid ZIP archive: central directory entry missing'); } const compressionMethod = buffer.readUInt16LE(offset + 10); const compressedSize = buffer.readUInt32LE(offset + 20); const uncompressedSize = buffer.readUInt32LE(offset + 24); const fileNameLength = buffer.readUInt16LE(offset + 28); const extraLength = buffer.readUInt16LE(offset + 30); const commentLength = buffer.readUInt16LE(offset + 32); const localHeaderOffset = buffer.readUInt32LE(offset + 42); const fileName = buffer.toString('utf8', offset + 46, offset + 46 + fileNameLength); entries.push({ path: fileName, size: uncompressedSize, compressedSize, compressionMethod, localHeaderOffset, }); offset += 46 + fileNameLength + extraLength + commentLength; } return entries; } function extractEntry(buffer, entry) { const localHeaderOffset = entry.localHeaderOffset; if (buffer.readUInt32LE(localHeaderOffset) !== LOCAL_FILE_HEADER_SIGNATURE) { throw new Error(`Invalid ZIP archive: missing local header for ${entry.path}`); } const fileNameLength = buffer.readUInt16LE(localHeaderOffset + 26); const extraLength = buffer.readUInt16LE(localHeaderOffset + 28); const dataOffset = localHeaderOffset + 30 + fileNameLength + extraLength; const compressed = buffer.subarray(dataOffset, dataOffset + entry.compressedSize); if (entry.compressionMethod === 0) { return compressed; } if (entry.compressionMethod === 8) { return zlib.inflateRawSync(compressed); } throw new Error(`Unsupported ZIP compression method: ${entry.compressionMethod}`); } function readZipEntry(buffer, path) { const entry = listZipEntries(buffer).find((candidate) => candidate.path === path); if (!entry) { throw new Error(`ZIP entry not found: ${path}`); } return extractEntry(buffer, entry); } module.exports = { listZipEntries, readZipEntry, };