neozipkit 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +410 -186
- package/contracts/ABI.txt +889 -0
- package/contracts/Bytecode.txt +1 -0
- package/contracts/COMPILATION_NOTES.md +59 -0
- package/contracts/QUICK_DEPLOY.md +286 -0
- package/contracts/README.md +235 -131
- package/contracts/VERIFICATION.md +308 -0
- package/contracts/deploy-interactive.js +448 -0
- package/contracts/deployment-arbitrum-sepolia.json +12 -0
- package/contracts/deployment-arbitrum.json +12 -0
- package/contracts/deployment-eth-sepolia.json +12 -0
- package/contracts/hardhat.config.js +114 -0
- package/contracts/package.json +20 -0
- package/contracts/scripts/compile-and-extract.js +119 -0
- package/contracts/scripts/verify-contract.js +223 -0
- package/contracts/src/{NZIP-NFT-Private.sol → NZIP-NFT-v2.0.sol} +66 -151
- package/contracts/src/NZIP-NFT.sol +9 -15
- package/dist/blockchain/browser/TokenVerifierBrowser.d.ts +67 -0
- package/dist/blockchain/browser/TokenVerifierBrowser.d.ts.map +1 -0
- package/dist/blockchain/browser/TokenVerifierBrowser.js +313 -0
- package/dist/blockchain/browser/TokenVerifierBrowser.js.map +1 -0
- package/dist/blockchain/browser/WalletManagerBrowser.d.ts +98 -0
- package/dist/blockchain/browser/WalletManagerBrowser.d.ts.map +1 -0
- package/dist/blockchain/browser/WalletManagerBrowser.js +434 -0
- package/dist/blockchain/browser/WalletManagerBrowser.js.map +1 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts +58 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts.map +1 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.js +317 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.js.map +1 -0
- package/dist/blockchain/browser/index.d.ts +11 -0
- package/dist/blockchain/browser/index.d.ts.map +1 -0
- package/dist/blockchain/browser/index.js +16 -0
- package/dist/blockchain/browser/index.js.map +1 -0
- package/dist/blockchain/core/WalletManager.d.ts +124 -0
- package/dist/blockchain/core/WalletManager.d.ts.map +1 -0
- package/dist/blockchain/{ZipKitWallet.js → core/WalletManager.js} +157 -177
- package/dist/blockchain/core/WalletManager.js.map +1 -0
- package/dist/blockchain/{ZipKitMinter.d.ts → core/ZipkitMinter.d.ts} +46 -11
- package/dist/blockchain/core/ZipkitMinter.d.ts.map +1 -0
- package/dist/blockchain/core/ZipkitMinter.js +548 -0
- package/dist/blockchain/core/ZipkitMinter.js.map +1 -0
- package/dist/blockchain/{ZipKitOTS.d.ts → core/ZipkitOTS.d.ts} +6 -15
- package/dist/blockchain/core/ZipkitOTS.d.ts.map +1 -0
- package/dist/blockchain/{ZipKitOTS.js → core/ZipkitOTS.js} +26 -84
- package/dist/blockchain/core/ZipkitOTS.js.map +1 -0
- package/dist/blockchain/core/ZipkitVerifier.d.ts +177 -0
- package/dist/blockchain/core/ZipkitVerifier.d.ts.map +1 -0
- package/dist/blockchain/core/ZipkitVerifier.js +632 -0
- package/dist/blockchain/core/ZipkitVerifier.js.map +1 -0
- package/dist/blockchain/core/contracts.d.ts +83 -0
- package/dist/blockchain/core/contracts.d.ts.map +1 -0
- package/dist/blockchain/core/contracts.js +341 -0
- package/dist/blockchain/core/contracts.js.map +1 -0
- package/dist/blockchain/core/index.d.ts +12 -0
- package/dist/blockchain/core/index.d.ts.map +1 -0
- package/dist/blockchain/core/index.js +59 -0
- package/dist/blockchain/core/index.js.map +1 -0
- package/dist/blockchain/index.d.ts +11 -7
- package/dist/blockchain/index.d.ts.map +1 -0
- package/dist/blockchain/index.js +18 -34
- package/dist/blockchain/index.js.map +1 -0
- package/dist/blockchain/node/WalletManagerNode.d.ts +47 -0
- package/dist/blockchain/node/WalletManagerNode.d.ts.map +1 -0
- package/dist/blockchain/node/WalletManagerNode.js +203 -0
- package/dist/blockchain/node/WalletManagerNode.js.map +1 -0
- package/dist/blockchain/node/index.d.ts +12 -0
- package/dist/blockchain/node/index.d.ts.map +1 -0
- package/dist/blockchain/node/index.js +24 -0
- package/dist/blockchain/node/index.js.map +1 -0
- package/dist/browser/ZipkitBrowser.d.ts +27 -0
- package/dist/browser/ZipkitBrowser.d.ts.map +1 -0
- package/dist/browser/{ZipKitBrowser.js → ZipkitBrowser.js} +96 -43
- package/dist/browser/ZipkitBrowser.js.map +1 -0
- package/dist/browser/index.d.ts +12 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +42 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser-esm/index.d.ts +12 -0
- package/dist/browser-esm/index.js +59559 -0
- package/dist/browser-esm/index.js.map +7 -0
- package/dist/browser-umd/index.d.ts +12 -0
- package/dist/browser-umd/index.js +59576 -0
- package/dist/browser-umd/index.js.map +7 -0
- package/dist/browser-umd/index.min.js +63 -0
- package/dist/browser.d.ts +8 -14
- package/dist/browser.js +13 -28
- package/dist/core/ZipCompress.d.ts +99 -0
- package/dist/core/ZipCompress.d.ts.map +1 -0
- package/dist/core/ZipCompress.js +309 -0
- package/dist/core/ZipCompress.js.map +1 -0
- package/dist/core/ZipDecompress.d.ts +58 -0
- package/dist/core/ZipDecompress.d.ts.map +1 -0
- package/dist/core/ZipDecompress.js +172 -0
- package/dist/core/ZipDecompress.js.map +1 -0
- package/dist/{shared → core}/ZipEntry.d.ts +8 -1
- package/dist/core/ZipEntry.d.ts.map +1 -0
- package/dist/{shared → core}/ZipEntry.js +225 -82
- package/dist/core/ZipEntry.js.map +1 -0
- package/dist/core/Zipkit.d.ts +315 -0
- package/dist/core/Zipkit.d.ts.map +1 -0
- package/dist/core/Zipkit.js +647 -0
- package/dist/core/Zipkit.js.map +1 -0
- package/dist/core/components/HashCalculator.d.ts +138 -0
- package/dist/core/components/HashCalculator.d.ts.map +1 -0
- package/dist/core/components/HashCalculator.js +360 -0
- package/dist/core/components/HashCalculator.js.map +1 -0
- package/dist/core/components/Logger.d.ts +73 -0
- package/dist/core/components/Logger.d.ts.map +1 -0
- package/dist/core/components/Logger.js +156 -0
- package/dist/core/components/Logger.js.map +1 -0
- package/dist/core/components/ProgressTracker.d.ts +43 -0
- package/dist/core/components/ProgressTracker.d.ts.map +1 -0
- package/dist/core/components/ProgressTracker.js +112 -0
- package/dist/core/components/ProgressTracker.js.map +1 -0
- package/dist/{shared → core}/components/Support.d.ts +1 -0
- package/dist/core/components/Support.d.ts.map +1 -0
- package/dist/{shared → core}/components/Support.js +1 -0
- package/dist/core/components/Support.js.map +1 -0
- package/dist/{shared → core}/components/Util.d.ts +7 -2
- package/dist/core/components/Util.d.ts.map +1 -0
- package/dist/{shared → core}/components/Util.js +14 -34
- package/dist/core/components/Util.js.map +1 -0
- package/dist/{shared → core}/constants/Errors.d.ts +1 -2
- package/dist/core/constants/Errors.d.ts.map +1 -0
- package/dist/{shared → core}/constants/Errors.js +1 -3
- package/dist/core/constants/Errors.js.map +1 -0
- package/dist/{shared → core}/constants/Headers.d.ts +3 -0
- package/dist/core/constants/Headers.d.ts.map +1 -0
- package/dist/{shared → core}/constants/Headers.js +20 -17
- package/dist/core/constants/Headers.js.map +1 -0
- package/dist/core/encryption/Manager.d.ts +58 -0
- package/dist/core/encryption/Manager.d.ts.map +1 -0
- package/dist/core/encryption/Manager.js +121 -0
- package/dist/core/encryption/Manager.js.map +1 -0
- package/dist/core/encryption/ZipCrypto.d.ts +172 -0
- package/dist/core/encryption/ZipCrypto.d.ts.map +1 -0
- package/dist/core/encryption/ZipCrypto.js +554 -0
- package/dist/core/encryption/ZipCrypto.js.map +1 -0
- package/dist/core/encryption/index.d.ts +9 -0
- package/dist/core/encryption/index.d.ts.map +1 -0
- package/dist/core/encryption/index.js +17 -0
- package/dist/core/encryption/index.js.map +1 -0
- package/dist/core/encryption/types.d.ts +29 -0
- package/dist/core/encryption/types.d.ts.map +1 -0
- package/dist/core/encryption/types.js +12 -0
- package/dist/core/encryption/types.js.map +1 -0
- package/dist/core/index.d.ts +24 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +57 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/version.d.ts +5 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +31 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +8 -18
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -35
- package/dist/index.js.map +1 -0
- package/dist/node/ZipCompressNode.d.ts +123 -0
- package/dist/node/ZipCompressNode.d.ts.map +1 -0
- package/dist/node/ZipCompressNode.js +576 -0
- package/dist/node/ZipCompressNode.js.map +1 -0
- package/dist/node/ZipDecompressNode.d.ts +120 -0
- package/dist/node/ZipDecompressNode.d.ts.map +1 -0
- package/dist/node/ZipDecompressNode.js +461 -0
- package/dist/node/ZipDecompressNode.js.map +1 -0
- package/dist/node/ZipkitNode.d.ts +406 -0
- package/dist/node/ZipkitNode.d.ts.map +1 -0
- package/dist/node/ZipkitNode.js +1305 -0
- package/dist/node/ZipkitNode.js.map +1 -0
- package/dist/node/index.d.ts +26 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +65 -0
- package/dist/node/index.js.map +1 -0
- package/dist/types/index.d.ts +59 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +36 -1
- package/dist/types/index.js.map +1 -0
- package/examples/README.md +269 -0
- package/examples/blockchain-tokenize.ts +354 -0
- package/examples/create-zip.ts +172 -0
- package/examples/extract-zip.ts +158 -0
- package/examples/list-zip.ts +161 -0
- package/examples/test-files/data.json +116 -0
- package/examples/test-files/document.md +80 -0
- package/examples/test-files/document.txt +2 -0
- package/examples/test-files/file1.txt +48 -0
- package/examples/test-files/file2.txt +80 -0
- package/examples/tsconfig.json +44 -0
- package/examples/unzip-token.ts +491 -0
- package/examples/verify-tokenized-zip.ts +305 -0
- package/examples/zip-token.ts +604 -0
- package/package.json +108 -24
- package/src/blockchain/README.md +59 -66
- package/src/{browser/TokenVerifierBrowser.ts-remove → blockchain/browser/TokenVerifierBrowser.ts} +125 -79
- package/src/blockchain/browser/WalletManagerBrowser.ts +486 -0
- package/src/blockchain/browser/ZipkitMinterBrowser.ts +400 -0
- package/src/blockchain/browser/index.ts +13 -0
- package/src/blockchain/{ZipKitWallet.ts → core/WalletManager.ts} +241 -143
- package/src/blockchain/core/ZipkitMinter.ts +716 -0
- package/src/blockchain/{ZipKitOTS.ts → core/ZipkitOTS.ts} +28 -62
- package/src/blockchain/core/ZipkitVerifier.ts +853 -0
- package/src/blockchain/core/contracts.ts +370 -0
- package/src/blockchain/core/index.ts +71 -0
- package/src/blockchain/index.ts +21 -55
- package/src/blockchain/node/WalletManagerNode.ts +171 -0
- package/src/blockchain/node/index.ts +40 -0
- package/src/browser/{ZipKitBrowser.ts → ZipkitBrowser.ts} +104 -41
- package/src/browser/index.esm.ts +37 -0
- package/src/browser/index.ts +25 -0
- package/src/core/ZipCompress.ts +398 -0
- package/src/core/ZipDecompress.ts +212 -0
- package/src/{shared → core}/ZipEntry.ts +240 -90
- package/src/core/Zipkit.ts +794 -0
- package/src/core/components/HashCalculator.ts +384 -0
- package/src/core/components/Logger.ts +180 -0
- package/src/core/components/ProgressTracker.ts +134 -0
- package/src/{shared → core}/components/Util.ts +12 -34
- package/src/{shared → core}/constants/Errors.ts +0 -4
- package/src/{shared → core}/constants/Headers.ts +19 -17
- package/src/core/encryption/Manager.ts +137 -0
- package/src/core/encryption/ZipCrypto.ts +650 -0
- package/src/core/encryption/index.ts +15 -0
- package/src/core/encryption/types.ts +33 -0
- package/src/core/index.ts +34 -0
- package/src/core/version.ts +33 -0
- package/src/index.ts +54 -25
- package/src/node/ZipCompressNode.ts +632 -0
- package/src/node/ZipDecompressNode.ts +508 -0
- package/src/node/ZipkitNode.ts +1559 -0
- package/src/node/index.ts +69 -0
- package/src/types/index.ts +131 -1
- package/src/types/modules.d.ts +1 -11
- package/src/types/opentimestamps.d.ts +1 -23
- package/contracts/INTEGRATION.md +0 -338
- package/contracts/NETWORKS.md +0 -156
- package/contracts/NZIP-NFT-bytecode.txt +0 -1
- package/contracts/constants.ts +0 -952
- package/contracts/deploy-bytecode.mjs +0 -94
- package/dist/blockchain/CertificateToken.d.ts +0 -48
- package/dist/blockchain/CertificateToken.js +0 -386
- package/dist/blockchain/ZipKitMinter.js +0 -347
- package/dist/blockchain/ZipKitNFT.d.ts +0 -3
- package/dist/blockchain/ZipKitNFT.js +0 -7
- package/dist/blockchain/ZipKitVerifier.d.ts +0 -69
- package/dist/blockchain/ZipKitVerifier.js +0 -289
- package/dist/blockchain/ZipKitWallet.d.ts +0 -69
- package/dist/blockchain/contracts.d.ts +0 -14
- package/dist/blockchain/contracts.js +0 -77
- package/dist/blockchain/types.d.ts +0 -47
- package/dist/blockchain/types.js +0 -30
- package/dist/browser/ZipKitBrowser.d.ts +0 -18
- package/dist/browser/ZipKitStampBrowser.d.ts +0 -2
- package/dist/browser/ZipKitStampBrowser.js +0 -12
- package/dist/browser-index.d.ts +0 -18
- package/dist/browser-index.js +0 -57
- package/dist/server/ZipKitServer.d.ts +0 -74
- package/dist/server/ZipKitServer.js +0 -310
- package/dist/shared/ZipKit.d.ts +0 -243
- package/dist/shared/ZipKit.js +0 -772
- package/dist/shared/components/CertificateOTS.d.ts +0 -15
- package/dist/shared/components/CertificateOTS.js +0 -116
- package/dist/shared/components/FileSys.d.ts +0 -2
- package/dist/shared/components/FileSys.js +0 -113
- package/dist/shared/components/HashAccumulator.d.ts +0 -55
- package/dist/shared/components/HashAccumulator.js +0 -100
- package/dist/shared/components/ZipCrypto.d.ts +0 -3
- package/dist/shared/components/ZipCrypto.js +0 -78
- package/dist/shared/components/merkleTree.d.ts +0 -66
- package/dist/shared/components/merkleTree.js +0 -136
- package/dist/shared/types/index.d.ts +0 -21
- package/dist/shared/types/index.js +0 -3
- package/dist/shared/types.d.ts +0 -33
- package/dist/shared/types.js +0 -8
- package/dist/shared/version.d.ts +0 -2
- package/dist/shared/version.js +0 -6
- package/src/blockchain/CertificateToken.ts +0 -444
- package/src/blockchain/ZipKitMinter.ts +0 -470
- package/src/blockchain/ZipKitNFT.ts +0 -12
- package/src/blockchain/ZipKitVerifier.ts +0 -382
- package/src/blockchain/contracts.ts +0 -88
- package/src/blockchain/types.ts +0 -91
- package/src/browser/CertificateGeneratorBrowser.ts-remove +0 -498
- package/src/browser/ZipKitStampBrowser.ts +0 -9
- package/src/browser-index.ts +0 -36
- package/src/server/README.md +0 -25
- package/src/server/ZipKitServer.ts +0 -305
- package/src/shared/ZipKit.ts +0 -881
- package/src/shared/components/CertificateOTS.ts +0 -132
- package/src/shared/components/FileSys.ts +0 -87
- package/src/shared/components/HashAccumulator.ts +0 -113
- package/src/shared/components/ZipCrypto.ts +0 -91
- package/src/shared/components/merkleTree.ts +0 -162
- package/src/shared/types/index.ts +0 -25
- package/src/shared/types/modules.d.ts +0 -22
- package/src/shared/types/opentimestamps.d.ts +0 -23
- package/src/shared/types.d.ts +0 -8
- package/src/shared/types.ts +0 -43
- package/src/shared/version.ts +0 -3
- /package/src/{shared → core}/components/Support.ts +0 -0
|
@@ -13,12 +13,10 @@ import {
|
|
|
13
13
|
FILE_SYSTEM,
|
|
14
14
|
HDR_ID,
|
|
15
15
|
DOS_FILE_ATTR,
|
|
16
|
-
TIMESTAMP_SUBMITTED,
|
|
17
16
|
} from './constants/Headers';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import
|
|
21
|
-
import { crc32 } from './components/Util';
|
|
17
|
+
import { ZipFileEntry, FileData } from '../types';
|
|
18
|
+
import { Logger } from './components/Logger';
|
|
19
|
+
import { crc32 } from './encryption/ZipCrypto';
|
|
22
20
|
|
|
23
21
|
const VER_ENCODING = 30;
|
|
24
22
|
const VER_EXTRACT = 10; // Version needed to extract (1.0)
|
|
@@ -27,7 +25,7 @@ const VER_EXTRACT = 10; // Version needed to extract
|
|
|
27
25
|
* Class representing a single entry (file or directory) within a ZIP archive
|
|
28
26
|
*/
|
|
29
27
|
export default class ZipEntry implements ZipFileEntry {
|
|
30
|
-
debug =
|
|
28
|
+
debug = true;
|
|
31
29
|
|
|
32
30
|
verMadeBy: number = 0; // Read Version Made By
|
|
33
31
|
verExtract: number = 0; // Read Version Needed to Extract
|
|
@@ -67,6 +65,15 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
67
65
|
uid: number | null = null; // User ID
|
|
68
66
|
gid: number | null = null; // Group ID
|
|
69
67
|
sha256: string | null = null; // SHA-256 hash of the file
|
|
68
|
+
|
|
69
|
+
// Symbolic link data
|
|
70
|
+
isSymlink: boolean = false; // Entry is a symbolic link
|
|
71
|
+
linkTarget: string | null = null; // Target path for symbolic links
|
|
72
|
+
|
|
73
|
+
// Hard link data
|
|
74
|
+
isHardLink: boolean = false; // Entry is a hard link
|
|
75
|
+
originalEntry: string | null = null; // Original entry name for hard links
|
|
76
|
+
inode: number | null = null; // Inode number for hard links
|
|
70
77
|
|
|
71
78
|
fileData?: FileData;
|
|
72
79
|
|
|
@@ -186,7 +193,7 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
186
193
|
const unicodeName = _data.subarray(5).toString('utf8');
|
|
187
194
|
this.filename = unicodeName;
|
|
188
195
|
if (this.debug) {
|
|
189
|
-
|
|
196
|
+
Logger.log(`Using Unicode Path: ${this.filename}`);
|
|
190
197
|
}
|
|
191
198
|
}
|
|
192
199
|
}
|
|
@@ -232,6 +239,27 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
232
239
|
}
|
|
233
240
|
}
|
|
234
241
|
}
|
|
242
|
+
} else if (_id === HDR_ID.SYMLINK) {
|
|
243
|
+
// Extract symbolic link information
|
|
244
|
+
if (_len >= 3) { // Version + Target Length + Target
|
|
245
|
+
const version = _data.readUInt8(0);
|
|
246
|
+
const targetLength = _data.readUInt16LE(1);
|
|
247
|
+
if (targetLength > 0 && _len >= 3 + targetLength) {
|
|
248
|
+
this.isSymlink = true;
|
|
249
|
+
this.linkTarget = _data.subarray(3, 3 + targetLength).toString('utf8');
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
} else if (_id === HDR_ID.HARDLINK) {
|
|
253
|
+
// Extract hard link information
|
|
254
|
+
if (_len >= 11) { // Version + Inode + Original Length + Original
|
|
255
|
+
const version = _data.readUInt8(0);
|
|
256
|
+
this.inode = _data.readUInt32LE(1);
|
|
257
|
+
const originalLength = _data.readUInt16LE(5);
|
|
258
|
+
if (originalLength > 0 && _len >= 7 + originalLength) {
|
|
259
|
+
this.isHardLink = true;
|
|
260
|
+
this.originalEntry = _data.subarray(7, 7 + originalLength).toString('utf8');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
235
263
|
}
|
|
236
264
|
// Skip Unicode Path here as we already processed it
|
|
237
265
|
i += 4 + _len;
|
|
@@ -241,7 +269,7 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
241
269
|
// File Comment Length - 2 bytes
|
|
242
270
|
let comLen = data.readUInt16LE(CENTRAL_DIR.COMMENT_LEN);
|
|
243
271
|
if (comLen > 0)
|
|
244
|
-
this.comment = data.toString('utf8', CENTRAL_DIR.SIZE + fnameLen
|
|
272
|
+
this.comment = data.toString('utf8', CENTRAL_DIR.SIZE + fnameLen, CENTRAL_DIR.SIZE + fnameLen + comLen);
|
|
245
273
|
|
|
246
274
|
if (this.debug)
|
|
247
275
|
this.showVerboseInfo();
|
|
@@ -294,7 +322,6 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
294
322
|
* @returns Buffer containing the local header data
|
|
295
323
|
*/
|
|
296
324
|
createLocalHdr(): Buffer {
|
|
297
|
-
const commentLen = this.comment?.length ?? 0;
|
|
298
325
|
let extraFieldLen = 0;
|
|
299
326
|
|
|
300
327
|
// Only create Unicode Path field if needed
|
|
@@ -306,7 +333,7 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
306
333
|
extraFieldLen = 5 + unicodeNameLen + 4;
|
|
307
334
|
}
|
|
308
335
|
|
|
309
|
-
const data = Buffer.alloc(LOCAL_HDR.SIZE + this.filename.length +
|
|
336
|
+
const data = Buffer.alloc(LOCAL_HDR.SIZE + this.filename.length + extraFieldLen);
|
|
310
337
|
|
|
311
338
|
// "PK\003\004"
|
|
312
339
|
data.writeUInt32LE(LOCAL_HDR.SIGNATURE, 0);
|
|
@@ -342,11 +369,8 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
342
369
|
extraOffset = this.addUnicodePathField(data, extraOffset);
|
|
343
370
|
}
|
|
344
371
|
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
const commentBuf = Buffer.from(this.comment, 'utf8');
|
|
348
|
-
commentBuf.copy(data, extraOffset);
|
|
349
|
-
}
|
|
372
|
+
// File comments are NOT stored in local headers (ZIP specification)
|
|
373
|
+
// They are only stored in the central directory
|
|
350
374
|
|
|
351
375
|
return data;
|
|
352
376
|
}
|
|
@@ -357,12 +381,20 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
357
381
|
*/
|
|
358
382
|
centralDirEntry(): Buffer {
|
|
359
383
|
// Calculate the length of the extra fields
|
|
360
|
-
const commentLen = this.comment
|
|
384
|
+
const commentLen = this.comment ? Buffer.from(this.comment, 'utf8').length : 0;
|
|
361
385
|
const utfLen = this.universalTime ? 9 : 0; // 4 bytes header + 5 bytes data
|
|
362
386
|
const uidgidLen = this.uid && this.gid ? 11 + 4 : 0; // 1 byte version + 1 byte size + 4 bytes data + 1 byte size + 4 bytes data
|
|
363
387
|
const sha256Buf = this.sha256 ? Buffer.from(this.sha256, 'hex') : null;
|
|
364
388
|
const sha256Len = sha256Buf ? (sha256Buf.length + 4) : 0;
|
|
365
389
|
|
|
390
|
+
// Calculate symbolic link extra field length
|
|
391
|
+
const symlinkLen = this.isSymlink && this.linkTarget ?
|
|
392
|
+
(4 + 1 + 2 + Buffer.byteLength(this.linkTarget, 'utf8')) : 0; // 4 bytes header + 1 byte version + 2 bytes length + target
|
|
393
|
+
|
|
394
|
+
// Calculate hard link extra field length
|
|
395
|
+
const hardlinkLen = this.isHardLink && this.originalEntry && this.inode !== null ?
|
|
396
|
+
(4 + 1 + 4 + 2 + Buffer.byteLength(this.originalEntry, 'utf8')) : 0; // 4 bytes header + 1 byte version + 4 bytes inode + 2 bytes length + original
|
|
397
|
+
|
|
366
398
|
// Only add Unicode Path field if needed
|
|
367
399
|
const needsUnicode = this.needsUnicodeHandling();
|
|
368
400
|
let unicodePathLen = 0;
|
|
@@ -373,10 +405,14 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
373
405
|
unicodePathLen = 5 + unicodeNameLen + 4;
|
|
374
406
|
}
|
|
375
407
|
|
|
376
|
-
const extraLen = utfLen + sha256Len + uidgidLen + (needsUnicode ? unicodePathLen : 0);
|
|
408
|
+
const extraLen = utfLen + sha256Len + uidgidLen + symlinkLen + hardlinkLen + (needsUnicode ? unicodePathLen : 0);
|
|
377
409
|
|
|
410
|
+
// Calculate actual filename length (ASCII conversion may change length)
|
|
411
|
+
const asciiName = this.filename.replace(/[^\x00-\x7E]/g, '?');
|
|
412
|
+
const fnameLen = asciiName.length;
|
|
413
|
+
|
|
378
414
|
// Central directory header size (46 Bytes + filename + comment + extra fields)
|
|
379
|
-
const data = Buffer.alloc(CENTRAL_DIR.SIZE +
|
|
415
|
+
const data = Buffer.alloc(CENTRAL_DIR.SIZE + fnameLen + commentLen + extraLen);
|
|
380
416
|
|
|
381
417
|
// "PK\001\002"
|
|
382
418
|
data.writeUInt32LE(CENTRAL_DIR.SIGNATURE, 0);
|
|
@@ -413,52 +449,82 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
413
449
|
|
|
414
450
|
// Write filename - use ASCII filename (replacing non-ASCII with ?)
|
|
415
451
|
// This ensures compatibility with older ZIP readers
|
|
416
|
-
const asciiName = this.filename.replace(/[^\x00-\x7E]/g, '?');
|
|
417
452
|
const fnameBuf = Buffer.from(asciiName);
|
|
418
453
|
fnameBuf.copy(data, CENTRAL_DIR.SIZE);
|
|
419
454
|
|
|
455
|
+
// Add file comment immediately after filename (InfoZip format)
|
|
456
|
+
let currentOffset = CENTRAL_DIR.SIZE + fnameLen;
|
|
420
457
|
if (commentLen > 0 && this.comment) {
|
|
421
458
|
const commentBuf = Buffer.from(this.comment, 'utf8');
|
|
422
|
-
commentBuf.copy(data,
|
|
459
|
+
commentBuf.copy(data, currentOffset);
|
|
460
|
+
currentOffset += commentLen;
|
|
423
461
|
}
|
|
424
462
|
|
|
425
|
-
// Add Extra Field data
|
|
426
|
-
let extraOffset =
|
|
463
|
+
// Add Extra Field data after file comment
|
|
464
|
+
let extraOffset = currentOffset;
|
|
427
465
|
|
|
428
466
|
// Add Universal Time field
|
|
429
467
|
if (this.universalTime) {
|
|
430
468
|
data.writeUInt16LE(HDR_ID.UNV_TIME, extraOffset); // 0x5455
|
|
431
469
|
data.writeUInt16LE(5, extraOffset + 2); // Length of data (flags + time)
|
|
432
|
-
data.writeUInt8(
|
|
433
|
-
data.writeUInt32LE(
|
|
434
|
-
extraOffset += 9;
|
|
470
|
+
data.writeUInt8(1, extraOffset + 4); // Flags: modification time present
|
|
471
|
+
data.writeUInt32LE(Math.floor(Date.now() / 1000), extraOffset + 5); // Unix timestamp
|
|
472
|
+
extraOffset += 9;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Add SHA-256 field
|
|
476
|
+
if (sha256Buf) {
|
|
477
|
+
data.writeUInt16LE(HDR_ID.SHA256, extraOffset); // 0x1f
|
|
478
|
+
data.writeUInt16LE(sha256Buf.length, extraOffset + 2); // Length of data
|
|
479
|
+
sha256Buf.copy(data, extraOffset + 4);
|
|
480
|
+
extraOffset += 4 + sha256Buf.length;
|
|
435
481
|
}
|
|
436
482
|
|
|
437
|
-
//
|
|
483
|
+
// Add UID/GID field
|
|
438
484
|
if (this.uid && this.gid) {
|
|
439
|
-
|
|
440
|
-
data.writeUInt16LE(
|
|
441
|
-
data.
|
|
442
|
-
data.writeUInt8(
|
|
443
|
-
data.
|
|
444
|
-
data.
|
|
445
|
-
data.
|
|
446
|
-
|
|
447
|
-
extraOffset += uidgidLen + 4;
|
|
485
|
+
data.writeUInt16LE(HDR_ID.UID_GID, extraOffset); // 0x7875
|
|
486
|
+
data.writeUInt16LE(11, extraOffset + 2); // Length of data
|
|
487
|
+
data.writeUInt8(1, extraOffset + 4); // Version
|
|
488
|
+
data.writeUInt8(4, extraOffset + 5); // UID size
|
|
489
|
+
data.writeUInt32LE(this.uid, extraOffset + 6); // UID
|
|
490
|
+
data.writeUInt8(4, extraOffset + 10); // GID size
|
|
491
|
+
data.writeUInt32LE(this.gid, extraOffset + 11); // GID
|
|
492
|
+
extraOffset += 15;
|
|
448
493
|
}
|
|
449
|
-
|
|
450
|
-
// Add
|
|
494
|
+
|
|
495
|
+
// Add symbolic link field
|
|
496
|
+
if (this.isSymlink && this.linkTarget) {
|
|
497
|
+
const targetBuf = Buffer.from(this.linkTarget, 'utf8');
|
|
498
|
+
const dataLen = 1 + 2 + targetBuf.length; // version + length + target
|
|
499
|
+
|
|
500
|
+
data.writeUInt16LE(HDR_ID.SYMLINK, extraOffset); // 0x7855
|
|
501
|
+
data.writeUInt16LE(dataLen, extraOffset + 2); // Length of data
|
|
502
|
+
data.writeUInt8(1, extraOffset + 4); // Version
|
|
503
|
+
data.writeUInt16LE(targetBuf.length, extraOffset + 5); // Target length
|
|
504
|
+
targetBuf.copy(data, extraOffset + 7); // Target path
|
|
505
|
+
extraOffset += 4 + dataLen;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// Add hard link field
|
|
509
|
+
if (this.isHardLink && this.originalEntry && this.inode !== null) {
|
|
510
|
+
const originalBuf = Buffer.from(this.originalEntry, 'utf8');
|
|
511
|
+
const dataLen = 1 + 4 + 2 + originalBuf.length; // version + inode + length + original
|
|
512
|
+
|
|
513
|
+
data.writeUInt16LE(HDR_ID.HARDLINK, extraOffset); // 0x7865
|
|
514
|
+
data.writeUInt16LE(dataLen, extraOffset + 2); // Length of data
|
|
515
|
+
data.writeUInt8(1, extraOffset + 4); // Version
|
|
516
|
+
data.writeUInt32LE(this.inode, extraOffset + 5); // Inode number
|
|
517
|
+
data.writeUInt16LE(originalBuf.length, extraOffset + 9); // Original entry length
|
|
518
|
+
originalBuf.copy(data, extraOffset + 11); // Original entry path
|
|
519
|
+
extraOffset += 4 + dataLen;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Add Unicode Path field if needed
|
|
451
523
|
if (needsUnicode) {
|
|
452
524
|
extraOffset = this.addUnicodePathField(data, extraOffset);
|
|
453
525
|
}
|
|
454
526
|
|
|
455
|
-
//
|
|
456
|
-
if (sha256Buf) {
|
|
457
|
-
data.writeUInt16LE(HDR_ID.SHA256, extraOffset);
|
|
458
|
-
data.writeUInt16LE(sha256Buf.length, extraOffset + 2);
|
|
459
|
-
sha256Buf.copy(data, extraOffset + 4);
|
|
460
|
-
extraOffset += sha256Buf.length + 4;
|
|
461
|
-
}
|
|
527
|
+
// File comment is already written immediately after filename
|
|
462
528
|
|
|
463
529
|
return data;
|
|
464
530
|
}
|
|
@@ -474,14 +540,27 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
474
540
|
*/
|
|
475
541
|
setDateTime(date: Date): number {
|
|
476
542
|
if (!date) return 0;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
543
|
+
|
|
544
|
+
// DOS date/time format:
|
|
545
|
+
// Date part (16 bits): Year (7 bits) + Month (4 bits) + Day (5 bits)
|
|
546
|
+
// Time part (16 bits): Hour (5 bits) + Minute (6 bits) + Second (5 bits, stored as seconds/2)
|
|
547
|
+
|
|
548
|
+
const year = date.getFullYear() - 1980; // Years since 1980
|
|
549
|
+
const month = date.getMonth() + 1; // Month (1-12)
|
|
550
|
+
const day = date.getDate(); // Day (1-31)
|
|
551
|
+
const hour = date.getHours(); // Hour (0-23)
|
|
552
|
+
const minute = date.getMinutes(); // Minute (0-59)
|
|
553
|
+
const second = date.getSeconds(); // Second (0-59)
|
|
554
|
+
|
|
555
|
+
// Pack date: year (7 bits) + month (4 bits) + day (5 bits)
|
|
556
|
+
const datePart = ((year & 0x7f) << 9) | ((month & 0x0f) << 5) | (day & 0x1f);
|
|
557
|
+
|
|
558
|
+
// Pack time: hour (5 bits) + minute (6 bits) + second/2 (5 bits)
|
|
559
|
+
const timePart = ((hour & 0x1f) << 11) | ((minute & 0x3f) << 5) | ((second >> 1) & 0x1f);
|
|
560
|
+
|
|
561
|
+
// Combine date and time parts
|
|
562
|
+
const time = (datePart << 16) | timePart;
|
|
563
|
+
|
|
485
564
|
return time;
|
|
486
565
|
}
|
|
487
566
|
|
|
@@ -493,13 +572,20 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
493
572
|
parseDateTime(timeStamp: number): Date | null {
|
|
494
573
|
if (timeStamp == 0)
|
|
495
574
|
return null;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
575
|
+
|
|
576
|
+
// Extract date part (upper 16 bits)
|
|
577
|
+
const datePart = (timeStamp >> 16) & 0xffff;
|
|
578
|
+
const year = ((datePart >> 9) & 0x7f) + 1980; // Year (7 bits) + 1980
|
|
579
|
+
const month = ((datePart >> 5) & 0x0f) - 1; // Month (4 bits) - 1 for 0-based
|
|
580
|
+
const day = datePart & 0x1f; // Day (5 bits)
|
|
581
|
+
|
|
582
|
+
// Extract time part (lower 16 bits)
|
|
583
|
+
const timePart = timeStamp & 0xffff;
|
|
584
|
+
const hour = (timePart >> 11) & 0x1f; // Hour (5 bits)
|
|
585
|
+
const minute = (timePart >> 5) & 0x3f; // Minute (6 bits)
|
|
586
|
+
const second = (timePart & 0x1f) << 1; // Second (5 bits) * 2
|
|
587
|
+
|
|
588
|
+
return new Date(year, month, day, hour, minute, second);
|
|
503
589
|
}
|
|
504
590
|
|
|
505
591
|
/**
|
|
@@ -656,31 +742,31 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
656
742
|
* Includes compression, encryption, timestamps, and extra fields
|
|
657
743
|
*/
|
|
658
744
|
showVerboseInfo() {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
745
|
+
Logger.log('=== Central Directory Entry (%s) ===', this.filename);
|
|
746
|
+
Logger.log('unzip from start of archive: ', this.localHdrOffset);
|
|
747
|
+
Logger.log('File system or operating system of origin: ', this.fileSystemToString());
|
|
748
|
+
Logger.log('Version of encoding software: ', this.verMadeBy);
|
|
749
|
+
Logger.log('Compression Method: ', this.cmpMethodToString());
|
|
750
|
+
Logger.log('File Security Status: ',
|
|
665
751
|
this.bitFlags & GP_FLAG.ENCRYPTED ?
|
|
666
752
|
this.bitFlags & GP_FLAG.STRONG_ENCRYPT ? 'Strong Encrypt' : 'Encrypted' :
|
|
667
753
|
'Not Encrypted');
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
754
|
+
Logger.log('File Modified (DOS date/time) ', this.toFormattedDateString());
|
|
755
|
+
Logger.log('File Modified (UTC) ', this.toFormattedUTCDateString());
|
|
756
|
+
Logger.log('Compressed Size: ', this.compressedSize);
|
|
757
|
+
Logger.log('UnCompressed Size: ', this.uncompressedSize);
|
|
758
|
+
Logger.log(`32-bit CRC value (hex): ${this.crc.toString(16).padStart(8, '0')}`);
|
|
759
|
+
Logger.log('Length of extra field: ', this.extraField?.length ?? 0);
|
|
760
|
+
Logger.log('Length of file comment: ', this.comment?.length ?? 0);
|
|
761
|
+
Logger.log('Unix File Attributes: ');
|
|
762
|
+
Logger.log('MS-DOS File Attributes: ', this.dosAttributesToString());
|
|
677
763
|
if (this.extraField) {
|
|
678
|
-
|
|
764
|
+
Logger.log('\nThe Central-Directory Extra Field contains:');
|
|
679
765
|
try {
|
|
680
766
|
for (let i = 0; i < this.extraField.length; ) {
|
|
681
767
|
// Ensure we have at least 4 bytes (header ID + length)
|
|
682
768
|
if (i + 4 > this.extraField.length) {
|
|
683
|
-
|
|
769
|
+
Logger.log(` Warning: Truncated extra field at offset ${i}`);
|
|
684
770
|
break;
|
|
685
771
|
}
|
|
686
772
|
|
|
@@ -690,7 +776,7 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
690
776
|
|
|
691
777
|
// Validate the length to ensure it doesn't exceed buffer bounds
|
|
692
778
|
if (_len < 0 || i + 4 + _len > this.extraField.length) {
|
|
693
|
-
|
|
779
|
+
Logger.log(` Warning: Invalid extra field length (${_len}) at offset ${i} for ID ${_idStr}`);
|
|
694
780
|
break;
|
|
695
781
|
}
|
|
696
782
|
|
|
@@ -698,22 +784,22 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
698
784
|
|
|
699
785
|
try {
|
|
700
786
|
if (_id === HDR_ID.SHA256) {
|
|
701
|
-
|
|
787
|
+
Logger.log(` ID[0x${_idStr}] NeoZip-SHA256: ${_data.toString('hex')}`);
|
|
702
788
|
} else if (_id === HDR_ID.UNV_TIME) {
|
|
703
789
|
if (_len >= 5) {
|
|
704
790
|
const flags = _data.readUInt8(0);
|
|
705
791
|
const timestamp = _data.readUInt32LE(1);
|
|
706
792
|
const date = new Date(timestamp * 1000);
|
|
707
|
-
|
|
793
|
+
Logger.log(` ID[0x${_idStr}] Universal Time: flags=${flags}, time=${date.toISOString()}`);
|
|
708
794
|
} else {
|
|
709
|
-
|
|
795
|
+
Logger.log(` ID[0x${_idStr}] Universal Time: (invalid length ${_len})`);
|
|
710
796
|
}
|
|
711
797
|
} else if (_id === HDR_ID.UID_GID) {
|
|
712
798
|
if (_len >= 5) {
|
|
713
799
|
const version = _data.readUInt8(0);
|
|
714
800
|
const uidSize = _data.readUInt8(1);
|
|
715
801
|
if (2 + uidSize > _len) {
|
|
716
|
-
|
|
802
|
+
Logger.log(` ID[0x${_idStr}] Unix UID/GID: (invalid UID size ${uidSize})`);
|
|
717
803
|
} else {
|
|
718
804
|
const uid = _data.readUIntLE(2, Math.min(uidSize, 4));
|
|
719
805
|
let gid = 0;
|
|
@@ -723,10 +809,37 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
723
809
|
gid = _data.readUIntLE(2 + uidSize + 1, Math.min(gidSize, 4));
|
|
724
810
|
}
|
|
725
811
|
}
|
|
726
|
-
|
|
812
|
+
Logger.log(` ID[0x${_idStr}] Unix UID/GID: version=${version}, uid=${uid}, gid=${gid}`);
|
|
813
|
+
}
|
|
814
|
+
} else {
|
|
815
|
+
Logger.log(` ID[0x${_idStr}] Unix UID/GID: (invalid length ${_len})`);
|
|
816
|
+
}
|
|
817
|
+
} else if (_id === HDR_ID.SYMLINK) {
|
|
818
|
+
if (_len >= 3) {
|
|
819
|
+
const version = _data.readUInt8(0);
|
|
820
|
+
const targetLength = _data.readUInt16LE(1);
|
|
821
|
+
if (targetLength > 0 && _len >= 3 + targetLength) {
|
|
822
|
+
const target = _data.subarray(3, 3 + targetLength).toString('utf8');
|
|
823
|
+
Logger.log(` ID[0x${_idStr}] Symbolic Link: version=${version}, target="${target}"`);
|
|
824
|
+
} else {
|
|
825
|
+
Logger.log(` ID[0x${_idStr}] Symbolic Link: (invalid target length ${targetLength})`);
|
|
826
|
+
}
|
|
827
|
+
} else {
|
|
828
|
+
Logger.log(` ID[0x${_idStr}] Symbolic Link: (invalid length ${_len})`);
|
|
829
|
+
}
|
|
830
|
+
} else if (_id === HDR_ID.HARDLINK) {
|
|
831
|
+
if (_len >= 11) {
|
|
832
|
+
const version = _data.readUInt8(0);
|
|
833
|
+
const inode = _data.readUInt32LE(1);
|
|
834
|
+
const originalLength = _data.readUInt16LE(5);
|
|
835
|
+
if (originalLength > 0 && _len >= 7 + originalLength) {
|
|
836
|
+
const original = _data.subarray(7, 7 + originalLength).toString('utf8');
|
|
837
|
+
Logger.log(` ID[0x${_idStr}] Hard Link: version=${version}, inode=${inode}, original="${original}"`);
|
|
838
|
+
} else {
|
|
839
|
+
Logger.log(` ID[0x${_idStr}] Hard Link: (invalid original length ${originalLength})`);
|
|
727
840
|
}
|
|
728
841
|
} else {
|
|
729
|
-
|
|
842
|
+
Logger.log(` ID[0x${_idStr}] Hard Link: (invalid length ${_len})`);
|
|
730
843
|
}
|
|
731
844
|
} else if (_id === HDR_ID.UNICODE_PATH) {
|
|
732
845
|
if (_len >= 5) {
|
|
@@ -740,28 +853,65 @@ export default class ZipEntry implements ZipFileEntry {
|
|
|
740
853
|
|
|
741
854
|
const crcMatch = nameCrc32 === calculatedCrc ? 'MATCH' : 'MISMATCH';
|
|
742
855
|
|
|
743
|
-
|
|
744
|
-
|
|
856
|
+
Logger.log(` ID[0x${_idStr}] Unicode Path: version=${version}, CRC32=${nameCrc32.toString(16)} (${crcMatch})`);
|
|
857
|
+
Logger.log(` Path: "${unicodeName}"`);
|
|
745
858
|
} else {
|
|
746
|
-
|
|
859
|
+
Logger.log(` ID[0x${_idStr}] Unicode Path: (invalid length ${_len})`);
|
|
860
|
+
}
|
|
861
|
+
} else if (_id === HDR_ID.ZIP64) {
|
|
862
|
+
// ZIP64 Extended Information (0x0001)
|
|
863
|
+
Logger.log(` ID[0x${_idStr}] ZIP64 Extended Information:`);
|
|
864
|
+
if (_len >= 8) {
|
|
865
|
+
let offset = 0;
|
|
866
|
+
|
|
867
|
+
// Read uncompressed size (8 bytes) if present
|
|
868
|
+
if (offset + 8 <= _len) {
|
|
869
|
+
const uncompressedSize = _data.readBigUInt64LE(offset);
|
|
870
|
+
Logger.log(` Uncompressed Size (ZIP64): ${uncompressedSize.toString()} bytes`);
|
|
871
|
+
offset += 8;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// Read compressed size (8 bytes) if present
|
|
875
|
+
if (offset + 8 <= _len) {
|
|
876
|
+
const compressedSize = _data.readBigUInt64LE(offset);
|
|
877
|
+
Logger.log(` Compressed Size (ZIP64): ${compressedSize.toString()} bytes`);
|
|
878
|
+
offset += 8;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// Read local header offset (8 bytes) if present
|
|
882
|
+
if (offset + 8 <= _len) {
|
|
883
|
+
const localHeaderOffset = _data.readBigUInt64LE(offset);
|
|
884
|
+
Logger.log(` Local Header Offset (ZIP64): ${localHeaderOffset.toString()}`);
|
|
885
|
+
offset += 8;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// Read disk number (4 bytes) if present
|
|
889
|
+
if (offset + 4 <= _len) {
|
|
890
|
+
const diskNumber = _data.readUInt32LE(offset);
|
|
891
|
+
Logger.log(` Disk Number (ZIP64): ${diskNumber}`);
|
|
892
|
+
}
|
|
893
|
+
} else {
|
|
894
|
+
Logger.log(` ZIP64 Extended Information: (invalid length ${_len})`);
|
|
747
895
|
}
|
|
748
896
|
} else {
|
|
749
897
|
// For unknown fields, show a hex preview of the first few bytes
|
|
750
898
|
const preview = _len > 0
|
|
751
899
|
? _data.slice(0, Math.min(16, _len)).toString('hex')
|
|
752
900
|
: '';
|
|
753
|
-
|
|
901
|
+
Logger.log(` ID[0x${_idStr}] Unknown field: length=${_len} bytes${preview ? ', data=' + preview + '...' : ''}`);
|
|
754
902
|
}
|
|
755
903
|
} catch (error: any) {
|
|
756
|
-
|
|
904
|
+
Logger.log(` Error parsing extra field ID[0x${_idStr}]: ${error.message}`);
|
|
757
905
|
}
|
|
758
906
|
|
|
759
907
|
i += 4 + _len;
|
|
760
908
|
}
|
|
761
909
|
} catch (error: any) {
|
|
762
|
-
|
|
910
|
+
Logger.log(` Error parsing extra fields: ${error.message}`);
|
|
763
911
|
}
|
|
764
912
|
}
|
|
765
|
-
|
|
913
|
+
Logger.log('\n');
|
|
766
914
|
}
|
|
767
915
|
}
|
|
916
|
+
|
|
917
|
+
export { ZipEntry };
|