🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

@tokenizer/inflate

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tokenizer/inflate - npm Package Compare versions

Comparing version
0.2.4
to
0.2.5
+3
-1
lib/index.d.ts

@@ -15,3 +15,2 @@ import type { ITokenizer } from 'strtok3';

private syncBuffer;
private entries;
constructor(tokenizer: ITokenizer);

@@ -23,2 +22,5 @@ isZip(): Promise<boolean>;

unzip(fileCb: InflateFileFilter): Promise<void>;
private iterateOverCentralDirectory;
private inflate;
private readLocalFileHeader;
}

@@ -54,9 +54,14 @@ import { StringType, UINT32_LE } from 'token-types';

const eocdHeader = await this.tokenizer.readToken(EndOfCentralDirectoryRecordToken, offset);
const files = new Array(eocdHeader.nrOfEntriesOfSize);
const files = [];
this.tokenizer.setPosition(eocdHeader.offsetOfStartOfCd);
for (let n = 0; n < files.length; ++n) {
for (let n = 0; n < eocdHeader.nrOfEntriesOfSize; ++n) {
const entry = await this.tokenizer.readToken(FileHeader);
if (entry.signature !== Signature.CentralFileHeader) {
throw new Error('Expected Central-File-Header signature');
}
entry.filename = await this.tokenizer.readToken(new StringType(entry.filenameLength, 'utf-8'));
files[n] = entry;
debug(`Add central-directory file-entry: n=${n}/${files.length}: filename=${files[n].filename}`);
await this.tokenizer.ignore(entry.extraFieldLength);
await this.tokenizer.ignore(entry.fileCommentLength);
files.push(entry);
debug(`Add central-directory file-entry: n=${n + 1}/${files.length}: filename=${files[n].filename}`);
}

@@ -69,26 +74,13 @@ this.tokenizer.setPosition(pos);

async unzip(fileCb) {
let entry = 0;
const entries = await this.readCentralDirectory();
if (entries) {
// Use Central Directory to iterate over files
return this.iterateOverCentralDirectory(entries, fileCb);
}
// Scan Zip files for local-file-header
let stop = false;
do {
let zipHeader = undefined;
if (this.entries) {
// Use Central Director entry
zipHeader = this.entries[entry];
await this.tokenizer.ignore(LocalFileHeaderToken.len + zipHeader.filenameLength);
}
else {
const signature = await this.tokenizer.peekToken(UINT32_LE);
switch (signature) {
case Signature.LocalFileHeader:
zipHeader = await this.tokenizer.readToken(LocalFileHeaderToken);
zipHeader.filename = await this.tokenizer.readToken(new StringType(zipHeader.filenameLength, 'utf-8'));
break;
case Signature.CentralFileHeader:
break;
default:
throw new Error('Unexpected signature');
}
if (!zipHeader)
return;
}
const zipHeader = await this.readLocalFileHeader();
if (!zipHeader)
break;
const next = fileCb(zipHeader);

@@ -98,8 +90,2 @@ stop = !!next.stop;

await this.tokenizer.ignore(zipHeader.extraFieldLength);
if (entry === 0 && zipHeader.dataDescriptor) {
this.entries = await this.readCentralDirectory();
if (this.entries) {
zipHeader = this.entries[entry];
}
}
if (zipHeader.dataDescriptor && zipHeader.compressedSize === 0) {

@@ -125,25 +111,14 @@ const chunks = [];

debug(`Found data-descriptor-signature at pos=${this.tokenizer.position}`);
fileData = mergeArrays(chunks);
// Set position to next ZIP header
if (next.handler) {
await this.inflate(zipHeader, mergeArrays(chunks), next.handler);
}
}
if (next.handler) {
if (!fileData) {
else {
if (next.handler) {
debug(`Reading compressed-file-data: ${zipHeader.compressedSize} bytes`);
fileData = new Uint8Array(zipHeader.compressedSize);
await this.tokenizer.readBuffer(fileData);
await this.inflate(zipHeader, fileData, next.handler);
}
// Extract file data
if (!fileData)
throw new Error('fileData should be assigned');
if (zipHeader.compressedMethod === 0) {
await next.handler(fileData);
}
else {
debug(`Decompress filename=${zipHeader.filename}, compressed-size=${fileData.length}`);
const uncompressedData = decompressSync(fileData);
await next.handler(uncompressedData);
}
}
else {
if (!fileData) {
debug(`Ignoring compressed-file-data: ${zipHeader.compressedSize} bytes`);

@@ -155,2 +130,3 @@ await this.tokenizer.ignore(zipHeader.compressedSize);

if (zipHeader.dataDescriptor) {
// await this.tokenizer.ignore(DataDescriptor.len);
const dataDescriptor = await this.tokenizer.readToken(DataDescriptor);

@@ -161,6 +137,44 @@ if (dataDescriptor.signature !== 0x08074b50) {

}
++entry;
debug(`Completed file iteration at=${this.tokenizer.position}`);
} while (!stop && (!this.entries || entry < this.entries.length));
} while (!stop);
}
async iterateOverCentralDirectory(entries, fileCb) {
for (const fileHeader of entries) {
const next = fileCb(fileHeader);
if (next.handler) {
this.tokenizer.setPosition(fileHeader.relativeOffsetOfLocalHeader);
const zipHeader = await this.readLocalFileHeader();
if (zipHeader) {
await this.tokenizer.ignore(zipHeader.extraFieldLength);
const fileData = new Uint8Array(fileHeader.compressedSize);
await this.tokenizer.readBuffer(fileData);
await this.inflate(zipHeader, fileData, next.handler);
}
}
if (next.stop)
break;
}
}
inflate(zipHeader, fileData, cb) {
if (zipHeader.compressedMethod === 0) {
return cb(fileData);
}
debug(`Decompress filename=${zipHeader.filename}, compressed-size=${fileData.length}`);
const uncompressedData = decompressSync(fileData);
return cb(uncompressedData);
}
async readLocalFileHeader() {
const signature = await this.tokenizer.peekToken(UINT32_LE);
if (signature === Signature.LocalFileHeader) {
const header = await this.tokenizer.readToken(LocalFileHeaderToken);
header.filename = await this.tokenizer.readToken(new StringType(header.filenameLength, 'utf-8'));
return header;
}
if (signature === Signature.CentralFileHeader) {
return false;
}
if (signature === 0xE011CFD0) {
throw new Error('Encrypted ZIP');
}
throw new Error('Unexpected signature');
}
}

@@ -167,0 +181,0 @@ function indexOf(buffer, portion) {

{
"name": "@tokenizer/inflate",
"version": "0.2.4",
"version": "0.2.5",
"description": "Tokenized zip support",

@@ -34,3 +34,5 @@ "type": "module",

"devDependencies": {
"@aws-sdk/client-s3": "^3.705.0",
"@biomejs/biome": "=1.9.4",
"@tokenizer/s3": "^0.5.1",
"@types/chai": "^5.0.1",

@@ -37,0 +39,0 @@ "@types/debug": "^4",