@opengeni/artifact-tool 0.2.2
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 +190 -0
- package/README.md +104 -0
- package/dist/bounded-zip.d.ts +28 -0
- package/dist/chunk-4BSENMAE.js +39 -0
- package/dist/chunk-4BSENMAE.js.map +1 -0
- package/dist/chunk-4FRFNNBM.js +276 -0
- package/dist/chunk-4FRFNNBM.js.map +1 -0
- package/dist/chunk-5XIA6KHZ.js +49 -0
- package/dist/chunk-5XIA6KHZ.js.map +1 -0
- package/dist/chunk-66CT2ZRP.js +2229 -0
- package/dist/chunk-66CT2ZRP.js.map +1 -0
- package/dist/chunk-72SYDU4O.js +319 -0
- package/dist/chunk-72SYDU4O.js.map +1 -0
- package/dist/chunk-B2ZJRZDA.js +279 -0
- package/dist/chunk-B2ZJRZDA.js.map +1 -0
- package/dist/chunk-DCTLTNPW.js +2458 -0
- package/dist/chunk-DCTLTNPW.js.map +1 -0
- package/dist/chunk-FGZM4FQ6.js +473 -0
- package/dist/chunk-FGZM4FQ6.js.map +1 -0
- package/dist/chunk-HTJBLBDE.js +591 -0
- package/dist/chunk-HTJBLBDE.js.map +1 -0
- package/dist/chunk-IYFXZQ34.js +5306 -0
- package/dist/chunk-IYFXZQ34.js.map +1 -0
- package/dist/chunk-J6N7IR44.js +172 -0
- package/dist/chunk-J6N7IR44.js.map +1 -0
- package/dist/chunk-N2IHNWBS.js +1002 -0
- package/dist/chunk-N2IHNWBS.js.map +1 -0
- package/dist/chunk-NAG44K67.js +549 -0
- package/dist/chunk-NAG44K67.js.map +1 -0
- package/dist/chunk-O24KTEGP.js +33 -0
- package/dist/chunk-O24KTEGP.js.map +1 -0
- package/dist/chunk-PI2AZVGK.js +2074 -0
- package/dist/chunk-PI2AZVGK.js.map +1 -0
- package/dist/chunk-Q2FFHEY7.js +40 -0
- package/dist/chunk-Q2FFHEY7.js.map +1 -0
- package/dist/chunk-RBGQADXA.js +57 -0
- package/dist/chunk-RBGQADXA.js.map +1 -0
- package/dist/chunk-U5G2BKM2.js +613 -0
- package/dist/chunk-U5G2BKM2.js.map +1 -0
- package/dist/chunk-VOJHMSM3.js +39 -0
- package/dist/chunk-VOJHMSM3.js.map +1 -0
- package/dist/chunk-VUNV25KB.js +16 -0
- package/dist/chunk-VUNV25KB.js.map +1 -0
- package/dist/chunk-XIFUNVBO.js +101 -0
- package/dist/chunk-XIFUNVBO.js.map +1 -0
- package/dist/chunk-ZCJYRJGB.js +489 -0
- package/dist/chunk-ZCJYRJGB.js.map +1 -0
- package/dist/chunk-ZZXPEE4S.js +2260 -0
- package/dist/chunk-ZZXPEE4S.js.map +1 -0
- package/dist/document-docx-api.d.ts +49 -0
- package/dist/document-docx-codec.d.ts +9 -0
- package/dist/document-docx-codec.js +4765 -0
- package/dist/document-docx-codec.js.map +1 -0
- package/dist/document-docx-import.d.ts +261 -0
- package/dist/document-docx-packer.d.ts +18 -0
- package/dist/document-docx-state.d.ts +12 -0
- package/dist/document-render.d.ts +3 -0
- package/dist/document-render.js +492 -0
- package/dist/document-render.js.map +1 -0
- package/dist/document.d.ts +432 -0
- package/dist/document.js +37 -0
- package/dist/document.js.map +1 -0
- package/dist/errors.d.ts +23 -0
- package/dist/file-blob.d.ts +11 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/inspection.d.ts +12 -0
- package/dist/kernel.d.ts +101 -0
- package/dist/lib-GQLPACFK.js +9746 -0
- package/dist/lib-GQLPACFK.js.map +1 -0
- package/dist/materializer-cli-entry.d.ts +2 -0
- package/dist/materializer-cli-entry.js +29 -0
- package/dist/materializer-cli-entry.js.map +1 -0
- package/dist/materializer-cli.d.ts +24 -0
- package/dist/materializer-cli.js +24 -0
- package/dist/materializer-cli.js.map +1 -0
- package/dist/native-raster.d.ts +10 -0
- package/dist/native.d.ts +129 -0
- package/dist/native.js +31 -0
- package/dist/native.js.map +1 -0
- package/dist/office-import.d.ts +48 -0
- package/dist/office-import.js +154 -0
- package/dist/office-import.js.map +1 -0
- package/dist/presentation-pptx-api.d.ts +60 -0
- package/dist/presentation-pptx-import.d.ts +5 -0
- package/dist/presentation-pptx-state-digest-765CZZED.js +10 -0
- package/dist/presentation-pptx-state-digest-765CZZED.js.map +1 -0
- package/dist/presentation-pptx-state-digest.d.ts +3 -0
- package/dist/presentation-pptx-state.d.ts +4 -0
- package/dist/presentation-pptx-xml.d.ts +29 -0
- package/dist/presentation-pptx.d.ts +5 -0
- package/dist/presentation-pptx.js +2365 -0
- package/dist/presentation-pptx.js.map +1 -0
- package/dist/presentation-render.d.ts +29 -0
- package/dist/presentation-render.js +375 -0
- package/dist/presentation-render.js.map +1 -0
- package/dist/presentation.d.ts +565 -0
- package/dist/presentation.js +71 -0
- package/dist/presentation.js.map +1 -0
- package/dist/production-composite.d.ts +68 -0
- package/dist/production-document.d.ts +2 -0
- package/dist/production-document.js +176 -0
- package/dist/production-document.js.map +1 -0
- package/dist/production-native-codecs.d.ts +94 -0
- package/dist/production-presentation.d.ts +2 -0
- package/dist/production-presentation.js +176 -0
- package/dist/production-presentation.js.map +1 -0
- package/dist/production-sha256.d.ts +2 -0
- package/dist/production-spreadsheet-native.d.ts +12 -0
- package/dist/production-spreadsheet.d.ts +2 -0
- package/dist/production-spreadsheet.js +176 -0
- package/dist/production-spreadsheet.js.map +1 -0
- package/dist/production.d.ts +96 -0
- package/dist/raster-image.d.ts +34 -0
- package/dist/reference.d.ts +17 -0
- package/dist/reference.js +574 -0
- package/dist/reference.js.map +1 -0
- package/dist/runtime-cli-entry.d.ts +2 -0
- package/dist/runtime-cli-entry.js +21 -0
- package/dist/runtime-cli-entry.js.map +1 -0
- package/dist/runtime-cli.d.ts +76 -0
- package/dist/runtime-cli.js +26 -0
- package/dist/runtime-cli.js.map +1 -0
- package/dist/runtime-development.d.ts +73 -0
- package/dist/runtime-development.js +30 -0
- package/dist/runtime-development.js.map +1 -0
- package/dist/runtime-receipt.d.ts +19 -0
- package/dist/runtime.d.ts +355 -0
- package/dist/runtime.js +42 -0
- package/dist/runtime.js.map +1 -0
- package/dist/snapshot.d.ts +26 -0
- package/dist/snapshot.js +61 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/spreadsheet-address.d.ts +18 -0
- package/dist/spreadsheet-file.d.ts +17 -0
- package/dist/spreadsheet-formula.d.ts +67 -0
- package/dist/spreadsheet-image.d.ts +17 -0
- package/dist/spreadsheet-render.d.ts +5 -0
- package/dist/spreadsheet-render.js +752 -0
- package/dist/spreadsheet-render.js.map +1 -0
- package/dist/spreadsheet-types.d.ts +155 -0
- package/dist/spreadsheet-xlsx-api.d.ts +88 -0
- package/dist/spreadsheet-xlsx-codec.d.ts +16 -0
- package/dist/spreadsheet-xlsx-codec.js +16 -0
- package/dist/spreadsheet-xlsx-codec.js.map +1 -0
- package/dist/spreadsheet-xlsx-state.d.ts +16 -0
- package/dist/spreadsheet.d.ts +724 -0
- package/dist/spreadsheet.js +67 -0
- package/dist/spreadsheet.js.map +1 -0
- package/package.json +129 -0
- package/src/bounded-zip.ts +450 -0
- package/src/document-docx-api.ts +64 -0
- package/src/document-docx-codec.ts +2253 -0
- package/src/document-docx-import.ts +3814 -0
- package/src/document-docx-packer.ts +72 -0
- package/src/document-docx-state.ts +59 -0
- package/src/document-render.ts +615 -0
- package/src/document.ts +2800 -0
- package/src/errors.ts +45 -0
- package/src/file-blob.ts +43 -0
- package/src/index.ts +4 -0
- package/src/inspection.ts +50 -0
- package/src/kernel.ts +525 -0
- package/src/materializer-cli-entry.ts +11 -0
- package/src/materializer-cli.ts +743 -0
- package/src/native-raster.ts +141 -0
- package/src/native.ts +390 -0
- package/src/office-import.ts +243 -0
- package/src/presentation-pptx-api.ts +107 -0
- package/src/presentation-pptx-import.ts +2065 -0
- package/src/presentation-pptx-state-digest.ts +46 -0
- package/src/presentation-pptx-state.ts +18 -0
- package/src/presentation-pptx-xml.ts +473 -0
- package/src/presentation-pptx.ts +447 -0
- package/src/presentation-render.ts +532 -0
- package/src/presentation.ts +2599 -0
- package/src/production-composite.ts +805 -0
- package/src/production-document.ts +2 -0
- package/src/production-native-codecs.ts +1141 -0
- package/src/production-presentation.ts +2 -0
- package/src/production-sha256.ts +150 -0
- package/src/production-spreadsheet-native.ts +686 -0
- package/src/production-spreadsheet.ts +2 -0
- package/src/production.ts +1022 -0
- package/src/raster-image.ts +586 -0
- package/src/reference.ts +17 -0
- package/src/runtime-cli-entry.ts +13 -0
- package/src/runtime-cli.ts +670 -0
- package/src/runtime-development.ts +689 -0
- package/src/runtime-receipt.ts +169 -0
- package/src/runtime.ts +1463 -0
- package/src/snapshot.ts +88 -0
- package/src/spreadsheet-address.ts +90 -0
- package/src/spreadsheet-file.ts +71 -0
- package/src/spreadsheet-formula.ts +1212 -0
- package/src/spreadsheet-image.ts +242 -0
- package/src/spreadsheet-render.ts +985 -0
- package/src/spreadsheet-types.ts +171 -0
- package/src/spreadsheet-xlsx-api.ts +123 -0
- package/src/spreadsheet-xlsx-codec.ts +3063 -0
- package/src/spreadsheet-xlsx-state.ts +191 -0
- package/src/spreadsheet.ts +5195 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// src/bounded-zip.ts
|
|
2
|
+
function parseBoundedZip(bytes, limits, fail) {
|
|
3
|
+
if (bytes.byteLength < 22) fail("invalid", "ZIP end record is missing");
|
|
4
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
5
|
+
const end = findEndRecord(view, fail);
|
|
6
|
+
const disk = view.getUint16(end + 4, true);
|
|
7
|
+
const centralDisk = view.getUint16(end + 6, true);
|
|
8
|
+
const diskEntries = view.getUint16(end + 8, true);
|
|
9
|
+
const entryCount = view.getUint16(end + 10, true);
|
|
10
|
+
const centralSize = view.getUint32(end + 12, true);
|
|
11
|
+
const centralOffset = view.getUint32(end + 16, true);
|
|
12
|
+
if (disk !== 0 || centralDisk !== 0 || diskEntries !== entryCount) {
|
|
13
|
+
fail("unsupported", "Multi-disk ZIP archives are unsupported");
|
|
14
|
+
}
|
|
15
|
+
if (entryCount === 65535 || centralSize === 4294967295 || centralOffset === 4294967295) {
|
|
16
|
+
fail("unsupported", "ZIP64 archives are unsupported");
|
|
17
|
+
}
|
|
18
|
+
if (entryCount > limits.entries) fail("limit", "ZIP exceeds its entry limit");
|
|
19
|
+
if (centralOffset + centralSize !== end || centralOffset > bytes.byteLength) {
|
|
20
|
+
fail("invalid", "ZIP central-directory bounds are invalid");
|
|
21
|
+
}
|
|
22
|
+
if (end >= 20 && view.getUint32(end - 20, true) === 117853008) {
|
|
23
|
+
fail("unsupported", "ZIP64 archives are unsupported");
|
|
24
|
+
}
|
|
25
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
26
|
+
const names = /* @__PURE__ */ new Set();
|
|
27
|
+
const entries = [];
|
|
28
|
+
let offset = centralOffset;
|
|
29
|
+
let expandedBytes = 0;
|
|
30
|
+
let compressedBytes = 0;
|
|
31
|
+
for (let index = 0; index < entryCount; index += 1) {
|
|
32
|
+
ensureRange(bytes, offset, 46, fail, "ZIP central-directory entry");
|
|
33
|
+
if (view.getUint32(offset, true) !== 33639248) {
|
|
34
|
+
fail("invalid", "ZIP central-directory signature is invalid");
|
|
35
|
+
}
|
|
36
|
+
const flags = view.getUint16(offset + 8, true);
|
|
37
|
+
const compression = view.getUint16(offset + 10, true);
|
|
38
|
+
const checksum = view.getUint32(offset + 16, true);
|
|
39
|
+
const compressedSize = view.getUint32(offset + 20, true);
|
|
40
|
+
const expandedSize = view.getUint32(offset + 24, true);
|
|
41
|
+
const nameLength = view.getUint16(offset + 28, true);
|
|
42
|
+
const extraLength = view.getUint16(offset + 30, true);
|
|
43
|
+
const commentLength = view.getUint16(offset + 32, true);
|
|
44
|
+
const startDisk = view.getUint16(offset + 34, true);
|
|
45
|
+
const localHeaderOffset = view.getUint32(offset + 42, true);
|
|
46
|
+
const recordLength = 46 + nameLength + extraLength + commentLength;
|
|
47
|
+
ensureRange(bytes, offset, recordLength, fail, "ZIP central-directory entry");
|
|
48
|
+
if (offset + recordLength > centralOffset + centralSize) {
|
|
49
|
+
fail("invalid", "ZIP central-directory entry is out of bounds");
|
|
50
|
+
}
|
|
51
|
+
if (startDisk !== 0) fail("unsupported", "Multi-disk ZIP entries are unsupported");
|
|
52
|
+
if ((flags & 65) !== 0) fail("encrypted", "Encrypted ZIP entries are unsupported");
|
|
53
|
+
if ((flags & ~2062) !== 0 || compression === 0 && (flags & 6) !== 0) {
|
|
54
|
+
fail("unsupported", "ZIP entry flags are unsupported");
|
|
55
|
+
}
|
|
56
|
+
if (compression !== 0 && compression !== 8) {
|
|
57
|
+
fail("unsupported", `ZIP compression method ${compression} is unsupported`);
|
|
58
|
+
}
|
|
59
|
+
if (compressedSize === 4294967295 || expandedSize === 4294967295 || localHeaderOffset === 4294967295) {
|
|
60
|
+
fail("unsupported", "ZIP64 entries are unsupported");
|
|
61
|
+
}
|
|
62
|
+
rejectZip64Extra(
|
|
63
|
+
bytes.subarray(offset + 46 + nameLength, offset + 46 + nameLength + extraLength),
|
|
64
|
+
fail
|
|
65
|
+
);
|
|
66
|
+
let name;
|
|
67
|
+
try {
|
|
68
|
+
name = decoder.decode(bytes.subarray(offset + 46, offset + 46 + nameLength));
|
|
69
|
+
} catch {
|
|
70
|
+
fail("invalid", "ZIP entry name is not valid UTF-8");
|
|
71
|
+
}
|
|
72
|
+
validatePath(name, fail);
|
|
73
|
+
const collisionKey = name.normalize("NFC").toLowerCase();
|
|
74
|
+
if (names.has(collisionKey))
|
|
75
|
+
fail("invalid", "ZIP contains duplicate normalized entry names", name);
|
|
76
|
+
names.add(collisionKey);
|
|
77
|
+
if (compressedSize > limits.compressedEntryBytes)
|
|
78
|
+
fail("limit", "ZIP entry exceeds its compressed-size limit", name);
|
|
79
|
+
if (expandedSize > limits.expandedEntryBytes)
|
|
80
|
+
fail("limit", "ZIP entry exceeds its expanded-size limit", name);
|
|
81
|
+
if (compressedSize === 0 && expandedSize !== 0)
|
|
82
|
+
fail("invalid", "ZIP entry has impossible sizes", name);
|
|
83
|
+
if (expandedSize > (limits.compressionRatioThreshold ?? 0) && expandedSize / Math.max(1, compressedSize) > limits.compressionRatio)
|
|
84
|
+
fail("limit", "ZIP entry exceeds its compression-ratio limit", name);
|
|
85
|
+
expandedBytes += expandedSize;
|
|
86
|
+
compressedBytes += compressedSize;
|
|
87
|
+
if (expandedBytes > limits.expandedBytes) fail("limit", "ZIP exceeds its expanded-size limit");
|
|
88
|
+
if (expandedBytes > (limits.compressionRatioThreshold ?? 0) && expandedBytes / Math.max(1, compressedBytes) > limits.compressionRatio) {
|
|
89
|
+
fail("limit", "ZIP exceeds its aggregate compression-ratio limit", name);
|
|
90
|
+
}
|
|
91
|
+
const entry = localBounds(
|
|
92
|
+
bytes,
|
|
93
|
+
view,
|
|
94
|
+
decoder,
|
|
95
|
+
{
|
|
96
|
+
name,
|
|
97
|
+
flags,
|
|
98
|
+
compression,
|
|
99
|
+
checksum,
|
|
100
|
+
compressedSize,
|
|
101
|
+
expandedSize,
|
|
102
|
+
localHeaderOffset,
|
|
103
|
+
directory: name.endsWith("/")
|
|
104
|
+
},
|
|
105
|
+
centralOffset,
|
|
106
|
+
fail
|
|
107
|
+
);
|
|
108
|
+
entries.push(entry);
|
|
109
|
+
offset += recordLength;
|
|
110
|
+
}
|
|
111
|
+
if (offset !== centralOffset + centralSize)
|
|
112
|
+
fail("invalid", "ZIP central-directory size is inconsistent");
|
|
113
|
+
const localOrder = [...entries].sort(
|
|
114
|
+
(left, right) => left.localHeaderOffset - right.localHeaderOffset
|
|
115
|
+
);
|
|
116
|
+
for (let index = 1; index < localOrder.length; index += 1) {
|
|
117
|
+
const previous = localOrder[index - 1];
|
|
118
|
+
const current = localOrder[index];
|
|
119
|
+
if (previous.recordEnd > current.localHeaderOffset) {
|
|
120
|
+
fail("invalid", `ZIP local entries overlap: ${previous.name}`, current.name);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return entries;
|
|
124
|
+
}
|
|
125
|
+
async function consumeZipEntry(archive, entry, maximumBytes, fail, collect) {
|
|
126
|
+
if (entry.expandedSize > maximumBytes) {
|
|
127
|
+
fail("limit", "ZIP entry exceeds its configured expanded-size limit", entry.name);
|
|
128
|
+
}
|
|
129
|
+
const compressed = archive.subarray(entry.dataStart, entry.dataEnd);
|
|
130
|
+
if (entry.compression === 0) {
|
|
131
|
+
if (compressed.byteLength !== entry.expandedSize || zipCrc32(compressed) !== entry.checksum) {
|
|
132
|
+
fail("invalid", "ZIP entry failed size or checksum validation", entry.name);
|
|
133
|
+
}
|
|
134
|
+
return collect ? compressed.slice() : void 0;
|
|
135
|
+
}
|
|
136
|
+
if (typeof DecompressionStream === "undefined") {
|
|
137
|
+
return inflateWithNode(compressed, entry, fail, collect);
|
|
138
|
+
}
|
|
139
|
+
let stream;
|
|
140
|
+
try {
|
|
141
|
+
stream = new Blob([Uint8Array.from(compressed)]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
|
|
142
|
+
} catch {
|
|
143
|
+
return inflateWithNode(compressed, entry, fail, collect);
|
|
144
|
+
}
|
|
145
|
+
const output = collect ? new Uint8Array(entry.expandedSize) : void 0;
|
|
146
|
+
const reader = stream.getReader();
|
|
147
|
+
let offset = 0;
|
|
148
|
+
let checksum = 4294967295;
|
|
149
|
+
try {
|
|
150
|
+
while (true) {
|
|
151
|
+
const result = await reader.read().catch(() => fail("invalid", "DEFLATE stream is invalid", entry.name));
|
|
152
|
+
if (result.done) break;
|
|
153
|
+
if (offset + result.value.byteLength > entry.expandedSize) {
|
|
154
|
+
await reader.cancel().catch(() => void 0);
|
|
155
|
+
fail("limit", "Inflated ZIP entry exceeds its declared or configured size", entry.name);
|
|
156
|
+
}
|
|
157
|
+
output?.set(result.value, offset);
|
|
158
|
+
offset += result.value.byteLength;
|
|
159
|
+
checksum = zipCrc32Update(checksum, result.value);
|
|
160
|
+
}
|
|
161
|
+
} finally {
|
|
162
|
+
reader.releaseLock();
|
|
163
|
+
}
|
|
164
|
+
if (offset !== entry.expandedSize || (checksum ^ 4294967295) >>> 0 !== entry.checksum) {
|
|
165
|
+
fail("invalid", "ZIP entry failed size or checksum validation", entry.name);
|
|
166
|
+
}
|
|
167
|
+
return output;
|
|
168
|
+
}
|
|
169
|
+
async function inflateWithNode(compressed, entry, fail, collect) {
|
|
170
|
+
if (typeof process === "undefined" || !process.versions?.node) {
|
|
171
|
+
fail("platform", "Raw DEFLATE is unavailable", entry.name);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const { inflateRawSync } = await loadNodeZlib();
|
|
175
|
+
const output = inflateRawSync(compressed, { maxOutputLength: entry.expandedSize });
|
|
176
|
+
if (output.byteLength !== entry.expandedSize || zipCrc32(output) !== entry.checksum) {
|
|
177
|
+
fail("invalid", "ZIP entry failed size or checksum validation", entry.name);
|
|
178
|
+
}
|
|
179
|
+
return collect ? Uint8Array.from(output) : void 0;
|
|
180
|
+
} catch (error) {
|
|
181
|
+
if (error.code === "ERR_BUFFER_TOO_LARGE") {
|
|
182
|
+
fail("limit", "Inflated ZIP entry exceeds its declared or configured size", entry.name);
|
|
183
|
+
}
|
|
184
|
+
fail("invalid", "DEFLATE stream is invalid", entry.name);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async function loadNodeZlib() {
|
|
188
|
+
return importRuntimeModule("node:zlib");
|
|
189
|
+
}
|
|
190
|
+
function importRuntimeModule(specifier) {
|
|
191
|
+
return import(
|
|
192
|
+
/* @vite-ignore */
|
|
193
|
+
specifier
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
async function inflateBoundedZipEntry(archive, entry, maximumBytes, fail) {
|
|
197
|
+
return await consumeZipEntry(archive, entry, maximumBytes, fail, true);
|
|
198
|
+
}
|
|
199
|
+
async function verifyBoundedZipEntry(archive, entry, maximumBytes, fail) {
|
|
200
|
+
await consumeZipEntry(archive, entry, maximumBytes, fail, false);
|
|
201
|
+
}
|
|
202
|
+
function findEndRecord(view, fail) {
|
|
203
|
+
const minimum = Math.max(0, view.byteLength - 65557);
|
|
204
|
+
for (let offset = view.byteLength - 22; offset >= minimum; offset -= 1) {
|
|
205
|
+
if (view.getUint32(offset, true) === 101010256 && offset + 22 + view.getUint16(offset + 20, true) === view.byteLength)
|
|
206
|
+
return offset;
|
|
207
|
+
}
|
|
208
|
+
return fail("invalid", "ZIP end record is missing");
|
|
209
|
+
}
|
|
210
|
+
function localBounds(bytes, view, decoder, entry, centralOffset, fail) {
|
|
211
|
+
const header = entry.localHeaderOffset;
|
|
212
|
+
ensureRange(bytes, header, 30, fail, "ZIP local header", entry.name);
|
|
213
|
+
if (header + 30 > centralOffset || view.getUint32(header, true) !== 67324752) {
|
|
214
|
+
fail("invalid", "ZIP local-file header is invalid", entry.name);
|
|
215
|
+
}
|
|
216
|
+
const flags = view.getUint16(header + 6, true);
|
|
217
|
+
const compression = view.getUint16(header + 8, true);
|
|
218
|
+
if (flags !== entry.flags || compression !== entry.compression) {
|
|
219
|
+
fail("invalid", "ZIP local and central entry metadata disagree", entry.name);
|
|
220
|
+
}
|
|
221
|
+
const checksum = view.getUint32(header + 14, true);
|
|
222
|
+
const compressedSize = view.getUint32(header + 18, true);
|
|
223
|
+
const expandedSize = view.getUint32(header + 22, true);
|
|
224
|
+
const descriptor = (entry.flags & 8) !== 0;
|
|
225
|
+
if (!descriptor && (checksum !== entry.checksum || compressedSize !== entry.compressedSize || expandedSize !== entry.expandedSize) || descriptor && (checksum !== 0 && checksum !== entry.checksum || compressedSize !== 0 && compressedSize !== entry.compressedSize || expandedSize !== 0 && expandedSize !== entry.expandedSize))
|
|
226
|
+
fail("invalid", "ZIP local and central sizes or checksum disagree", entry.name);
|
|
227
|
+
const nameLength = view.getUint16(header + 26, true);
|
|
228
|
+
const extraLength = view.getUint16(header + 28, true);
|
|
229
|
+
const nameStart = header + 30;
|
|
230
|
+
const nameEnd = nameStart + nameLength;
|
|
231
|
+
ensureRange(
|
|
232
|
+
bytes,
|
|
233
|
+
header,
|
|
234
|
+
30 + nameLength + extraLength + entry.compressedSize,
|
|
235
|
+
fail,
|
|
236
|
+
"ZIP local entry",
|
|
237
|
+
entry.name
|
|
238
|
+
);
|
|
239
|
+
let localName;
|
|
240
|
+
try {
|
|
241
|
+
localName = decoder.decode(bytes.subarray(nameStart, nameEnd));
|
|
242
|
+
} catch {
|
|
243
|
+
fail("invalid", "ZIP local entry name is not valid UTF-8", entry.name);
|
|
244
|
+
}
|
|
245
|
+
if (localName !== entry.name)
|
|
246
|
+
fail("invalid", "ZIP local and central entry names disagree", entry.name);
|
|
247
|
+
const dataStart = nameEnd + extraLength;
|
|
248
|
+
const payloadEnd = dataStart + entry.compressedSize;
|
|
249
|
+
rejectZip64Extra(bytes.subarray(nameEnd, dataStart), fail, entry.name);
|
|
250
|
+
let recordEnd = payloadEnd;
|
|
251
|
+
if (descriptor) recordEnd = validateDescriptor(bytes, view, recordEnd, entry, fail);
|
|
252
|
+
if (dataStart < nameEnd || recordEnd > centralOffset) {
|
|
253
|
+
fail("invalid", "ZIP entry data is outside the local-file area", entry.name);
|
|
254
|
+
}
|
|
255
|
+
if (entry.directory && (entry.compressedSize !== 0 || entry.expandedSize !== 0)) {
|
|
256
|
+
fail("invalid", "ZIP directory entry contains data", entry.name);
|
|
257
|
+
}
|
|
258
|
+
return { ...entry, dataStart, dataEnd: payloadEnd, recordEnd };
|
|
259
|
+
}
|
|
260
|
+
function validateDescriptor(bytes, view, offset, entry, fail) {
|
|
261
|
+
ensureRange(bytes, offset, 12, fail, "ZIP data descriptor", entry.name);
|
|
262
|
+
const matches = (start) => start + 12 <= bytes.byteLength && view.getUint32(start, true) === entry.checksum && view.getUint32(start + 4, true) === entry.compressedSize && view.getUint32(start + 8, true) === entry.expandedSize;
|
|
263
|
+
if (matches(offset)) return offset + 12;
|
|
264
|
+
if (view.getUint32(offset, true) === 134695760 && matches(offset + 4)) return offset + 16;
|
|
265
|
+
return fail("invalid", "ZIP data descriptor disagrees with central directory", entry.name);
|
|
266
|
+
}
|
|
267
|
+
function rejectZip64Extra(extra, fail, entryName) {
|
|
268
|
+
const view = new DataView(extra.buffer, extra.byteOffset, extra.byteLength);
|
|
269
|
+
let offset = 0;
|
|
270
|
+
while (offset < extra.byteLength) {
|
|
271
|
+
if (offset + 4 > extra.byteLength) fail("invalid", "ZIP extra field is malformed", entryName);
|
|
272
|
+
const id = view.getUint16(offset, true);
|
|
273
|
+
const size = view.getUint16(offset + 2, true);
|
|
274
|
+
if (offset + 4 + size > extra.byteLength)
|
|
275
|
+
fail("invalid", "ZIP extra field is malformed", entryName);
|
|
276
|
+
if (id === 1) fail("unsupported", "ZIP64 entries are unsupported", entryName);
|
|
277
|
+
offset += 4 + size;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function validatePath(name, fail) {
|
|
281
|
+
if (name.length === 0 || name.length > 1024 || /[\u0000-\u001f\u007f]/.test(name) || name.includes("\\") || name.startsWith("/") || /^[A-Za-z]:/.test(name) || /%(?:2e|2f|5c)/i.test(name))
|
|
282
|
+
fail("invalid", "ZIP entry path is unsafe", name);
|
|
283
|
+
const segments = name.split("/");
|
|
284
|
+
if (segments.some(
|
|
285
|
+
(segment, index) => segment === "." || segment === ".." || segment === "" && index !== segments.length - 1
|
|
286
|
+
)) {
|
|
287
|
+
fail("invalid", "ZIP entry path is unsafe", name);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function ensureRange(bytes, offset, length, fail, description, entryName) {
|
|
291
|
+
if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(length) || offset < 0 || length < 0 || offset + length > bytes.byteLength) {
|
|
292
|
+
fail("invalid", `${description} is out of bounds`, entryName);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
var crcTable;
|
|
296
|
+
function zipCrc32Update(initial, bytes) {
|
|
297
|
+
if (!crcTable) {
|
|
298
|
+
crcTable = new Uint32Array(256);
|
|
299
|
+
for (let index = 0; index < 256; index += 1) {
|
|
300
|
+
let value2 = index;
|
|
301
|
+
for (let bit = 0; bit < 8; bit += 1)
|
|
302
|
+
value2 = (value2 & 1) !== 0 ? 3988292384 ^ value2 >>> 1 : value2 >>> 1;
|
|
303
|
+
crcTable[index] = value2 >>> 0;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
let value = initial;
|
|
307
|
+
for (const byte of bytes) value = (crcTable[(value ^ byte) & 255] ?? 0) ^ value >>> 8;
|
|
308
|
+
return value >>> 0;
|
|
309
|
+
}
|
|
310
|
+
function zipCrc32(bytes) {
|
|
311
|
+
return (zipCrc32Update(4294967295, bytes) ^ 4294967295) >>> 0;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export {
|
|
315
|
+
parseBoundedZip,
|
|
316
|
+
inflateBoundedZipEntry,
|
|
317
|
+
verifyBoundedZipEntry
|
|
318
|
+
};
|
|
319
|
+
//# sourceMappingURL=chunk-72SYDU4O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bounded-zip.ts"],"sourcesContent":["export type BoundedZipEntry = {\n name: string;\n flags: number;\n compression: 0 | 8;\n checksum: number;\n compressedSize: number;\n expandedSize: number;\n localHeaderOffset: number;\n dataStart: number;\n dataEnd: number;\n recordEnd: number;\n directory: boolean;\n};\n\nexport type BoundedZipLimits = {\n entries: number;\n compressedEntryBytes: number;\n expandedEntryBytes: number;\n expandedBytes: number;\n compressionRatio: number;\n compressionRatioThreshold?: number;\n};\n\nexport type BoundedZipFailure = (\n kind: \"invalid\" | \"unsupported\" | \"encrypted\" | \"limit\" | \"platform\",\n message: string,\n entryName?: string,\n) => never;\n\n/** Parses ZIP metadata and validates every local record without inflating payloads. */\nexport function parseBoundedZip(\n bytes: Uint8Array,\n limits: BoundedZipLimits,\n fail: BoundedZipFailure,\n): BoundedZipEntry[] {\n if (bytes.byteLength < 22) fail(\"invalid\", \"ZIP end record is missing\");\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const end = findEndRecord(view, fail);\n const disk = view.getUint16(end + 4, true);\n const centralDisk = view.getUint16(end + 6, true);\n const diskEntries = view.getUint16(end + 8, true);\n const entryCount = view.getUint16(end + 10, true);\n const centralSize = view.getUint32(end + 12, true);\n const centralOffset = view.getUint32(end + 16, true);\n if (disk !== 0 || centralDisk !== 0 || diskEntries !== entryCount) {\n fail(\"unsupported\", \"Multi-disk ZIP archives are unsupported\");\n }\n if (entryCount === 0xffff || centralSize === 0xffffffff || centralOffset === 0xffffffff) {\n fail(\"unsupported\", \"ZIP64 archives are unsupported\");\n }\n if (entryCount > limits.entries) fail(\"limit\", \"ZIP exceeds its entry limit\");\n if (centralOffset + centralSize !== end || centralOffset > bytes.byteLength) {\n fail(\"invalid\", \"ZIP central-directory bounds are invalid\");\n }\n if (end >= 20 && view.getUint32(end - 20, true) === 0x07064b50) {\n fail(\"unsupported\", \"ZIP64 archives are unsupported\");\n }\n\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n const names = new Set<string>();\n const entries: BoundedZipEntry[] = [];\n let offset = centralOffset;\n let expandedBytes = 0;\n let compressedBytes = 0;\n for (let index = 0; index < entryCount; index += 1) {\n ensureRange(bytes, offset, 46, fail, \"ZIP central-directory entry\");\n if (view.getUint32(offset, true) !== 0x02014b50) {\n fail(\"invalid\", \"ZIP central-directory signature is invalid\");\n }\n const flags = view.getUint16(offset + 8, true);\n const compression = view.getUint16(offset + 10, true);\n const checksum = view.getUint32(offset + 16, true);\n const compressedSize = view.getUint32(offset + 20, true);\n const expandedSize = view.getUint32(offset + 24, true);\n const nameLength = view.getUint16(offset + 28, true);\n const extraLength = view.getUint16(offset + 30, true);\n const commentLength = view.getUint16(offset + 32, true);\n const startDisk = view.getUint16(offset + 34, true);\n const localHeaderOffset = view.getUint32(offset + 42, true);\n const recordLength = 46 + nameLength + extraLength + commentLength;\n ensureRange(bytes, offset, recordLength, fail, \"ZIP central-directory entry\");\n if (offset + recordLength > centralOffset + centralSize) {\n fail(\"invalid\", \"ZIP central-directory entry is out of bounds\");\n }\n if (startDisk !== 0) fail(\"unsupported\", \"Multi-disk ZIP entries are unsupported\");\n if ((flags & 0x0041) !== 0) fail(\"encrypted\", \"Encrypted ZIP entries are unsupported\");\n if ((flags & ~0x080e) !== 0 || (compression === 0 && (flags & 0x0006) !== 0)) {\n fail(\"unsupported\", \"ZIP entry flags are unsupported\");\n }\n if (compression !== 0 && compression !== 8) {\n fail(\"unsupported\", `ZIP compression method ${compression} is unsupported`);\n }\n if (\n compressedSize === 0xffffffff ||\n expandedSize === 0xffffffff ||\n localHeaderOffset === 0xffffffff\n ) {\n fail(\"unsupported\", \"ZIP64 entries are unsupported\");\n }\n rejectZip64Extra(\n bytes.subarray(offset + 46 + nameLength, offset + 46 + nameLength + extraLength),\n fail,\n );\n let name: string;\n try {\n name = decoder.decode(bytes.subarray(offset + 46, offset + 46 + nameLength));\n } catch {\n fail(\"invalid\", \"ZIP entry name is not valid UTF-8\");\n }\n validatePath(name, fail);\n const collisionKey = name.normalize(\"NFC\").toLowerCase();\n if (names.has(collisionKey))\n fail(\"invalid\", \"ZIP contains duplicate normalized entry names\", name);\n names.add(collisionKey);\n if (compressedSize > limits.compressedEntryBytes)\n fail(\"limit\", \"ZIP entry exceeds its compressed-size limit\", name);\n if (expandedSize > limits.expandedEntryBytes)\n fail(\"limit\", \"ZIP entry exceeds its expanded-size limit\", name);\n if (compressedSize === 0 && expandedSize !== 0)\n fail(\"invalid\", \"ZIP entry has impossible sizes\", name);\n if (\n expandedSize > (limits.compressionRatioThreshold ?? 0) &&\n expandedSize / Math.max(1, compressedSize) > limits.compressionRatio\n )\n fail(\"limit\", \"ZIP entry exceeds its compression-ratio limit\", name);\n expandedBytes += expandedSize;\n compressedBytes += compressedSize;\n if (expandedBytes > limits.expandedBytes) fail(\"limit\", \"ZIP exceeds its expanded-size limit\");\n if (\n expandedBytes > (limits.compressionRatioThreshold ?? 0) &&\n expandedBytes / Math.max(1, compressedBytes) > limits.compressionRatio\n ) {\n fail(\"limit\", \"ZIP exceeds its aggregate compression-ratio limit\", name);\n }\n\n const entry = localBounds(\n bytes,\n view,\n decoder,\n {\n name,\n flags,\n compression,\n checksum,\n compressedSize,\n expandedSize,\n localHeaderOffset,\n directory: name.endsWith(\"/\"),\n },\n centralOffset,\n fail,\n );\n entries.push(entry);\n offset += recordLength;\n }\n if (offset !== centralOffset + centralSize)\n fail(\"invalid\", \"ZIP central-directory size is inconsistent\");\n const localOrder = [...entries].sort(\n (left, right) => left.localHeaderOffset - right.localHeaderOffset,\n );\n for (let index = 1; index < localOrder.length; index += 1) {\n const previous = localOrder[index - 1]!;\n const current = localOrder[index]!;\n if (previous.recordEnd > current.localHeaderOffset) {\n fail(\"invalid\", `ZIP local entries overlap: ${previous.name}`, current.name);\n }\n }\n return entries;\n}\n\nasync function consumeZipEntry(\n archive: Uint8Array,\n entry: BoundedZipEntry,\n maximumBytes: number,\n fail: BoundedZipFailure,\n collect: boolean,\n): Promise<Uint8Array | undefined> {\n if (entry.expandedSize > maximumBytes) {\n fail(\"limit\", \"ZIP entry exceeds its configured expanded-size limit\", entry.name);\n }\n const compressed = archive.subarray(entry.dataStart, entry.dataEnd);\n if (entry.compression === 0) {\n if (compressed.byteLength !== entry.expandedSize || zipCrc32(compressed) !== entry.checksum) {\n fail(\"invalid\", \"ZIP entry failed size or checksum validation\", entry.name);\n }\n return collect ? compressed.slice() : undefined;\n }\n if (typeof DecompressionStream === \"undefined\") {\n return inflateWithNode(compressed, entry, fail, collect);\n }\n let stream: ReadableStream<Uint8Array>;\n try {\n stream = new Blob([Uint8Array.from(compressed)])\n .stream()\n .pipeThrough(new DecompressionStream(\"deflate-raw\"));\n } catch {\n return inflateWithNode(compressed, entry, fail, collect);\n }\n const output = collect ? new Uint8Array(entry.expandedSize) : undefined;\n const reader = stream.getReader();\n let offset = 0;\n let checksum = 0xffffffff;\n try {\n while (true) {\n const result = await reader\n .read()\n .catch(() => fail(\"invalid\", \"DEFLATE stream is invalid\", entry.name));\n if (result.done) break;\n if (offset + result.value.byteLength > entry.expandedSize) {\n await reader.cancel().catch(() => undefined);\n fail(\"limit\", \"Inflated ZIP entry exceeds its declared or configured size\", entry.name);\n }\n output?.set(result.value, offset);\n offset += result.value.byteLength;\n checksum = zipCrc32Update(checksum, result.value);\n }\n } finally {\n reader.releaseLock();\n }\n if (offset !== entry.expandedSize || (checksum ^ 0xffffffff) >>> 0 !== entry.checksum) {\n fail(\"invalid\", \"ZIP entry failed size or checksum validation\", entry.name);\n }\n return output;\n}\n\nasync function inflateWithNode(\n compressed: Uint8Array,\n entry: BoundedZipEntry,\n fail: BoundedZipFailure,\n collect: boolean,\n): Promise<Uint8Array | undefined> {\n if (typeof process === \"undefined\" || !process.versions?.node) {\n fail(\"platform\", \"Raw DEFLATE is unavailable\", entry.name);\n }\n try {\n const { inflateRawSync } = await loadNodeZlib();\n const output = inflateRawSync(compressed, { maxOutputLength: entry.expandedSize });\n if (output.byteLength !== entry.expandedSize || zipCrc32(output) !== entry.checksum) {\n fail(\"invalid\", \"ZIP entry failed size or checksum validation\", entry.name);\n }\n return collect ? Uint8Array.from(output) : undefined;\n } catch (error) {\n if ((error as { code?: string }).code === \"ERR_BUFFER_TOO_LARGE\") {\n fail(\"limit\", \"Inflated ZIP entry exceeds its declared or configured size\", entry.name);\n }\n fail(\"invalid\", \"DEFLATE stream is invalid\", entry.name);\n }\n}\n\nasync function loadNodeZlib(): Promise<typeof import(\"node:zlib\")> {\n // Literal dynamic imports are still resolved and polyfilled by browser\n // bundlers. Keep the fallback available to Node/Bun without granting the\n // browser codec graph an eager Node compatibility closure.\n return importRuntimeModule<typeof import(\"node:zlib\")>(\"node:zlib\");\n}\n\nfunction importRuntimeModule<T>(specifier: string): Promise<T> {\n return import(/* @vite-ignore */ specifier) as Promise<T>;\n}\n\nexport async function inflateBoundedZipEntry(\n archive: Uint8Array,\n entry: BoundedZipEntry,\n maximumBytes: number,\n fail: BoundedZipFailure,\n): Promise<Uint8Array> {\n return (await consumeZipEntry(archive, entry, maximumBytes, fail, true))!;\n}\n\nexport async function verifyBoundedZipEntry(\n archive: Uint8Array,\n entry: BoundedZipEntry,\n maximumBytes: number,\n fail: BoundedZipFailure,\n): Promise<void> {\n await consumeZipEntry(archive, entry, maximumBytes, fail, false);\n}\n\nfunction findEndRecord(view: DataView, fail: BoundedZipFailure): number {\n const minimum = Math.max(0, view.byteLength - 65_557);\n for (let offset = view.byteLength - 22; offset >= minimum; offset -= 1) {\n if (\n view.getUint32(offset, true) === 0x06054b50 &&\n offset + 22 + view.getUint16(offset + 20, true) === view.byteLength\n )\n return offset;\n }\n return fail(\"invalid\", \"ZIP end record is missing\");\n}\n\nfunction localBounds(\n bytes: Uint8Array,\n view: DataView,\n decoder: TextDecoder,\n entry: Omit<BoundedZipEntry, \"dataStart\" | \"dataEnd\" | \"recordEnd\">,\n centralOffset: number,\n fail: BoundedZipFailure,\n): BoundedZipEntry {\n const header = entry.localHeaderOffset;\n ensureRange(bytes, header, 30, fail, \"ZIP local header\", entry.name);\n if (header + 30 > centralOffset || view.getUint32(header, true) !== 0x04034b50) {\n fail(\"invalid\", \"ZIP local-file header is invalid\", entry.name);\n }\n const flags = view.getUint16(header + 6, true);\n const compression = view.getUint16(header + 8, true);\n if (flags !== entry.flags || compression !== entry.compression) {\n fail(\"invalid\", \"ZIP local and central entry metadata disagree\", entry.name);\n }\n const checksum = view.getUint32(header + 14, true);\n const compressedSize = view.getUint32(header + 18, true);\n const expandedSize = view.getUint32(header + 22, true);\n const descriptor = (entry.flags & 0x0008) !== 0;\n if (\n (!descriptor &&\n (checksum !== entry.checksum ||\n compressedSize !== entry.compressedSize ||\n expandedSize !== entry.expandedSize)) ||\n (descriptor &&\n ((checksum !== 0 && checksum !== entry.checksum) ||\n (compressedSize !== 0 && compressedSize !== entry.compressedSize) ||\n (expandedSize !== 0 && expandedSize !== entry.expandedSize)))\n )\n fail(\"invalid\", \"ZIP local and central sizes or checksum disagree\", entry.name);\n const nameLength = view.getUint16(header + 26, true);\n const extraLength = view.getUint16(header + 28, true);\n const nameStart = header + 30;\n const nameEnd = nameStart + nameLength;\n ensureRange(\n bytes,\n header,\n 30 + nameLength + extraLength + entry.compressedSize,\n fail,\n \"ZIP local entry\",\n entry.name,\n );\n let localName: string;\n try {\n localName = decoder.decode(bytes.subarray(nameStart, nameEnd));\n } catch {\n fail(\"invalid\", \"ZIP local entry name is not valid UTF-8\", entry.name);\n }\n if (localName !== entry.name)\n fail(\"invalid\", \"ZIP local and central entry names disagree\", entry.name);\n const dataStart = nameEnd + extraLength;\n const payloadEnd = dataStart + entry.compressedSize;\n rejectZip64Extra(bytes.subarray(nameEnd, dataStart), fail, entry.name);\n let recordEnd = payloadEnd;\n if (descriptor) recordEnd = validateDescriptor(bytes, view, recordEnd, entry, fail);\n if (dataStart < nameEnd || recordEnd > centralOffset) {\n fail(\"invalid\", \"ZIP entry data is outside the local-file area\", entry.name);\n }\n if (entry.directory && (entry.compressedSize !== 0 || entry.expandedSize !== 0)) {\n fail(\"invalid\", \"ZIP directory entry contains data\", entry.name);\n }\n return { ...entry, dataStart, dataEnd: payloadEnd, recordEnd };\n}\n\nfunction validateDescriptor(\n bytes: Uint8Array,\n view: DataView,\n offset: number,\n entry: Omit<BoundedZipEntry, \"dataStart\" | \"dataEnd\" | \"recordEnd\">,\n fail: BoundedZipFailure,\n): number {\n ensureRange(bytes, offset, 12, fail, \"ZIP data descriptor\", entry.name);\n const matches = (start: number): boolean =>\n start + 12 <= bytes.byteLength &&\n view.getUint32(start, true) === entry.checksum &&\n view.getUint32(start + 4, true) === entry.compressedSize &&\n view.getUint32(start + 8, true) === entry.expandedSize;\n if (matches(offset)) return offset + 12;\n if (view.getUint32(offset, true) === 0x08074b50 && matches(offset + 4)) return offset + 16;\n return fail(\"invalid\", \"ZIP data descriptor disagrees with central directory\", entry.name);\n}\n\nfunction rejectZip64Extra(extra: Uint8Array, fail: BoundedZipFailure, entryName?: string): void {\n const view = new DataView(extra.buffer, extra.byteOffset, extra.byteLength);\n let offset = 0;\n while (offset < extra.byteLength) {\n if (offset + 4 > extra.byteLength) fail(\"invalid\", \"ZIP extra field is malformed\", entryName);\n const id = view.getUint16(offset, true);\n const size = view.getUint16(offset + 2, true);\n if (offset + 4 + size > extra.byteLength)\n fail(\"invalid\", \"ZIP extra field is malformed\", entryName);\n if (id === 0x0001) fail(\"unsupported\", \"ZIP64 entries are unsupported\", entryName);\n offset += 4 + size;\n }\n}\n\nfunction validatePath(name: string, fail: BoundedZipFailure): void {\n if (\n name.length === 0 ||\n name.length > 1_024 ||\n /[\\u0000-\\u001f\\u007f]/.test(name) ||\n name.includes(\"\\\\\") ||\n name.startsWith(\"/\") ||\n /^[A-Za-z]:/.test(name) ||\n /%(?:2e|2f|5c)/i.test(name)\n )\n fail(\"invalid\", \"ZIP entry path is unsafe\", name);\n const segments = name.split(\"/\");\n if (\n segments.some(\n (segment, index) =>\n segment === \".\" || segment === \"..\" || (segment === \"\" && index !== segments.length - 1),\n )\n ) {\n fail(\"invalid\", \"ZIP entry path is unsafe\", name);\n }\n}\n\nfunction ensureRange(\n bytes: Uint8Array,\n offset: number,\n length: number,\n fail: BoundedZipFailure,\n description: string,\n entryName?: string,\n): void {\n if (\n !Number.isSafeInteger(offset) ||\n !Number.isSafeInteger(length) ||\n offset < 0 ||\n length < 0 ||\n offset + length > bytes.byteLength\n ) {\n fail(\"invalid\", `${description} is out of bounds`, entryName);\n }\n}\n\nlet crcTable: Uint32Array | undefined;\n\nexport function zipCrc32Update(initial: number, bytes: Uint8Array): number {\n if (!crcTable) {\n crcTable = new Uint32Array(256);\n for (let index = 0; index < 256; index += 1) {\n let value = index;\n for (let bit = 0; bit < 8; bit += 1)\n value = (value & 1) !== 0 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;\n crcTable[index] = value >>> 0;\n }\n }\n let value = initial;\n for (const byte of bytes) value = (crcTable[(value ^ byte) & 0xff] ?? 0) ^ (value >>> 8);\n return value >>> 0;\n}\n\nexport function zipCrc32(bytes: Uint8Array): number {\n return (zipCrc32Update(0xffffffff, bytes) ^ 0xffffffff) >>> 0;\n}\n"],"mappings":"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","names":["value"]}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ArtifactRuntimeError
|
|
3
|
+
} from "./chunk-N2IHNWBS.js";
|
|
4
|
+
|
|
5
|
+
// src/native.ts
|
|
6
|
+
import {
|
|
7
|
+
EDITABLE_ARTIFACT_INTENT_VERSION,
|
|
8
|
+
SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
9
|
+
assertCanonicalSpreadsheetArtifactCommandBytes,
|
|
10
|
+
decodeEditableArtifactMutationIntent,
|
|
11
|
+
encodeEditableArtifactMutationIntent,
|
|
12
|
+
encodeSpreadsheetArtifactCommandBatch,
|
|
13
|
+
hashEditableArtifactMutationIntentBytes
|
|
14
|
+
} from "@opengeni/contracts/editable-artifacts";
|
|
15
|
+
import {
|
|
16
|
+
SPREADSHEET_ARTIFACT_COMMAND_VERSION as SPREADSHEET_ARTIFACT_COMMAND_VERSION2,
|
|
17
|
+
assertCanonicalSpreadsheetArtifactCommandBytes as assertCanonicalSpreadsheetArtifactCommandBytes2,
|
|
18
|
+
decodeSpreadsheetArtifactCommandBatch,
|
|
19
|
+
editableArtifactStableId,
|
|
20
|
+
encodeSpreadsheetArtifactCommandBatch as encodeSpreadsheetArtifactCommandBatch2,
|
|
21
|
+
spreadsheetSheetId
|
|
22
|
+
} from "@opengeni/contracts/editable-artifacts";
|
|
23
|
+
var NativeSpreadsheetSession = class _NativeSpreadsheetSession {
|
|
24
|
+
constructor(runtime, session) {
|
|
25
|
+
this.runtime = runtime;
|
|
26
|
+
this.session = session;
|
|
27
|
+
requireNativeSpreadsheetRuntime(runtime);
|
|
28
|
+
this.target = runtime.target;
|
|
29
|
+
this.capabilities = runtime.capabilities;
|
|
30
|
+
this.buildIdentity = runtime.buildIdentity;
|
|
31
|
+
}
|
|
32
|
+
kind = "native";
|
|
33
|
+
modality = "spreadsheet";
|
|
34
|
+
target;
|
|
35
|
+
capabilities;
|
|
36
|
+
buildIdentity;
|
|
37
|
+
static create(runtime, replicaNamespace) {
|
|
38
|
+
requireNativeSpreadsheetRuntime(runtime);
|
|
39
|
+
return new _NativeSpreadsheetSession(
|
|
40
|
+
runtime,
|
|
41
|
+
runtime.createCollaborationSession(replicaNamespace)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
static open(runtime, snapshot) {
|
|
45
|
+
requireNativeSpreadsheetRuntime(runtime);
|
|
46
|
+
return new _NativeSpreadsheetSession(runtime, runtime.openCollaborationSession(snapshot));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Authors one already-canonical mutation. Rust independently validates the
|
|
50
|
+
* exact OGATX/OGASC bytes, resolves typed operations, applies atomically, and
|
|
51
|
+
* returns the whole canonical OGACO transaction.
|
|
52
|
+
*/
|
|
53
|
+
authorTransaction(intentBytes, resolvedBaseBytes) {
|
|
54
|
+
assertSpreadsheetIntent(intentBytes);
|
|
55
|
+
return this.session.authorTransaction(intentBytes, resolvedBaseBytes);
|
|
56
|
+
}
|
|
57
|
+
/** Encodes one identity-free typed command batch and authors it atomically. */
|
|
58
|
+
authorCommands(input) {
|
|
59
|
+
const commandBytes = encodeSpreadsheetArtifactCommandBatch(input.commands);
|
|
60
|
+
const intentBytes = encodeEditableArtifactMutationIntent({
|
|
61
|
+
...input.intent,
|
|
62
|
+
envelopeVersion: EDITABLE_ARTIFACT_INTENT_VERSION,
|
|
63
|
+
protocolVersion: 1,
|
|
64
|
+
modelSchemaVersion: 1,
|
|
65
|
+
commandProtocolVersion: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
66
|
+
commandBytes
|
|
67
|
+
});
|
|
68
|
+
const requestHash = hashEditableArtifactMutationIntentBytes(intentBytes);
|
|
69
|
+
const committedTransactionBytes = this.authorTransaction(intentBytes, input.resolvedBaseBytes);
|
|
70
|
+
return Object.freeze({ intentBytes, requestHash, committedTransactionBytes });
|
|
71
|
+
}
|
|
72
|
+
/** Replays one whole authoritative OGACO transaction atomically. */
|
|
73
|
+
applyCommitted(committedTransactionBytes) {
|
|
74
|
+
this.session.applyCommitted(committedTransactionBytes);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Executes one canonical OGAKQ request. Typed viewport/metadata helpers use
|
|
78
|
+
* the shared contract codec; this raw method remains useful at server byte
|
|
79
|
+
* boundaries and never exposes a Rust object layout.
|
|
80
|
+
*/
|
|
81
|
+
query(queryBytes) {
|
|
82
|
+
return this.session.query(queryBytes);
|
|
83
|
+
}
|
|
84
|
+
snapshot() {
|
|
85
|
+
return this.session.snapshot();
|
|
86
|
+
}
|
|
87
|
+
frontier() {
|
|
88
|
+
return this.session.frontier();
|
|
89
|
+
}
|
|
90
|
+
stateHash() {
|
|
91
|
+
return this.session.stateHash();
|
|
92
|
+
}
|
|
93
|
+
revision() {
|
|
94
|
+
return this.session.revision();
|
|
95
|
+
}
|
|
96
|
+
fork() {
|
|
97
|
+
return new _NativeSpreadsheetSession(this.runtime, this.session.fork());
|
|
98
|
+
}
|
|
99
|
+
isClosed() {
|
|
100
|
+
return this.session.isClosed();
|
|
101
|
+
}
|
|
102
|
+
dispose() {
|
|
103
|
+
this.session.dispose();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var NativeDocumentSession = class _NativeDocumentSession {
|
|
107
|
+
constructor(runtime, session) {
|
|
108
|
+
this.runtime = runtime;
|
|
109
|
+
this.session = session;
|
|
110
|
+
requireNativeRuntime(runtime);
|
|
111
|
+
this.target = runtime.target;
|
|
112
|
+
this.capabilities = runtime.capabilities;
|
|
113
|
+
this.buildIdentity = runtime.buildIdentity;
|
|
114
|
+
}
|
|
115
|
+
kind = "native";
|
|
116
|
+
modality = "document";
|
|
117
|
+
target;
|
|
118
|
+
capabilities;
|
|
119
|
+
buildIdentity;
|
|
120
|
+
static create(runtime, namespace) {
|
|
121
|
+
requireNativeRuntime(runtime);
|
|
122
|
+
return new _NativeDocumentSession(runtime, runtime.createDocumentSession(namespace));
|
|
123
|
+
}
|
|
124
|
+
static open(runtime, snapshot) {
|
|
125
|
+
requireNativeRuntime(runtime);
|
|
126
|
+
return new _NativeDocumentSession(runtime, runtime.openDocumentSession(snapshot));
|
|
127
|
+
}
|
|
128
|
+
applyCommands(commands) {
|
|
129
|
+
return this.session.applyCommands(commands);
|
|
130
|
+
}
|
|
131
|
+
query(request) {
|
|
132
|
+
return this.session.query(request);
|
|
133
|
+
}
|
|
134
|
+
snapshot() {
|
|
135
|
+
return this.session.snapshot();
|
|
136
|
+
}
|
|
137
|
+
revision() {
|
|
138
|
+
return this.session.revision();
|
|
139
|
+
}
|
|
140
|
+
stateHash() {
|
|
141
|
+
return this.session.stateHash();
|
|
142
|
+
}
|
|
143
|
+
fork() {
|
|
144
|
+
return new _NativeDocumentSession(this.runtime, this.session.fork());
|
|
145
|
+
}
|
|
146
|
+
isClosed() {
|
|
147
|
+
return this.session.isClosed();
|
|
148
|
+
}
|
|
149
|
+
dispose() {
|
|
150
|
+
this.session.dispose();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var NativePresentationSession = class _NativePresentationSession {
|
|
154
|
+
constructor(runtime, session) {
|
|
155
|
+
this.runtime = runtime;
|
|
156
|
+
this.session = session;
|
|
157
|
+
requireNativeRuntime(runtime);
|
|
158
|
+
this.target = runtime.target;
|
|
159
|
+
this.capabilities = runtime.capabilities;
|
|
160
|
+
this.buildIdentity = runtime.buildIdentity;
|
|
161
|
+
}
|
|
162
|
+
kind = "native";
|
|
163
|
+
modality = "presentation";
|
|
164
|
+
target;
|
|
165
|
+
capabilities;
|
|
166
|
+
buildIdentity;
|
|
167
|
+
static create(runtime, namespace) {
|
|
168
|
+
requireNativeRuntime(runtime);
|
|
169
|
+
return new _NativePresentationSession(runtime, runtime.createPresentationSession(namespace));
|
|
170
|
+
}
|
|
171
|
+
static open(runtime, snapshot) {
|
|
172
|
+
requireNativeRuntime(runtime);
|
|
173
|
+
return new _NativePresentationSession(runtime, runtime.openPresentationSession(snapshot));
|
|
174
|
+
}
|
|
175
|
+
applyCommands(commands) {
|
|
176
|
+
return this.session.applyCommands(commands);
|
|
177
|
+
}
|
|
178
|
+
query(request) {
|
|
179
|
+
return this.session.query(request);
|
|
180
|
+
}
|
|
181
|
+
snapshot() {
|
|
182
|
+
return this.session.snapshot();
|
|
183
|
+
}
|
|
184
|
+
revision() {
|
|
185
|
+
return this.session.revision();
|
|
186
|
+
}
|
|
187
|
+
stateHash() {
|
|
188
|
+
return this.session.stateHash();
|
|
189
|
+
}
|
|
190
|
+
fork() {
|
|
191
|
+
return new _NativePresentationSession(this.runtime, this.session.fork());
|
|
192
|
+
}
|
|
193
|
+
isClosed() {
|
|
194
|
+
return this.session.isClosed();
|
|
195
|
+
}
|
|
196
|
+
dispose() {
|
|
197
|
+
this.session.dispose();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
var NativeTextLayoutSession = class _NativeTextLayoutSession {
|
|
201
|
+
constructor(session, runtime) {
|
|
202
|
+
this.session = session;
|
|
203
|
+
requireNativeRuntime(runtime);
|
|
204
|
+
this.target = runtime.target;
|
|
205
|
+
this.capabilities = runtime.capabilities;
|
|
206
|
+
this.buildIdentity = runtime.buildIdentity;
|
|
207
|
+
}
|
|
208
|
+
kind = "native";
|
|
209
|
+
modality = "text-layout";
|
|
210
|
+
target;
|
|
211
|
+
capabilities;
|
|
212
|
+
buildIdentity;
|
|
213
|
+
static open(runtime, fontBundle) {
|
|
214
|
+
requireNativeRuntime(runtime);
|
|
215
|
+
return new _NativeTextLayoutSession(runtime.openTextLayoutSession(fontBundle), runtime);
|
|
216
|
+
}
|
|
217
|
+
layout(request) {
|
|
218
|
+
return this.session.layout(request);
|
|
219
|
+
}
|
|
220
|
+
isClosed() {
|
|
221
|
+
return this.session.isClosed();
|
|
222
|
+
}
|
|
223
|
+
dispose() {
|
|
224
|
+
this.session.dispose();
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
function createNativeArtifactSession(runtime, input) {
|
|
228
|
+
if (input.modality === "spreadsheet") {
|
|
229
|
+
return NativeSpreadsheetSession.create(runtime, input.replicaNamespace);
|
|
230
|
+
}
|
|
231
|
+
if (input.modality === "document") {
|
|
232
|
+
return NativeDocumentSession.create(runtime, input.replicaNamespace);
|
|
233
|
+
}
|
|
234
|
+
return NativePresentationSession.create(runtime, input.replicaNamespace);
|
|
235
|
+
}
|
|
236
|
+
function openNativeArtifactSession(runtime, input) {
|
|
237
|
+
if (input.modality === "spreadsheet")
|
|
238
|
+
return NativeSpreadsheetSession.open(runtime, input.snapshot);
|
|
239
|
+
if (input.modality === "document") return NativeDocumentSession.open(runtime, input.snapshot);
|
|
240
|
+
return NativePresentationSession.open(runtime, input.snapshot);
|
|
241
|
+
}
|
|
242
|
+
function assertSpreadsheetIntent(intentBytes) {
|
|
243
|
+
const intent = decodeEditableArtifactMutationIntent(intentBytes);
|
|
244
|
+
if (intent.envelopeVersion !== EDITABLE_ARTIFACT_INTENT_VERSION || intent.protocolVersion !== 1 || intent.modelSchemaVersion !== 1 || intent.commandProtocolVersion !== SPREADSHEET_ARTIFACT_COMMAND_VERSION) {
|
|
245
|
+
throw new ArtifactRuntimeError(
|
|
246
|
+
"ARTIFACT_RUNTIME_INCOMPATIBLE",
|
|
247
|
+
"Spreadsheet intent versions do not match the loaded production kernel"
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
assertCanonicalSpreadsheetArtifactCommandBytes(intent.commandBytes);
|
|
251
|
+
hashEditableArtifactMutationIntentBytes(intentBytes);
|
|
252
|
+
}
|
|
253
|
+
function requireNativeSpreadsheetRuntime(runtime) {
|
|
254
|
+
requireNativeRuntime(runtime);
|
|
255
|
+
}
|
|
256
|
+
function requireNativeRuntime(runtime) {
|
|
257
|
+
if (runtime.kind !== "native" || runtime.target === "wasm-web") {
|
|
258
|
+
throw new ArtifactRuntimeError(
|
|
259
|
+
"ARTIFACT_RUNTIME_UNAVAILABLE",
|
|
260
|
+
"NativeSpreadsheetSession requires an exact local N-API kernel; browser editing uses @opengeni/sdk/editable-artifacts"
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export {
|
|
266
|
+
NativeSpreadsheetSession,
|
|
267
|
+
NativeDocumentSession,
|
|
268
|
+
NativePresentationSession,
|
|
269
|
+
NativeTextLayoutSession,
|
|
270
|
+
createNativeArtifactSession,
|
|
271
|
+
openNativeArtifactSession,
|
|
272
|
+
SPREADSHEET_ARTIFACT_COMMAND_VERSION2 as SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
273
|
+
assertCanonicalSpreadsheetArtifactCommandBytes2 as assertCanonicalSpreadsheetArtifactCommandBytes,
|
|
274
|
+
decodeSpreadsheetArtifactCommandBatch,
|
|
275
|
+
editableArtifactStableId,
|
|
276
|
+
encodeSpreadsheetArtifactCommandBatch2 as encodeSpreadsheetArtifactCommandBatch,
|
|
277
|
+
spreadsheetSheetId
|
|
278
|
+
};
|
|
279
|
+
//# sourceMappingURL=chunk-B2ZJRZDA.js.map
|