@runcofactor/cli 0.10.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/README.md +125 -0
- package/dist/api-catalog-GFGCLVS4.js +401 -0
- package/dist/api-catalog-GFGCLVS4.js.map +1 -0
- package/dist/attachment-SJC7D7FY.js +276 -0
- package/dist/attachment-SJC7D7FY.js.map +1 -0
- package/dist/auth-EN6NQCJY.js +31 -0
- package/dist/auth-EN6NQCJY.js.map +1 -0
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-3CZU7XCS.js +272 -0
- package/dist/chunk-3CZU7XCS.js.map +1 -0
- package/dist/chunk-4NRDONSC.js +1048 -0
- package/dist/chunk-4NRDONSC.js.map +1 -0
- package/dist/chunk-4PNOV7OV.js +51980 -0
- package/dist/chunk-4PNOV7OV.js.map +1 -0
- package/dist/chunk-52IO7ACJ.js +2941 -0
- package/dist/chunk-52IO7ACJ.js.map +1 -0
- package/dist/chunk-6LEZCKKV.js +663 -0
- package/dist/chunk-6LEZCKKV.js.map +1 -0
- package/dist/chunk-A4OFTUVV.js +170 -0
- package/dist/chunk-A4OFTUVV.js.map +1 -0
- package/dist/chunk-B2VISN2V.js +2459 -0
- package/dist/chunk-B2VISN2V.js.map +1 -0
- package/dist/chunk-CLAWT7BJ.js +271 -0
- package/dist/chunk-CLAWT7BJ.js.map +1 -0
- package/dist/chunk-GKY2KXO5.js +281 -0
- package/dist/chunk-GKY2KXO5.js.map +1 -0
- package/dist/chunk-I4QLI3JO.js +413 -0
- package/dist/chunk-I4QLI3JO.js.map +1 -0
- package/dist/chunk-IMPZAX6L.js +180 -0
- package/dist/chunk-IMPZAX6L.js.map +1 -0
- package/dist/chunk-J6SH7GQT.js +241 -0
- package/dist/chunk-J6SH7GQT.js.map +1 -0
- package/dist/chunk-JDBCZ3Z2.js +298 -0
- package/dist/chunk-JDBCZ3Z2.js.map +1 -0
- package/dist/chunk-JICSYFRJ.js +46 -0
- package/dist/chunk-JICSYFRJ.js.map +1 -0
- package/dist/chunk-JWHYXEA2.js +32 -0
- package/dist/chunk-JWHYXEA2.js.map +1 -0
- package/dist/chunk-N7HFALX3.js +88 -0
- package/dist/chunk-N7HFALX3.js.map +1 -0
- package/dist/chunk-Q4BO4Z5V.js +178 -0
- package/dist/chunk-Q4BO4Z5V.js.map +1 -0
- package/dist/chunk-QFDOWABX.js +195 -0
- package/dist/chunk-QFDOWABX.js.map +1 -0
- package/dist/chunk-SJJW77WN.js +605 -0
- package/dist/chunk-SJJW77WN.js.map +1 -0
- package/dist/chunk-VKVL7WBN.js +50 -0
- package/dist/chunk-VKVL7WBN.js.map +1 -0
- package/dist/chunk-WOHL4FTB.js +353 -0
- package/dist/chunk-WOHL4FTB.js.map +1 -0
- package/dist/chunk-XQXVG7RA.js +426 -0
- package/dist/chunk-XQXVG7RA.js.map +1 -0
- package/dist/chunk-ZD3KHESI.js +94 -0
- package/dist/chunk-ZD3KHESI.js.map +1 -0
- package/dist/credential-COLTBV6D.js +450 -0
- package/dist/credential-COLTBV6D.js.map +1 -0
- package/dist/credential-template-EEPYFG7R.js +291 -0
- package/dist/credential-template-EEPYFG7R.js.map +1 -0
- package/dist/debug-workflow-KOVH5GOP.js +259 -0
- package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
- package/dist/dist-44PZR7BQ.js +423 -0
- package/dist/dist-44PZR7BQ.js.map +1 -0
- package/dist/docs-3SSORHB5.js +366 -0
- package/dist/docs-3SSORHB5.js.map +1 -0
- package/dist/doctor-OTSIWV6G.js +132 -0
- package/dist/doctor-OTSIWV6G.js.map +1 -0
- package/dist/feature-flag-T2LRZME3.js +283 -0
- package/dist/feature-flag-T2LRZME3.js.map +1 -0
- package/dist/file-type-S3UUBVCT.js +4205 -0
- package/dist/file-type-S3UUBVCT.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +982 -0
- package/dist/index.js.map +1 -0
- package/dist/init-TGWRECT2.js +208 -0
- package/dist/init-TGWRECT2.js.map +1 -0
- package/dist/install-DXSNWZKO.js +295 -0
- package/dist/install-DXSNWZKO.js.map +1 -0
- package/dist/issues-XIZOPX6T.js +564 -0
- package/dist/issues-XIZOPX6T.js.map +1 -0
- package/dist/knobs-NBINZIUB.js +295 -0
- package/dist/knobs-NBINZIUB.js.map +1 -0
- package/dist/list-3TDHK637.js +59 -0
- package/dist/list-3TDHK637.js.map +1 -0
- package/dist/local-HICVD6PU.js +100 -0
- package/dist/local-HICVD6PU.js.map +1 -0
- package/dist/login-UOIUXVUK.js +315 -0
- package/dist/login-UOIUXVUK.js.map +1 -0
- package/dist/mcp-54IJEOUA.js +1956 -0
- package/dist/mcp-54IJEOUA.js.map +1 -0
- package/dist/pdf-extract-ABWV3L5X.js +13 -0
- package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
- package/dist/pdfjs-DQ2YA5S3.js +41561 -0
- package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
- package/dist/property-UXLOLPTD.js +701 -0
- package/dist/property-UXLOLPTD.js.map +1 -0
- package/dist/property-skill-guide.md +189 -0
- package/dist/psql-BYUUNLGG.js +115 -0
- package/dist/psql-BYUUNLGG.js.map +1 -0
- package/dist/record-4TR2UIIS.js +233 -0
- package/dist/record-4TR2UIIS.js.map +1 -0
- package/dist/redis-35VBUYW7.js +116 -0
- package/dist/redis-35VBUYW7.js.map +1 -0
- package/dist/release-OOLTUBUT.js +354 -0
- package/dist/release-OOLTUBUT.js.map +1 -0
- package/dist/sandbox-XGSUU6G7.js +2046 -0
- package/dist/sandbox-XGSUU6G7.js.map +1 -0
- package/dist/scenarios-GWLJEGHA.js +280 -0
- package/dist/scenarios-GWLJEGHA.js.map +1 -0
- package/dist/session-MYFNZPRP.js +2414 -0
- package/dist/session-MYFNZPRP.js.map +1 -0
- package/dist/skill-KM34LDMO.js +1839 -0
- package/dist/skill-KM34LDMO.js.map +1 -0
- package/dist/skills/debug-run/SKILL.md +262 -0
- package/dist/skills/debug-run/history/1.0.0.md +244 -0
- package/dist/skills/debug-run/history/1.0.1.md +245 -0
- package/dist/skills/debug-run/history/1.0.2.md +254 -0
- package/dist/skills/debug-run/history/1.1.0.md +262 -0
- package/dist/skills/debug-run/version.json +3 -0
- package/dist/spec-RA3CFEKG.js +951 -0
- package/dist/spec-RA3CFEKG.js.map +1 -0
- package/dist/src-LB4HBTJQ.js +1516 -0
- package/dist/src-LB4HBTJQ.js.map +1 -0
- package/dist/src-N3TPKGTY.js +244 -0
- package/dist/src-N3TPKGTY.js.map +1 -0
- package/dist/src-UVDX5UP6.js +17 -0
- package/dist/src-UVDX5UP6.js.map +1 -0
- package/dist/start-PSEQSQA3.js +151 -0
- package/dist/start-PSEQSQA3.js.map +1 -0
- package/dist/tag-YY6YAABQ.js +22 -0
- package/dist/tag-YY6YAABQ.js.map +1 -0
- package/dist/task-IQC3YR5K.js +922 -0
- package/dist/task-IQC3YR5K.js.map +1 -0
- package/dist/test-suite-DZNJFXDW.js +394 -0
- package/dist/test-suite-DZNJFXDW.js.map +1 -0
- package/dist/trace-HXIW7U2D.js +14 -0
- package/dist/trace-HXIW7U2D.js.map +1 -0
- package/dist/triage-ORG45R5W.js +16 -0
- package/dist/triage-ORG45R5W.js.map +1 -0
- package/dist/upgrade-L2VYMP2V.js +61 -0
- package/dist/upgrade-L2VYMP2V.js.map +1 -0
- package/dist/workflow-XYFH5LTP.js +3708 -0
- package/dist/workflow-XYFH5LTP.js.map +1 -0
- package/dist/workflow-cache-NQJQFWMV.js +253 -0
- package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
- package/dist/workflow-debug-BGD4UIXU.js +927 -0
- package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
- package/dist/workflow-proposals-MTUDX46O.js +382 -0
- package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,4205 @@
|
|
|
1
|
+
import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
require_src
|
|
4
|
+
} from "./chunk-6LEZCKKV.js";
|
|
5
|
+
import {
|
|
6
|
+
__commonJS,
|
|
7
|
+
__toESM
|
|
8
|
+
} from "./chunk-VKVL7WBN.js";
|
|
9
|
+
|
|
10
|
+
// ../../node_modules/.bun/ieee754@1.2.1/node_modules/ieee754/index.js
|
|
11
|
+
var require_ieee754 = __commonJS({
|
|
12
|
+
"../../node_modules/.bun/ieee754@1.2.1/node_modules/ieee754/index.js"(exports) {
|
|
13
|
+
"use strict";
|
|
14
|
+
exports.read = function(buffer, offset, isLE, mLen, nBytes) {
|
|
15
|
+
var e, m;
|
|
16
|
+
var eLen = nBytes * 8 - mLen - 1;
|
|
17
|
+
var eMax = (1 << eLen) - 1;
|
|
18
|
+
var eBias = eMax >> 1;
|
|
19
|
+
var nBits = -7;
|
|
20
|
+
var i = isLE ? nBytes - 1 : 0;
|
|
21
|
+
var d = isLE ? -1 : 1;
|
|
22
|
+
var s = buffer[offset + i];
|
|
23
|
+
i += d;
|
|
24
|
+
e = s & (1 << -nBits) - 1;
|
|
25
|
+
s >>= -nBits;
|
|
26
|
+
nBits += eLen;
|
|
27
|
+
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {
|
|
28
|
+
}
|
|
29
|
+
m = e & (1 << -nBits) - 1;
|
|
30
|
+
e >>= -nBits;
|
|
31
|
+
nBits += mLen;
|
|
32
|
+
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {
|
|
33
|
+
}
|
|
34
|
+
if (e === 0) {
|
|
35
|
+
e = 1 - eBias;
|
|
36
|
+
} else if (e === eMax) {
|
|
37
|
+
return m ? NaN : (s ? -1 : 1) * Infinity;
|
|
38
|
+
} else {
|
|
39
|
+
m = m + Math.pow(2, mLen);
|
|
40
|
+
e = e - eBias;
|
|
41
|
+
}
|
|
42
|
+
return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
|
|
43
|
+
};
|
|
44
|
+
exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
|
|
45
|
+
var e, m, c;
|
|
46
|
+
var eLen = nBytes * 8 - mLen - 1;
|
|
47
|
+
var eMax = (1 << eLen) - 1;
|
|
48
|
+
var eBias = eMax >> 1;
|
|
49
|
+
var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;
|
|
50
|
+
var i = isLE ? 0 : nBytes - 1;
|
|
51
|
+
var d = isLE ? 1 : -1;
|
|
52
|
+
var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;
|
|
53
|
+
value = Math.abs(value);
|
|
54
|
+
if (isNaN(value) || value === Infinity) {
|
|
55
|
+
m = isNaN(value) ? 1 : 0;
|
|
56
|
+
e = eMax;
|
|
57
|
+
} else {
|
|
58
|
+
e = Math.floor(Math.log(value) / Math.LN2);
|
|
59
|
+
if (value * (c = Math.pow(2, -e)) < 1) {
|
|
60
|
+
e--;
|
|
61
|
+
c *= 2;
|
|
62
|
+
}
|
|
63
|
+
if (e + eBias >= 1) {
|
|
64
|
+
value += rt / c;
|
|
65
|
+
} else {
|
|
66
|
+
value += rt * Math.pow(2, 1 - eBias);
|
|
67
|
+
}
|
|
68
|
+
if (value * c >= 2) {
|
|
69
|
+
e++;
|
|
70
|
+
c /= 2;
|
|
71
|
+
}
|
|
72
|
+
if (e + eBias >= eMax) {
|
|
73
|
+
m = 0;
|
|
74
|
+
e = eMax;
|
|
75
|
+
} else if (e + eBias >= 1) {
|
|
76
|
+
m = (value * c - 1) * Math.pow(2, mLen);
|
|
77
|
+
e = e + eBias;
|
|
78
|
+
} else {
|
|
79
|
+
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
|
|
80
|
+
e = 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (; mLen >= 8; buffer[offset + i] = m & 255, i += d, m /= 256, mLen -= 8) {
|
|
84
|
+
}
|
|
85
|
+
e = e << mLen | m;
|
|
86
|
+
eLen += mLen;
|
|
87
|
+
for (; eLen > 0; buffer[offset + i] = e & 255, i += d, e /= 256, eLen -= 8) {
|
|
88
|
+
}
|
|
89
|
+
buffer[offset + i - d] |= s * 128;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// ../../node_modules/.bun/file-type@21.3.4/node_modules/file-type/index.js
|
|
95
|
+
import { ReadableStream as WebReadableStream } from "stream/web";
|
|
96
|
+
import { pipeline, PassThrough, Readable } from "stream";
|
|
97
|
+
import fs from "fs/promises";
|
|
98
|
+
import { constants as fileSystemConstants } from "fs";
|
|
99
|
+
|
|
100
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/index.js
|
|
101
|
+
import { stat as fsStat } from "fs/promises";
|
|
102
|
+
|
|
103
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/Errors.js
|
|
104
|
+
var defaultMessages = "End-Of-Stream";
|
|
105
|
+
var EndOfStreamError = class extends Error {
|
|
106
|
+
constructor() {
|
|
107
|
+
super(defaultMessages);
|
|
108
|
+
this.name = "EndOfStreamError";
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var AbortError = class extends Error {
|
|
112
|
+
constructor(message = "The operation was aborted") {
|
|
113
|
+
super(message);
|
|
114
|
+
this.name = "AbortError";
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/Deferred.js
|
|
119
|
+
var Deferred = class {
|
|
120
|
+
constructor() {
|
|
121
|
+
this.resolve = () => null;
|
|
122
|
+
this.reject = () => null;
|
|
123
|
+
this.promise = new Promise((resolve, reject) => {
|
|
124
|
+
this.reject = reject;
|
|
125
|
+
this.resolve = resolve;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/AbstractStreamReader.js
|
|
131
|
+
var AbstractStreamReader = class {
|
|
132
|
+
constructor() {
|
|
133
|
+
this.endOfStream = false;
|
|
134
|
+
this.interrupted = false;
|
|
135
|
+
this.peekQueue = [];
|
|
136
|
+
}
|
|
137
|
+
async peek(uint8Array, mayBeLess = false) {
|
|
138
|
+
const bytesRead = await this.read(uint8Array, mayBeLess);
|
|
139
|
+
this.peekQueue.push(uint8Array.subarray(0, bytesRead));
|
|
140
|
+
return bytesRead;
|
|
141
|
+
}
|
|
142
|
+
async read(buffer, mayBeLess = false) {
|
|
143
|
+
if (buffer.length === 0) {
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
let bytesRead = this.readFromPeekBuffer(buffer);
|
|
147
|
+
if (!this.endOfStream) {
|
|
148
|
+
bytesRead += await this.readRemainderFromStream(buffer.subarray(bytesRead), mayBeLess);
|
|
149
|
+
}
|
|
150
|
+
if (bytesRead === 0 && !mayBeLess) {
|
|
151
|
+
throw new EndOfStreamError();
|
|
152
|
+
}
|
|
153
|
+
return bytesRead;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Read chunk from stream
|
|
157
|
+
* @param buffer - Target Uint8Array (or Buffer) to store data read from stream in
|
|
158
|
+
* @returns Number of bytes read
|
|
159
|
+
*/
|
|
160
|
+
readFromPeekBuffer(buffer) {
|
|
161
|
+
let remaining = buffer.length;
|
|
162
|
+
let bytesRead = 0;
|
|
163
|
+
while (this.peekQueue.length > 0 && remaining > 0) {
|
|
164
|
+
const peekData = this.peekQueue.pop();
|
|
165
|
+
if (!peekData)
|
|
166
|
+
throw new Error("peekData should be defined");
|
|
167
|
+
const lenCopy = Math.min(peekData.length, remaining);
|
|
168
|
+
buffer.set(peekData.subarray(0, lenCopy), bytesRead);
|
|
169
|
+
bytesRead += lenCopy;
|
|
170
|
+
remaining -= lenCopy;
|
|
171
|
+
if (lenCopy < peekData.length) {
|
|
172
|
+
this.peekQueue.push(peekData.subarray(lenCopy));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return bytesRead;
|
|
176
|
+
}
|
|
177
|
+
async readRemainderFromStream(buffer, mayBeLess) {
|
|
178
|
+
let bytesRead = 0;
|
|
179
|
+
while (bytesRead < buffer.length && !this.endOfStream) {
|
|
180
|
+
if (this.interrupted) {
|
|
181
|
+
throw new AbortError();
|
|
182
|
+
}
|
|
183
|
+
const chunkLen = await this.readFromStream(buffer.subarray(bytesRead), mayBeLess);
|
|
184
|
+
if (chunkLen === 0)
|
|
185
|
+
break;
|
|
186
|
+
bytesRead += chunkLen;
|
|
187
|
+
}
|
|
188
|
+
if (!mayBeLess && bytesRead < buffer.length) {
|
|
189
|
+
throw new EndOfStreamError();
|
|
190
|
+
}
|
|
191
|
+
return bytesRead;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/StreamReader.js
|
|
196
|
+
var StreamReader = class extends AbstractStreamReader {
|
|
197
|
+
constructor(s) {
|
|
198
|
+
super();
|
|
199
|
+
this.s = s;
|
|
200
|
+
this.deferred = null;
|
|
201
|
+
if (!s.read || !s.once) {
|
|
202
|
+
throw new Error("Expected an instance of stream.Readable");
|
|
203
|
+
}
|
|
204
|
+
this.s.once("end", () => {
|
|
205
|
+
this.endOfStream = true;
|
|
206
|
+
if (this.deferred) {
|
|
207
|
+
this.deferred.resolve(0);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
this.s.once("error", (err) => this.reject(err));
|
|
211
|
+
this.s.once("close", () => this.abort());
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Read chunk from stream
|
|
215
|
+
* @param buffer Target Uint8Array (or Buffer) to store data read from stream in
|
|
216
|
+
* @param mayBeLess - If true, may fill the buffer partially
|
|
217
|
+
* @returns Number of bytes read
|
|
218
|
+
*/
|
|
219
|
+
async readFromStream(buffer, mayBeLess) {
|
|
220
|
+
if (buffer.length === 0)
|
|
221
|
+
return 0;
|
|
222
|
+
const readBuffer = this.s.read(buffer.length);
|
|
223
|
+
if (readBuffer) {
|
|
224
|
+
buffer.set(readBuffer);
|
|
225
|
+
return readBuffer.length;
|
|
226
|
+
}
|
|
227
|
+
const request = {
|
|
228
|
+
buffer,
|
|
229
|
+
mayBeLess,
|
|
230
|
+
deferred: new Deferred()
|
|
231
|
+
};
|
|
232
|
+
this.deferred = request.deferred;
|
|
233
|
+
this.s.once("readable", () => {
|
|
234
|
+
this.readDeferred(request);
|
|
235
|
+
});
|
|
236
|
+
return request.deferred.promise;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Process deferred read request
|
|
240
|
+
* @param request Deferred read request
|
|
241
|
+
*/
|
|
242
|
+
readDeferred(request) {
|
|
243
|
+
const readBuffer = this.s.read(request.buffer.length);
|
|
244
|
+
if (readBuffer) {
|
|
245
|
+
request.buffer.set(readBuffer);
|
|
246
|
+
request.deferred.resolve(readBuffer.length);
|
|
247
|
+
this.deferred = null;
|
|
248
|
+
} else {
|
|
249
|
+
this.s.once("readable", () => {
|
|
250
|
+
this.readDeferred(request);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
reject(err) {
|
|
255
|
+
this.interrupted = true;
|
|
256
|
+
if (this.deferred) {
|
|
257
|
+
this.deferred.reject(err);
|
|
258
|
+
this.deferred = null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async abort() {
|
|
262
|
+
this.reject(new AbortError());
|
|
263
|
+
}
|
|
264
|
+
async close() {
|
|
265
|
+
return this.abort();
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/WebStreamReader.js
|
|
270
|
+
var WebStreamReader = class extends AbstractStreamReader {
|
|
271
|
+
constructor(reader) {
|
|
272
|
+
super();
|
|
273
|
+
this.reader = reader;
|
|
274
|
+
}
|
|
275
|
+
async abort() {
|
|
276
|
+
return this.close();
|
|
277
|
+
}
|
|
278
|
+
async close() {
|
|
279
|
+
this.reader.releaseLock();
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/WebStreamByobReader.js
|
|
284
|
+
var WebStreamByobReader = class extends WebStreamReader {
|
|
285
|
+
/**
|
|
286
|
+
* Read from stream
|
|
287
|
+
* @param buffer - Target Uint8Array (or Buffer) to store data read from stream in
|
|
288
|
+
* @param mayBeLess - If true, may fill the buffer partially
|
|
289
|
+
* @protected Bytes read
|
|
290
|
+
*/
|
|
291
|
+
async readFromStream(buffer, mayBeLess) {
|
|
292
|
+
if (buffer.length === 0)
|
|
293
|
+
return 0;
|
|
294
|
+
const result = await this.reader.read(new Uint8Array(buffer.length), { min: mayBeLess ? void 0 : buffer.length });
|
|
295
|
+
if (result.done) {
|
|
296
|
+
this.endOfStream = result.done;
|
|
297
|
+
}
|
|
298
|
+
if (result.value) {
|
|
299
|
+
buffer.set(result.value);
|
|
300
|
+
return result.value.length;
|
|
301
|
+
}
|
|
302
|
+
return 0;
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/WebStreamDefaultReader.js
|
|
307
|
+
var WebStreamDefaultReader = class extends AbstractStreamReader {
|
|
308
|
+
constructor(reader) {
|
|
309
|
+
super();
|
|
310
|
+
this.reader = reader;
|
|
311
|
+
this.buffer = null;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Copy chunk to target, and store the remainder in this.buffer
|
|
315
|
+
*/
|
|
316
|
+
writeChunk(target, chunk) {
|
|
317
|
+
const written = Math.min(chunk.length, target.length);
|
|
318
|
+
target.set(chunk.subarray(0, written));
|
|
319
|
+
if (written < chunk.length) {
|
|
320
|
+
this.buffer = chunk.subarray(written);
|
|
321
|
+
} else {
|
|
322
|
+
this.buffer = null;
|
|
323
|
+
}
|
|
324
|
+
return written;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Read from stream
|
|
328
|
+
* @param buffer - Target Uint8Array (or Buffer) to store data read from stream in
|
|
329
|
+
* @param mayBeLess - If true, may fill the buffer partially
|
|
330
|
+
* @protected Bytes read
|
|
331
|
+
*/
|
|
332
|
+
async readFromStream(buffer, mayBeLess) {
|
|
333
|
+
if (buffer.length === 0)
|
|
334
|
+
return 0;
|
|
335
|
+
let totalBytesRead = 0;
|
|
336
|
+
if (this.buffer) {
|
|
337
|
+
totalBytesRead += this.writeChunk(buffer, this.buffer);
|
|
338
|
+
}
|
|
339
|
+
while (totalBytesRead < buffer.length && !this.endOfStream) {
|
|
340
|
+
const result = await this.reader.read();
|
|
341
|
+
if (result.done) {
|
|
342
|
+
this.endOfStream = true;
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
if (result.value) {
|
|
346
|
+
totalBytesRead += this.writeChunk(buffer.subarray(totalBytesRead), result.value);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (!mayBeLess && totalBytesRead === 0 && this.endOfStream) {
|
|
350
|
+
throw new EndOfStreamError();
|
|
351
|
+
}
|
|
352
|
+
return totalBytesRead;
|
|
353
|
+
}
|
|
354
|
+
abort() {
|
|
355
|
+
this.interrupted = true;
|
|
356
|
+
return this.reader.cancel();
|
|
357
|
+
}
|
|
358
|
+
async close() {
|
|
359
|
+
await this.abort();
|
|
360
|
+
this.reader.releaseLock();
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/stream/WebStreamReaderFactory.js
|
|
365
|
+
function makeWebStreamReader(stream) {
|
|
366
|
+
try {
|
|
367
|
+
const reader = stream.getReader({ mode: "byob" });
|
|
368
|
+
if (reader instanceof ReadableStreamDefaultReader) {
|
|
369
|
+
return new WebStreamDefaultReader(reader);
|
|
370
|
+
}
|
|
371
|
+
return new WebStreamByobReader(reader);
|
|
372
|
+
} catch (error) {
|
|
373
|
+
if (error instanceof TypeError) {
|
|
374
|
+
return new WebStreamDefaultReader(stream.getReader());
|
|
375
|
+
}
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/AbstractTokenizer.js
|
|
381
|
+
var AbstractTokenizer = class {
|
|
382
|
+
/**
|
|
383
|
+
* Constructor
|
|
384
|
+
* @param options Tokenizer options
|
|
385
|
+
* @protected
|
|
386
|
+
*/
|
|
387
|
+
constructor(options) {
|
|
388
|
+
this.numBuffer = new Uint8Array(8);
|
|
389
|
+
this.position = 0;
|
|
390
|
+
this.onClose = options?.onClose;
|
|
391
|
+
if (options?.abortSignal) {
|
|
392
|
+
options.abortSignal.addEventListener("abort", () => {
|
|
393
|
+
this.abort();
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Read a token from the tokenizer-stream
|
|
399
|
+
* @param token - The token to read
|
|
400
|
+
* @param position - If provided, the desired position in the tokenizer-stream
|
|
401
|
+
* @returns Promise with token data
|
|
402
|
+
*/
|
|
403
|
+
async readToken(token, position = this.position) {
|
|
404
|
+
const uint8Array = new Uint8Array(token.len);
|
|
405
|
+
const len = await this.readBuffer(uint8Array, { position });
|
|
406
|
+
if (len < token.len)
|
|
407
|
+
throw new EndOfStreamError();
|
|
408
|
+
return token.get(uint8Array, 0);
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Peek a token from the tokenizer-stream.
|
|
412
|
+
* @param token - Token to peek from the tokenizer-stream.
|
|
413
|
+
* @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position.
|
|
414
|
+
* @returns Promise with token data
|
|
415
|
+
*/
|
|
416
|
+
async peekToken(token, position = this.position) {
|
|
417
|
+
const uint8Array = new Uint8Array(token.len);
|
|
418
|
+
const len = await this.peekBuffer(uint8Array, { position });
|
|
419
|
+
if (len < token.len)
|
|
420
|
+
throw new EndOfStreamError();
|
|
421
|
+
return token.get(uint8Array, 0);
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Read a numeric token from the stream
|
|
425
|
+
* @param token - Numeric token
|
|
426
|
+
* @returns Promise with number
|
|
427
|
+
*/
|
|
428
|
+
async readNumber(token) {
|
|
429
|
+
const len = await this.readBuffer(this.numBuffer, { length: token.len });
|
|
430
|
+
if (len < token.len)
|
|
431
|
+
throw new EndOfStreamError();
|
|
432
|
+
return token.get(this.numBuffer, 0);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Read a numeric token from the stream
|
|
436
|
+
* @param token - Numeric token
|
|
437
|
+
* @returns Promise with number
|
|
438
|
+
*/
|
|
439
|
+
async peekNumber(token) {
|
|
440
|
+
const len = await this.peekBuffer(this.numBuffer, { length: token.len });
|
|
441
|
+
if (len < token.len)
|
|
442
|
+
throw new EndOfStreamError();
|
|
443
|
+
return token.get(this.numBuffer, 0);
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Ignore number of bytes, advances the pointer in under tokenizer-stream.
|
|
447
|
+
* @param length - Number of bytes to ignore. Must be ≥ 0.
|
|
448
|
+
* @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
|
|
449
|
+
*/
|
|
450
|
+
async ignore(length) {
|
|
451
|
+
if (length < 0) {
|
|
452
|
+
throw new RangeError("ignore length must be \u2265 0 bytes");
|
|
453
|
+
}
|
|
454
|
+
if (this.fileInfo.size !== void 0) {
|
|
455
|
+
const bytesLeft = this.fileInfo.size - this.position;
|
|
456
|
+
if (length > bytesLeft) {
|
|
457
|
+
this.position += bytesLeft;
|
|
458
|
+
return bytesLeft;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
this.position += length;
|
|
462
|
+
return length;
|
|
463
|
+
}
|
|
464
|
+
async close() {
|
|
465
|
+
await this.abort();
|
|
466
|
+
await this.onClose?.();
|
|
467
|
+
}
|
|
468
|
+
normalizeOptions(uint8Array, options) {
|
|
469
|
+
if (!this.supportsRandomAccess() && options && options.position !== void 0 && options.position < this.position) {
|
|
470
|
+
throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
...{
|
|
474
|
+
mayBeLess: false,
|
|
475
|
+
offset: 0,
|
|
476
|
+
length: uint8Array.length,
|
|
477
|
+
position: this.position
|
|
478
|
+
},
|
|
479
|
+
...options
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
abort() {
|
|
483
|
+
return Promise.resolve();
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/ReadStreamTokenizer.js
|
|
488
|
+
var maxBufferSize = 256e3;
|
|
489
|
+
var ReadStreamTokenizer = class extends AbstractTokenizer {
|
|
490
|
+
/**
|
|
491
|
+
* Constructor
|
|
492
|
+
* @param streamReader stream-reader to read from
|
|
493
|
+
* @param options Tokenizer options
|
|
494
|
+
*/
|
|
495
|
+
constructor(streamReader, options) {
|
|
496
|
+
super(options);
|
|
497
|
+
this.streamReader = streamReader;
|
|
498
|
+
this.fileInfo = options?.fileInfo ?? {};
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Read buffer from tokenizer
|
|
502
|
+
* @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream
|
|
503
|
+
* @param options - Read behaviour options
|
|
504
|
+
* @returns Promise with number of bytes read
|
|
505
|
+
*/
|
|
506
|
+
async readBuffer(uint8Array, options) {
|
|
507
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
508
|
+
const skipBytes = normOptions.position - this.position;
|
|
509
|
+
if (skipBytes > 0) {
|
|
510
|
+
await this.ignore(skipBytes);
|
|
511
|
+
return this.readBuffer(uint8Array, options);
|
|
512
|
+
}
|
|
513
|
+
if (skipBytes < 0) {
|
|
514
|
+
throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
|
|
515
|
+
}
|
|
516
|
+
if (normOptions.length === 0) {
|
|
517
|
+
return 0;
|
|
518
|
+
}
|
|
519
|
+
const bytesRead = await this.streamReader.read(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
|
|
520
|
+
this.position += bytesRead;
|
|
521
|
+
if ((!options || !options.mayBeLess) && bytesRead < normOptions.length) {
|
|
522
|
+
throw new EndOfStreamError();
|
|
523
|
+
}
|
|
524
|
+
return bytesRead;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Peek (read ahead) buffer from tokenizer
|
|
528
|
+
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
529
|
+
* @param options - Read behaviour options
|
|
530
|
+
* @returns Promise with number of bytes peeked
|
|
531
|
+
*/
|
|
532
|
+
async peekBuffer(uint8Array, options) {
|
|
533
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
534
|
+
let bytesRead = 0;
|
|
535
|
+
if (normOptions.position) {
|
|
536
|
+
const skipBytes = normOptions.position - this.position;
|
|
537
|
+
if (skipBytes > 0) {
|
|
538
|
+
const skipBuffer = new Uint8Array(normOptions.length + skipBytes);
|
|
539
|
+
bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: normOptions.mayBeLess });
|
|
540
|
+
uint8Array.set(skipBuffer.subarray(skipBytes));
|
|
541
|
+
return bytesRead - skipBytes;
|
|
542
|
+
}
|
|
543
|
+
if (skipBytes < 0) {
|
|
544
|
+
throw new Error("Cannot peek from a negative offset in a stream");
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (normOptions.length > 0) {
|
|
548
|
+
try {
|
|
549
|
+
bytesRead = await this.streamReader.peek(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
|
|
550
|
+
} catch (err) {
|
|
551
|
+
if (options?.mayBeLess && err instanceof EndOfStreamError) {
|
|
552
|
+
return 0;
|
|
553
|
+
}
|
|
554
|
+
throw err;
|
|
555
|
+
}
|
|
556
|
+
if (!normOptions.mayBeLess && bytesRead < normOptions.length) {
|
|
557
|
+
throw new EndOfStreamError();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return bytesRead;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* @param length Number of bytes to ignore. Must be ≥ 0.
|
|
564
|
+
*/
|
|
565
|
+
async ignore(length) {
|
|
566
|
+
if (length < 0) {
|
|
567
|
+
throw new RangeError("ignore length must be \u2265 0 bytes");
|
|
568
|
+
}
|
|
569
|
+
const bufSize = Math.min(maxBufferSize, length);
|
|
570
|
+
const buf = new Uint8Array(bufSize);
|
|
571
|
+
let totBytesRead = 0;
|
|
572
|
+
while (totBytesRead < length) {
|
|
573
|
+
const remaining = length - totBytesRead;
|
|
574
|
+
const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) });
|
|
575
|
+
if (bytesRead < 0) {
|
|
576
|
+
return bytesRead;
|
|
577
|
+
}
|
|
578
|
+
totBytesRead += bytesRead;
|
|
579
|
+
}
|
|
580
|
+
return totBytesRead;
|
|
581
|
+
}
|
|
582
|
+
abort() {
|
|
583
|
+
return this.streamReader.abort();
|
|
584
|
+
}
|
|
585
|
+
async close() {
|
|
586
|
+
return this.streamReader.close();
|
|
587
|
+
}
|
|
588
|
+
supportsRandomAccess() {
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/BufferTokenizer.js
|
|
594
|
+
var BufferTokenizer = class extends AbstractTokenizer {
|
|
595
|
+
/**
|
|
596
|
+
* Construct BufferTokenizer
|
|
597
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
598
|
+
* @param options Tokenizer options
|
|
599
|
+
*/
|
|
600
|
+
constructor(uint8Array, options) {
|
|
601
|
+
super(options);
|
|
602
|
+
this.uint8Array = uint8Array;
|
|
603
|
+
this.fileInfo = { ...options?.fileInfo ?? {}, ...{ size: uint8Array.length } };
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Read buffer from tokenizer
|
|
607
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
608
|
+
* @param options - Read behaviour options
|
|
609
|
+
* @returns {Promise<number>}
|
|
610
|
+
*/
|
|
611
|
+
async readBuffer(uint8Array, options) {
|
|
612
|
+
if (options?.position) {
|
|
613
|
+
this.position = options.position;
|
|
614
|
+
}
|
|
615
|
+
const bytesRead = await this.peekBuffer(uint8Array, options);
|
|
616
|
+
this.position += bytesRead;
|
|
617
|
+
return bytesRead;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Peek (read ahead) buffer from tokenizer
|
|
621
|
+
* @param uint8Array
|
|
622
|
+
* @param options - Read behaviour options
|
|
623
|
+
* @returns {Promise<number>}
|
|
624
|
+
*/
|
|
625
|
+
async peekBuffer(uint8Array, options) {
|
|
626
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
627
|
+
const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length);
|
|
628
|
+
if (!normOptions.mayBeLess && bytes2read < normOptions.length) {
|
|
629
|
+
throw new EndOfStreamError();
|
|
630
|
+
}
|
|
631
|
+
uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read));
|
|
632
|
+
return bytes2read;
|
|
633
|
+
}
|
|
634
|
+
close() {
|
|
635
|
+
return super.close();
|
|
636
|
+
}
|
|
637
|
+
supportsRandomAccess() {
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
setPosition(position) {
|
|
641
|
+
this.position = position;
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/BlobTokenizer.js
|
|
646
|
+
var BlobTokenizer = class extends AbstractTokenizer {
|
|
647
|
+
/**
|
|
648
|
+
* Construct BufferTokenizer
|
|
649
|
+
* @param blob - Uint8Array to tokenize
|
|
650
|
+
* @param options Tokenizer options
|
|
651
|
+
*/
|
|
652
|
+
constructor(blob, options) {
|
|
653
|
+
super(options);
|
|
654
|
+
this.blob = blob;
|
|
655
|
+
this.fileInfo = { ...options?.fileInfo ?? {}, ...{ size: blob.size, mimeType: blob.type } };
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Read buffer from tokenizer
|
|
659
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
660
|
+
* @param options - Read behaviour options
|
|
661
|
+
* @returns {Promise<number>}
|
|
662
|
+
*/
|
|
663
|
+
async readBuffer(uint8Array, options) {
|
|
664
|
+
if (options?.position) {
|
|
665
|
+
this.position = options.position;
|
|
666
|
+
}
|
|
667
|
+
const bytesRead = await this.peekBuffer(uint8Array, options);
|
|
668
|
+
this.position += bytesRead;
|
|
669
|
+
return bytesRead;
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Peek (read ahead) buffer from tokenizer
|
|
673
|
+
* @param buffer
|
|
674
|
+
* @param options - Read behaviour options
|
|
675
|
+
* @returns {Promise<number>}
|
|
676
|
+
*/
|
|
677
|
+
async peekBuffer(buffer, options) {
|
|
678
|
+
const normOptions = this.normalizeOptions(buffer, options);
|
|
679
|
+
const bytes2read = Math.min(this.blob.size - normOptions.position, normOptions.length);
|
|
680
|
+
if (!normOptions.mayBeLess && bytes2read < normOptions.length) {
|
|
681
|
+
throw new EndOfStreamError();
|
|
682
|
+
}
|
|
683
|
+
const arrayBuffer = await this.blob.slice(normOptions.position, normOptions.position + bytes2read).arrayBuffer();
|
|
684
|
+
buffer.set(new Uint8Array(arrayBuffer));
|
|
685
|
+
return bytes2read;
|
|
686
|
+
}
|
|
687
|
+
close() {
|
|
688
|
+
return super.close();
|
|
689
|
+
}
|
|
690
|
+
supportsRandomAccess() {
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
setPosition(position) {
|
|
694
|
+
this.position = position;
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/core.js
|
|
699
|
+
function fromStream(stream, options) {
|
|
700
|
+
const streamReader = new StreamReader(stream);
|
|
701
|
+
const _options = options ?? {};
|
|
702
|
+
const chainedClose = _options.onClose;
|
|
703
|
+
_options.onClose = async () => {
|
|
704
|
+
await streamReader.close();
|
|
705
|
+
if (chainedClose) {
|
|
706
|
+
return chainedClose();
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
return new ReadStreamTokenizer(streamReader, _options);
|
|
710
|
+
}
|
|
711
|
+
function fromWebStream(webStream, options) {
|
|
712
|
+
const webStreamReader = makeWebStreamReader(webStream);
|
|
713
|
+
const _options = options ?? {};
|
|
714
|
+
const chainedClose = _options.onClose;
|
|
715
|
+
_options.onClose = async () => {
|
|
716
|
+
await webStreamReader.close();
|
|
717
|
+
if (chainedClose) {
|
|
718
|
+
return chainedClose();
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
return new ReadStreamTokenizer(webStreamReader, _options);
|
|
722
|
+
}
|
|
723
|
+
function fromBuffer(uint8Array, options) {
|
|
724
|
+
return new BufferTokenizer(uint8Array, options);
|
|
725
|
+
}
|
|
726
|
+
function fromBlob(blob, options) {
|
|
727
|
+
return new BlobTokenizer(blob, options);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/FileTokenizer.js
|
|
731
|
+
import { open as fsOpen } from "fs/promises";
|
|
732
|
+
var FileTokenizer = class _FileTokenizer extends AbstractTokenizer {
|
|
733
|
+
/**
|
|
734
|
+
* Create tokenizer from provided file path
|
|
735
|
+
* @param sourceFilePath File path
|
|
736
|
+
*/
|
|
737
|
+
static async fromFile(sourceFilePath) {
|
|
738
|
+
const fileHandle = await fsOpen(sourceFilePath, "r");
|
|
739
|
+
const stat = await fileHandle.stat();
|
|
740
|
+
return new _FileTokenizer(fileHandle, { fileInfo: { path: sourceFilePath, size: stat.size } });
|
|
741
|
+
}
|
|
742
|
+
constructor(fileHandle, options) {
|
|
743
|
+
super(options);
|
|
744
|
+
this.fileHandle = fileHandle;
|
|
745
|
+
this.fileInfo = options.fileInfo;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Read buffer from file
|
|
749
|
+
* @param uint8Array - Uint8Array to write result to
|
|
750
|
+
* @param options - Read behaviour options
|
|
751
|
+
* @returns Promise number of bytes read
|
|
752
|
+
*/
|
|
753
|
+
async readBuffer(uint8Array, options) {
|
|
754
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
755
|
+
this.position = normOptions.position;
|
|
756
|
+
if (normOptions.length === 0)
|
|
757
|
+
return 0;
|
|
758
|
+
const res = await this.fileHandle.read(uint8Array, 0, normOptions.length, normOptions.position);
|
|
759
|
+
this.position += res.bytesRead;
|
|
760
|
+
if (res.bytesRead < normOptions.length && (!options || !options.mayBeLess)) {
|
|
761
|
+
throw new EndOfStreamError();
|
|
762
|
+
}
|
|
763
|
+
return res.bytesRead;
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Peek buffer from file
|
|
767
|
+
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
768
|
+
* @param options - Read behaviour options
|
|
769
|
+
* @returns Promise number of bytes read
|
|
770
|
+
*/
|
|
771
|
+
async peekBuffer(uint8Array, options) {
|
|
772
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
773
|
+
const res = await this.fileHandle.read(uint8Array, 0, normOptions.length, normOptions.position);
|
|
774
|
+
if (!normOptions.mayBeLess && res.bytesRead < normOptions.length) {
|
|
775
|
+
throw new EndOfStreamError();
|
|
776
|
+
}
|
|
777
|
+
return res.bytesRead;
|
|
778
|
+
}
|
|
779
|
+
async close() {
|
|
780
|
+
await this.fileHandle.close();
|
|
781
|
+
return super.close();
|
|
782
|
+
}
|
|
783
|
+
setPosition(position) {
|
|
784
|
+
this.position = position;
|
|
785
|
+
}
|
|
786
|
+
supportsRandomAccess() {
|
|
787
|
+
return true;
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
// ../../node_modules/.bun/strtok3@10.3.5/node_modules/strtok3/lib/index.js
|
|
792
|
+
async function fromStream2(stream, options) {
|
|
793
|
+
const rst = fromStream(stream, options);
|
|
794
|
+
if (stream.path) {
|
|
795
|
+
const stat = await fsStat(stream.path);
|
|
796
|
+
rst.fileInfo.path = stream.path;
|
|
797
|
+
rst.fileInfo.size = stat.size;
|
|
798
|
+
}
|
|
799
|
+
return rst;
|
|
800
|
+
}
|
|
801
|
+
var fromFile = FileTokenizer.fromFile;
|
|
802
|
+
|
|
803
|
+
// ../../node_modules/.bun/token-types@6.1.2/node_modules/token-types/lib/index.js
|
|
804
|
+
var ieee754 = __toESM(require_ieee754(), 1);
|
|
805
|
+
|
|
806
|
+
// ../../node_modules/.bun/@borewit+text-codec@0.2.2/node_modules/@borewit/text-codec/lib/index.js
|
|
807
|
+
var WINDOWS_1252_EXTRA = {
|
|
808
|
+
128: "\u20AC",
|
|
809
|
+
130: "\u201A",
|
|
810
|
+
131: "\u0192",
|
|
811
|
+
132: "\u201E",
|
|
812
|
+
133: "\u2026",
|
|
813
|
+
134: "\u2020",
|
|
814
|
+
135: "\u2021",
|
|
815
|
+
136: "\u02C6",
|
|
816
|
+
137: "\u2030",
|
|
817
|
+
138: "\u0160",
|
|
818
|
+
139: "\u2039",
|
|
819
|
+
140: "\u0152",
|
|
820
|
+
142: "\u017D",
|
|
821
|
+
145: "\u2018",
|
|
822
|
+
146: "\u2019",
|
|
823
|
+
147: "\u201C",
|
|
824
|
+
148: "\u201D",
|
|
825
|
+
149: "\u2022",
|
|
826
|
+
150: "\u2013",
|
|
827
|
+
151: "\u2014",
|
|
828
|
+
152: "\u02DC",
|
|
829
|
+
153: "\u2122",
|
|
830
|
+
154: "\u0161",
|
|
831
|
+
155: "\u203A",
|
|
832
|
+
156: "\u0153",
|
|
833
|
+
158: "\u017E",
|
|
834
|
+
159: "\u0178"
|
|
835
|
+
};
|
|
836
|
+
var WINDOWS_1252_REVERSE = {};
|
|
837
|
+
for (const [code, char] of Object.entries(WINDOWS_1252_EXTRA)) {
|
|
838
|
+
WINDOWS_1252_REVERSE[char] = Number.parseInt(code, 10);
|
|
839
|
+
}
|
|
840
|
+
var _utf8Decoder;
|
|
841
|
+
function utf8Decoder() {
|
|
842
|
+
if (typeof globalThis.TextDecoder === "undefined")
|
|
843
|
+
return void 0;
|
|
844
|
+
return _utf8Decoder !== null && _utf8Decoder !== void 0 ? _utf8Decoder : _utf8Decoder = new globalThis.TextDecoder("utf-8");
|
|
845
|
+
}
|
|
846
|
+
var CHUNK = 32 * 1024;
|
|
847
|
+
var REPLACEMENT = 65533;
|
|
848
|
+
function textDecode(bytes, encoding = "utf-8") {
|
|
849
|
+
switch (encoding.toLowerCase()) {
|
|
850
|
+
case "utf-8":
|
|
851
|
+
case "utf8": {
|
|
852
|
+
const dec = utf8Decoder();
|
|
853
|
+
return dec ? dec.decode(bytes) : decodeUTF8(bytes);
|
|
854
|
+
}
|
|
855
|
+
case "utf-16le":
|
|
856
|
+
return decodeUTF16LE(bytes);
|
|
857
|
+
case "us-ascii":
|
|
858
|
+
case "ascii":
|
|
859
|
+
return decodeASCII(bytes);
|
|
860
|
+
case "latin1":
|
|
861
|
+
case "iso-8859-1":
|
|
862
|
+
return decodeLatin1(bytes);
|
|
863
|
+
case "windows-1252":
|
|
864
|
+
return decodeWindows1252(bytes);
|
|
865
|
+
default:
|
|
866
|
+
throw new RangeError(`Encoding '${encoding}' not supported`);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
function flushChunk(parts, chunk) {
|
|
870
|
+
if (chunk.length === 0)
|
|
871
|
+
return;
|
|
872
|
+
parts.push(String.fromCharCode.apply(null, chunk));
|
|
873
|
+
chunk.length = 0;
|
|
874
|
+
}
|
|
875
|
+
function pushCodeUnit(parts, chunk, codeUnit) {
|
|
876
|
+
chunk.push(codeUnit);
|
|
877
|
+
if (chunk.length >= CHUNK)
|
|
878
|
+
flushChunk(parts, chunk);
|
|
879
|
+
}
|
|
880
|
+
function pushCodePoint(parts, chunk, cp) {
|
|
881
|
+
if (cp <= 65535) {
|
|
882
|
+
pushCodeUnit(parts, chunk, cp);
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
cp -= 65536;
|
|
886
|
+
pushCodeUnit(parts, chunk, 55296 + (cp >> 10));
|
|
887
|
+
pushCodeUnit(parts, chunk, 56320 + (cp & 1023));
|
|
888
|
+
}
|
|
889
|
+
function decodeUTF8(bytes) {
|
|
890
|
+
const parts = [];
|
|
891
|
+
const chunk = [];
|
|
892
|
+
let i = 0;
|
|
893
|
+
if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) {
|
|
894
|
+
i = 3;
|
|
895
|
+
}
|
|
896
|
+
while (i < bytes.length) {
|
|
897
|
+
const b1 = bytes[i];
|
|
898
|
+
if (b1 <= 127) {
|
|
899
|
+
pushCodeUnit(parts, chunk, b1);
|
|
900
|
+
i++;
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
if (b1 < 194 || b1 > 244) {
|
|
904
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
905
|
+
i++;
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
if (b1 <= 223) {
|
|
909
|
+
if (i + 1 >= bytes.length) {
|
|
910
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
911
|
+
i++;
|
|
912
|
+
continue;
|
|
913
|
+
}
|
|
914
|
+
const b22 = bytes[i + 1];
|
|
915
|
+
if ((b22 & 192) !== 128) {
|
|
916
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
917
|
+
i++;
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
const cp2 = (b1 & 31) << 6 | b22 & 63;
|
|
921
|
+
pushCodeUnit(parts, chunk, cp2);
|
|
922
|
+
i += 2;
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
if (b1 <= 239) {
|
|
926
|
+
if (i + 2 >= bytes.length) {
|
|
927
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
928
|
+
i++;
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
const b22 = bytes[i + 1];
|
|
932
|
+
const b32 = bytes[i + 2];
|
|
933
|
+
const valid2 = (b22 & 192) === 128 && (b32 & 192) === 128 && !(b1 === 224 && b22 < 160) && // overlong
|
|
934
|
+
!(b1 === 237 && b22 >= 160);
|
|
935
|
+
if (!valid2) {
|
|
936
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
937
|
+
i++;
|
|
938
|
+
continue;
|
|
939
|
+
}
|
|
940
|
+
const cp2 = (b1 & 15) << 12 | (b22 & 63) << 6 | b32 & 63;
|
|
941
|
+
pushCodeUnit(parts, chunk, cp2);
|
|
942
|
+
i += 3;
|
|
943
|
+
continue;
|
|
944
|
+
}
|
|
945
|
+
if (i + 3 >= bytes.length) {
|
|
946
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
947
|
+
i++;
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
const b2 = bytes[i + 1];
|
|
951
|
+
const b3 = bytes[i + 2];
|
|
952
|
+
const b4 = bytes[i + 3];
|
|
953
|
+
const valid = (b2 & 192) === 128 && (b3 & 192) === 128 && (b4 & 192) === 128 && !(b1 === 240 && b2 < 144) && // overlong
|
|
954
|
+
!(b1 === 244 && b2 > 143);
|
|
955
|
+
if (!valid) {
|
|
956
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
957
|
+
i++;
|
|
958
|
+
continue;
|
|
959
|
+
}
|
|
960
|
+
const cp = (b1 & 7) << 18 | (b2 & 63) << 12 | (b3 & 63) << 6 | b4 & 63;
|
|
961
|
+
pushCodePoint(parts, chunk, cp);
|
|
962
|
+
i += 4;
|
|
963
|
+
}
|
|
964
|
+
flushChunk(parts, chunk);
|
|
965
|
+
return parts.join("");
|
|
966
|
+
}
|
|
967
|
+
function decodeUTF16LE(bytes) {
|
|
968
|
+
const parts = [];
|
|
969
|
+
const chunk = [];
|
|
970
|
+
const len = bytes.length;
|
|
971
|
+
let i = 0;
|
|
972
|
+
while (i + 1 < len) {
|
|
973
|
+
const u1 = bytes[i] | bytes[i + 1] << 8;
|
|
974
|
+
i += 2;
|
|
975
|
+
if (u1 >= 55296 && u1 <= 56319) {
|
|
976
|
+
if (i + 1 < len) {
|
|
977
|
+
const u2 = bytes[i] | bytes[i + 1] << 8;
|
|
978
|
+
if (u2 >= 56320 && u2 <= 57343) {
|
|
979
|
+
pushCodeUnit(parts, chunk, u1);
|
|
980
|
+
pushCodeUnit(parts, chunk, u2);
|
|
981
|
+
i += 2;
|
|
982
|
+
} else {
|
|
983
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
984
|
+
}
|
|
985
|
+
} else {
|
|
986
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
987
|
+
}
|
|
988
|
+
continue;
|
|
989
|
+
}
|
|
990
|
+
if (u1 >= 56320 && u1 <= 57343) {
|
|
991
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
992
|
+
continue;
|
|
993
|
+
}
|
|
994
|
+
pushCodeUnit(parts, chunk, u1);
|
|
995
|
+
}
|
|
996
|
+
if (i < len) {
|
|
997
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
998
|
+
}
|
|
999
|
+
flushChunk(parts, chunk);
|
|
1000
|
+
return parts.join("");
|
|
1001
|
+
}
|
|
1002
|
+
function decodeASCII(bytes) {
|
|
1003
|
+
const parts = [];
|
|
1004
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
1005
|
+
const end = Math.min(bytes.length, i + CHUNK);
|
|
1006
|
+
const codes = new Array(end - i);
|
|
1007
|
+
for (let j = i, k = 0; j < end; j++, k++) {
|
|
1008
|
+
codes[k] = bytes[j] & 127;
|
|
1009
|
+
}
|
|
1010
|
+
parts.push(String.fromCharCode.apply(null, codes));
|
|
1011
|
+
}
|
|
1012
|
+
return parts.join("");
|
|
1013
|
+
}
|
|
1014
|
+
function decodeLatin1(bytes) {
|
|
1015
|
+
const parts = [];
|
|
1016
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
1017
|
+
const end = Math.min(bytes.length, i + CHUNK);
|
|
1018
|
+
const codes = new Array(end - i);
|
|
1019
|
+
for (let j = i, k = 0; j < end; j++, k++) {
|
|
1020
|
+
codes[k] = bytes[j];
|
|
1021
|
+
}
|
|
1022
|
+
parts.push(String.fromCharCode.apply(null, codes));
|
|
1023
|
+
}
|
|
1024
|
+
return parts.join("");
|
|
1025
|
+
}
|
|
1026
|
+
function decodeWindows1252(bytes) {
|
|
1027
|
+
const parts = [];
|
|
1028
|
+
let out = "";
|
|
1029
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1030
|
+
const b = bytes[i];
|
|
1031
|
+
const extra = b >= 128 && b <= 159 ? WINDOWS_1252_EXTRA[b] : void 0;
|
|
1032
|
+
out += extra !== null && extra !== void 0 ? extra : String.fromCharCode(b);
|
|
1033
|
+
if (out.length >= CHUNK) {
|
|
1034
|
+
parts.push(out);
|
|
1035
|
+
out = "";
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
if (out)
|
|
1039
|
+
parts.push(out);
|
|
1040
|
+
return parts.join("");
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// ../../node_modules/.bun/token-types@6.1.2/node_modules/token-types/lib/index.js
|
|
1044
|
+
function dv(array) {
|
|
1045
|
+
return new DataView(array.buffer, array.byteOffset);
|
|
1046
|
+
}
|
|
1047
|
+
var UINT8 = {
|
|
1048
|
+
len: 1,
|
|
1049
|
+
get(array, offset) {
|
|
1050
|
+
return dv(array).getUint8(offset);
|
|
1051
|
+
},
|
|
1052
|
+
put(array, offset, value) {
|
|
1053
|
+
dv(array).setUint8(offset, value);
|
|
1054
|
+
return offset + 1;
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
var UINT16_LE = {
|
|
1058
|
+
len: 2,
|
|
1059
|
+
get(array, offset) {
|
|
1060
|
+
return dv(array).getUint16(offset, true);
|
|
1061
|
+
},
|
|
1062
|
+
put(array, offset, value) {
|
|
1063
|
+
dv(array).setUint16(offset, value, true);
|
|
1064
|
+
return offset + 2;
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
var UINT16_BE = {
|
|
1068
|
+
len: 2,
|
|
1069
|
+
get(array, offset) {
|
|
1070
|
+
return dv(array).getUint16(offset);
|
|
1071
|
+
},
|
|
1072
|
+
put(array, offset, value) {
|
|
1073
|
+
dv(array).setUint16(offset, value);
|
|
1074
|
+
return offset + 2;
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
var UINT32_LE = {
|
|
1078
|
+
len: 4,
|
|
1079
|
+
get(array, offset) {
|
|
1080
|
+
return dv(array).getUint32(offset, true);
|
|
1081
|
+
},
|
|
1082
|
+
put(array, offset, value) {
|
|
1083
|
+
dv(array).setUint32(offset, value, true);
|
|
1084
|
+
return offset + 4;
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
var UINT32_BE = {
|
|
1088
|
+
len: 4,
|
|
1089
|
+
get(array, offset) {
|
|
1090
|
+
return dv(array).getUint32(offset);
|
|
1091
|
+
},
|
|
1092
|
+
put(array, offset, value) {
|
|
1093
|
+
dv(array).setUint32(offset, value);
|
|
1094
|
+
return offset + 4;
|
|
1095
|
+
}
|
|
1096
|
+
};
|
|
1097
|
+
var INT32_BE = {
|
|
1098
|
+
len: 4,
|
|
1099
|
+
get(array, offset) {
|
|
1100
|
+
return dv(array).getInt32(offset);
|
|
1101
|
+
},
|
|
1102
|
+
put(array, offset, value) {
|
|
1103
|
+
dv(array).setInt32(offset, value);
|
|
1104
|
+
return offset + 4;
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
var UINT64_LE = {
|
|
1108
|
+
len: 8,
|
|
1109
|
+
get(array, offset) {
|
|
1110
|
+
return dv(array).getBigUint64(offset, true);
|
|
1111
|
+
},
|
|
1112
|
+
put(array, offset, value) {
|
|
1113
|
+
dv(array).setBigUint64(offset, value, true);
|
|
1114
|
+
return offset + 8;
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
var StringType = class {
|
|
1118
|
+
constructor(len, encoding) {
|
|
1119
|
+
this.len = len;
|
|
1120
|
+
this.encoding = encoding;
|
|
1121
|
+
}
|
|
1122
|
+
get(data, offset = 0) {
|
|
1123
|
+
const bytes = data.subarray(offset, offset + this.len);
|
|
1124
|
+
return textDecode(bytes, this.encoding);
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1128
|
+
// ../../node_modules/.bun/@tokenizer+inflate@0.4.1/node_modules/@tokenizer/inflate/lib/ZipHandler.js
|
|
1129
|
+
var import_debug = __toESM(require_src(), 1);
|
|
1130
|
+
|
|
1131
|
+
// ../../node_modules/.bun/@tokenizer+inflate@0.4.1/node_modules/@tokenizer/inflate/lib/ZipToken.js
|
|
1132
|
+
var Signature = {
|
|
1133
|
+
LocalFileHeader: 67324752,
|
|
1134
|
+
DataDescriptor: 134695760,
|
|
1135
|
+
CentralFileHeader: 33639248,
|
|
1136
|
+
EndOfCentralDirectory: 101010256
|
|
1137
|
+
};
|
|
1138
|
+
var DataDescriptor = {
|
|
1139
|
+
get(array) {
|
|
1140
|
+
return {
|
|
1141
|
+
signature: UINT32_LE.get(array, 0),
|
|
1142
|
+
compressedSize: UINT32_LE.get(array, 8),
|
|
1143
|
+
uncompressedSize: UINT32_LE.get(array, 12)
|
|
1144
|
+
};
|
|
1145
|
+
},
|
|
1146
|
+
len: 16
|
|
1147
|
+
};
|
|
1148
|
+
var LocalFileHeaderToken = {
|
|
1149
|
+
get(array) {
|
|
1150
|
+
const flags = UINT16_LE.get(array, 6);
|
|
1151
|
+
return {
|
|
1152
|
+
signature: UINT32_LE.get(array, 0),
|
|
1153
|
+
minVersion: UINT16_LE.get(array, 4),
|
|
1154
|
+
dataDescriptor: !!(flags & 8),
|
|
1155
|
+
compressedMethod: UINT16_LE.get(array, 8),
|
|
1156
|
+
compressedSize: UINT32_LE.get(array, 18),
|
|
1157
|
+
uncompressedSize: UINT32_LE.get(array, 22),
|
|
1158
|
+
filenameLength: UINT16_LE.get(array, 26),
|
|
1159
|
+
extraFieldLength: UINT16_LE.get(array, 28),
|
|
1160
|
+
filename: null
|
|
1161
|
+
};
|
|
1162
|
+
},
|
|
1163
|
+
len: 30
|
|
1164
|
+
};
|
|
1165
|
+
var EndOfCentralDirectoryRecordToken = {
|
|
1166
|
+
get(array) {
|
|
1167
|
+
return {
|
|
1168
|
+
signature: UINT32_LE.get(array, 0),
|
|
1169
|
+
nrOfThisDisk: UINT16_LE.get(array, 4),
|
|
1170
|
+
nrOfThisDiskWithTheStart: UINT16_LE.get(array, 6),
|
|
1171
|
+
nrOfEntriesOnThisDisk: UINT16_LE.get(array, 8),
|
|
1172
|
+
nrOfEntriesOfSize: UINT16_LE.get(array, 10),
|
|
1173
|
+
sizeOfCd: UINT32_LE.get(array, 12),
|
|
1174
|
+
offsetOfStartOfCd: UINT32_LE.get(array, 16),
|
|
1175
|
+
zipFileCommentLength: UINT16_LE.get(array, 20)
|
|
1176
|
+
};
|
|
1177
|
+
},
|
|
1178
|
+
len: 22
|
|
1179
|
+
};
|
|
1180
|
+
var FileHeader = {
|
|
1181
|
+
get(array) {
|
|
1182
|
+
const flags = UINT16_LE.get(array, 8);
|
|
1183
|
+
return {
|
|
1184
|
+
signature: UINT32_LE.get(array, 0),
|
|
1185
|
+
minVersion: UINT16_LE.get(array, 6),
|
|
1186
|
+
dataDescriptor: !!(flags & 8),
|
|
1187
|
+
compressedMethod: UINT16_LE.get(array, 10),
|
|
1188
|
+
compressedSize: UINT32_LE.get(array, 20),
|
|
1189
|
+
uncompressedSize: UINT32_LE.get(array, 24),
|
|
1190
|
+
filenameLength: UINT16_LE.get(array, 28),
|
|
1191
|
+
extraFieldLength: UINT16_LE.get(array, 30),
|
|
1192
|
+
fileCommentLength: UINT16_LE.get(array, 32),
|
|
1193
|
+
relativeOffsetOfLocalHeader: UINT32_LE.get(array, 42),
|
|
1194
|
+
filename: null
|
|
1195
|
+
};
|
|
1196
|
+
},
|
|
1197
|
+
len: 46
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
// ../../node_modules/.bun/@tokenizer+inflate@0.4.1/node_modules/@tokenizer/inflate/lib/ZipHandler.js
|
|
1201
|
+
function signatureToArray(signature) {
|
|
1202
|
+
const signatureBytes = new Uint8Array(UINT32_LE.len);
|
|
1203
|
+
UINT32_LE.put(signatureBytes, 0, signature);
|
|
1204
|
+
return signatureBytes;
|
|
1205
|
+
}
|
|
1206
|
+
var debug = (0, import_debug.default)("tokenizer:inflate");
|
|
1207
|
+
var syncBufferSize = 256 * 1024;
|
|
1208
|
+
var ddSignatureArray = signatureToArray(Signature.DataDescriptor);
|
|
1209
|
+
var eocdSignatureBytes = signatureToArray(Signature.EndOfCentralDirectory);
|
|
1210
|
+
var ZipHandler = class _ZipHandler {
|
|
1211
|
+
constructor(tokenizer) {
|
|
1212
|
+
this.tokenizer = tokenizer;
|
|
1213
|
+
this.syncBuffer = new Uint8Array(syncBufferSize);
|
|
1214
|
+
}
|
|
1215
|
+
async isZip() {
|
|
1216
|
+
return await this.peekSignature() === Signature.LocalFileHeader;
|
|
1217
|
+
}
|
|
1218
|
+
peekSignature() {
|
|
1219
|
+
return this.tokenizer.peekToken(UINT32_LE);
|
|
1220
|
+
}
|
|
1221
|
+
async findEndOfCentralDirectoryLocator() {
|
|
1222
|
+
const randomReadTokenizer = this.tokenizer;
|
|
1223
|
+
const chunkLength = Math.min(16 * 1024, randomReadTokenizer.fileInfo.size);
|
|
1224
|
+
const buffer = this.syncBuffer.subarray(0, chunkLength);
|
|
1225
|
+
await this.tokenizer.readBuffer(buffer, { position: randomReadTokenizer.fileInfo.size - chunkLength });
|
|
1226
|
+
for (let i = buffer.length - 4; i >= 0; i--) {
|
|
1227
|
+
if (buffer[i] === eocdSignatureBytes[0] && buffer[i + 1] === eocdSignatureBytes[1] && buffer[i + 2] === eocdSignatureBytes[2] && buffer[i + 3] === eocdSignatureBytes[3]) {
|
|
1228
|
+
return randomReadTokenizer.fileInfo.size - chunkLength + i;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
return -1;
|
|
1232
|
+
}
|
|
1233
|
+
async readCentralDirectory() {
|
|
1234
|
+
if (!this.tokenizer.supportsRandomAccess()) {
|
|
1235
|
+
debug("Cannot reading central-directory without random-read support");
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
debug("Reading central-directory...");
|
|
1239
|
+
const pos = this.tokenizer.position;
|
|
1240
|
+
const offset = await this.findEndOfCentralDirectoryLocator();
|
|
1241
|
+
if (offset > 0) {
|
|
1242
|
+
debug("Central-directory 32-bit signature found");
|
|
1243
|
+
const eocdHeader = await this.tokenizer.readToken(EndOfCentralDirectoryRecordToken, offset);
|
|
1244
|
+
const files = [];
|
|
1245
|
+
this.tokenizer.setPosition(eocdHeader.offsetOfStartOfCd);
|
|
1246
|
+
for (let n = 0; n < eocdHeader.nrOfEntriesOfSize; ++n) {
|
|
1247
|
+
const entry = await this.tokenizer.readToken(FileHeader);
|
|
1248
|
+
if (entry.signature !== Signature.CentralFileHeader) {
|
|
1249
|
+
throw new Error("Expected Central-File-Header signature");
|
|
1250
|
+
}
|
|
1251
|
+
entry.filename = await this.tokenizer.readToken(new StringType(entry.filenameLength, "utf-8"));
|
|
1252
|
+
await this.tokenizer.ignore(entry.extraFieldLength);
|
|
1253
|
+
await this.tokenizer.ignore(entry.fileCommentLength);
|
|
1254
|
+
files.push(entry);
|
|
1255
|
+
debug(`Add central-directory file-entry: n=${n + 1}/${files.length}: filename=${files[n].filename}`);
|
|
1256
|
+
}
|
|
1257
|
+
this.tokenizer.setPosition(pos);
|
|
1258
|
+
return files;
|
|
1259
|
+
}
|
|
1260
|
+
this.tokenizer.setPosition(pos);
|
|
1261
|
+
}
|
|
1262
|
+
async unzip(fileCb) {
|
|
1263
|
+
const entries = await this.readCentralDirectory();
|
|
1264
|
+
if (entries) {
|
|
1265
|
+
return this.iterateOverCentralDirectory(entries, fileCb);
|
|
1266
|
+
}
|
|
1267
|
+
let stop = false;
|
|
1268
|
+
do {
|
|
1269
|
+
const zipHeader = await this.readLocalFileHeader();
|
|
1270
|
+
if (!zipHeader)
|
|
1271
|
+
break;
|
|
1272
|
+
const next = fileCb(zipHeader);
|
|
1273
|
+
stop = !!next.stop;
|
|
1274
|
+
let fileData;
|
|
1275
|
+
await this.tokenizer.ignore(zipHeader.extraFieldLength);
|
|
1276
|
+
if (zipHeader.dataDescriptor && zipHeader.compressedSize === 0) {
|
|
1277
|
+
const chunks = [];
|
|
1278
|
+
let len = syncBufferSize;
|
|
1279
|
+
debug("Compressed-file-size unknown, scanning for next data-descriptor-signature....");
|
|
1280
|
+
let nextHeaderIndex = -1;
|
|
1281
|
+
while (nextHeaderIndex < 0 && len === syncBufferSize) {
|
|
1282
|
+
len = await this.tokenizer.peekBuffer(this.syncBuffer, { mayBeLess: true });
|
|
1283
|
+
nextHeaderIndex = indexOf(this.syncBuffer.subarray(0, len), ddSignatureArray);
|
|
1284
|
+
const size = nextHeaderIndex >= 0 ? nextHeaderIndex : len;
|
|
1285
|
+
if (next.handler) {
|
|
1286
|
+
const data = new Uint8Array(size);
|
|
1287
|
+
await this.tokenizer.readBuffer(data);
|
|
1288
|
+
chunks.push(data);
|
|
1289
|
+
} else {
|
|
1290
|
+
await this.tokenizer.ignore(size);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
debug(`Found data-descriptor-signature at pos=${this.tokenizer.position}`);
|
|
1294
|
+
if (next.handler) {
|
|
1295
|
+
await this.inflate(zipHeader, mergeArrays(chunks), next.handler);
|
|
1296
|
+
}
|
|
1297
|
+
} else {
|
|
1298
|
+
if (next.handler) {
|
|
1299
|
+
debug(`Reading compressed-file-data: ${zipHeader.compressedSize} bytes`);
|
|
1300
|
+
fileData = new Uint8Array(zipHeader.compressedSize);
|
|
1301
|
+
await this.tokenizer.readBuffer(fileData);
|
|
1302
|
+
await this.inflate(zipHeader, fileData, next.handler);
|
|
1303
|
+
} else {
|
|
1304
|
+
debug(`Ignoring compressed-file-data: ${zipHeader.compressedSize} bytes`);
|
|
1305
|
+
await this.tokenizer.ignore(zipHeader.compressedSize);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
debug(`Reading data-descriptor at pos=${this.tokenizer.position}`);
|
|
1309
|
+
if (zipHeader.dataDescriptor) {
|
|
1310
|
+
const dataDescriptor = await this.tokenizer.readToken(DataDescriptor);
|
|
1311
|
+
if (dataDescriptor.signature !== 134695760) {
|
|
1312
|
+
throw new Error(`Expected data-descriptor-signature at position ${this.tokenizer.position - DataDescriptor.len}`);
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
} while (!stop);
|
|
1316
|
+
}
|
|
1317
|
+
async iterateOverCentralDirectory(entries, fileCb) {
|
|
1318
|
+
for (const fileHeader of entries) {
|
|
1319
|
+
const next = fileCb(fileHeader);
|
|
1320
|
+
if (next.handler) {
|
|
1321
|
+
this.tokenizer.setPosition(fileHeader.relativeOffsetOfLocalHeader);
|
|
1322
|
+
const zipHeader = await this.readLocalFileHeader();
|
|
1323
|
+
if (zipHeader) {
|
|
1324
|
+
await this.tokenizer.ignore(zipHeader.extraFieldLength);
|
|
1325
|
+
const fileData = new Uint8Array(fileHeader.compressedSize);
|
|
1326
|
+
await this.tokenizer.readBuffer(fileData);
|
|
1327
|
+
await this.inflate(zipHeader, fileData, next.handler);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
if (next.stop)
|
|
1331
|
+
break;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
async inflate(zipHeader, fileData, cb) {
|
|
1335
|
+
if (zipHeader.compressedMethod === 0) {
|
|
1336
|
+
return cb(fileData);
|
|
1337
|
+
}
|
|
1338
|
+
if (zipHeader.compressedMethod !== 8) {
|
|
1339
|
+
throw new Error(`Unsupported ZIP compression method: ${zipHeader.compressedMethod}`);
|
|
1340
|
+
}
|
|
1341
|
+
debug(`Decompress filename=${zipHeader.filename}, compressed-size=${fileData.length}`);
|
|
1342
|
+
const uncompressedData = await _ZipHandler.decompressDeflateRaw(fileData);
|
|
1343
|
+
return cb(uncompressedData);
|
|
1344
|
+
}
|
|
1345
|
+
static async decompressDeflateRaw(data) {
|
|
1346
|
+
const input = new ReadableStream({
|
|
1347
|
+
start(controller) {
|
|
1348
|
+
controller.enqueue(data);
|
|
1349
|
+
controller.close();
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
const ds = new DecompressionStream("deflate-raw");
|
|
1353
|
+
const output = input.pipeThrough(ds);
|
|
1354
|
+
try {
|
|
1355
|
+
const response = new Response(output);
|
|
1356
|
+
const buffer = await response.arrayBuffer();
|
|
1357
|
+
return new Uint8Array(buffer);
|
|
1358
|
+
} catch (err) {
|
|
1359
|
+
const message = err instanceof Error ? `Failed to deflate ZIP entry: ${err.message}` : "Unknown decompression error in ZIP entry";
|
|
1360
|
+
throw new TypeError(message);
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
async readLocalFileHeader() {
|
|
1364
|
+
const signature = await this.tokenizer.peekToken(UINT32_LE);
|
|
1365
|
+
if (signature === Signature.LocalFileHeader) {
|
|
1366
|
+
const header = await this.tokenizer.readToken(LocalFileHeaderToken);
|
|
1367
|
+
header.filename = await this.tokenizer.readToken(new StringType(header.filenameLength, "utf-8"));
|
|
1368
|
+
return header;
|
|
1369
|
+
}
|
|
1370
|
+
if (signature === Signature.CentralFileHeader) {
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
if (signature === 3759263696) {
|
|
1374
|
+
throw new Error("Encrypted ZIP");
|
|
1375
|
+
}
|
|
1376
|
+
throw new Error("Unexpected signature");
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1379
|
+
function indexOf(buffer, portion) {
|
|
1380
|
+
const bufferLength = buffer.length;
|
|
1381
|
+
const portionLength = portion.length;
|
|
1382
|
+
if (portionLength > bufferLength)
|
|
1383
|
+
return -1;
|
|
1384
|
+
for (let i = 0; i <= bufferLength - portionLength; i++) {
|
|
1385
|
+
let found = true;
|
|
1386
|
+
for (let j = 0; j < portionLength; j++) {
|
|
1387
|
+
if (buffer[i + j] !== portion[j]) {
|
|
1388
|
+
found = false;
|
|
1389
|
+
break;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
if (found) {
|
|
1393
|
+
return i;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
return -1;
|
|
1397
|
+
}
|
|
1398
|
+
function mergeArrays(chunks) {
|
|
1399
|
+
const totalLength = chunks.reduce((acc, curr) => acc + curr.length, 0);
|
|
1400
|
+
const mergedArray = new Uint8Array(totalLength);
|
|
1401
|
+
let offset = 0;
|
|
1402
|
+
for (const chunk of chunks) {
|
|
1403
|
+
mergedArray.set(chunk, offset);
|
|
1404
|
+
offset += chunk.length;
|
|
1405
|
+
}
|
|
1406
|
+
return mergedArray;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
// ../../node_modules/.bun/@tokenizer+inflate@0.4.1/node_modules/@tokenizer/inflate/lib/GzipHandler.js
|
|
1410
|
+
var GzipHandler = class {
|
|
1411
|
+
constructor(tokenizer) {
|
|
1412
|
+
this.tokenizer = tokenizer;
|
|
1413
|
+
}
|
|
1414
|
+
inflate() {
|
|
1415
|
+
const tokenizer = this.tokenizer;
|
|
1416
|
+
return new ReadableStream({
|
|
1417
|
+
async pull(controller) {
|
|
1418
|
+
const buffer = new Uint8Array(1024);
|
|
1419
|
+
const size = await tokenizer.readBuffer(buffer, { mayBeLess: true });
|
|
1420
|
+
if (size === 0) {
|
|
1421
|
+
controller.close();
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
controller.enqueue(buffer.subarray(0, size));
|
|
1425
|
+
}
|
|
1426
|
+
}).pipeThrough(new DecompressionStream("gzip"));
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1429
|
+
|
|
1430
|
+
// ../../node_modules/.bun/uint8array-extras@1.5.0/node_modules/uint8array-extras/index.js
|
|
1431
|
+
var cachedDecoders = {
|
|
1432
|
+
utf8: new globalThis.TextDecoder("utf8")
|
|
1433
|
+
};
|
|
1434
|
+
var cachedEncoder = new globalThis.TextEncoder();
|
|
1435
|
+
var byteToHexLookupTable = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
|
|
1436
|
+
function getUintBE(view) {
|
|
1437
|
+
const { byteLength } = view;
|
|
1438
|
+
if (byteLength === 6) {
|
|
1439
|
+
return view.getUint16(0) * 2 ** 32 + view.getUint32(2);
|
|
1440
|
+
}
|
|
1441
|
+
if (byteLength === 5) {
|
|
1442
|
+
return view.getUint8(0) * 2 ** 32 + view.getUint32(1);
|
|
1443
|
+
}
|
|
1444
|
+
if (byteLength === 4) {
|
|
1445
|
+
return view.getUint32(0);
|
|
1446
|
+
}
|
|
1447
|
+
if (byteLength === 3) {
|
|
1448
|
+
return view.getUint8(0) * 2 ** 16 + view.getUint16(1);
|
|
1449
|
+
}
|
|
1450
|
+
if (byteLength === 2) {
|
|
1451
|
+
return view.getUint16(0);
|
|
1452
|
+
}
|
|
1453
|
+
if (byteLength === 1) {
|
|
1454
|
+
return view.getUint8(0);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// ../../node_modules/.bun/file-type@21.3.4/node_modules/file-type/util.js
|
|
1459
|
+
function stringToBytes(string, encoding) {
|
|
1460
|
+
if (encoding === "utf-16le") {
|
|
1461
|
+
const bytes = [];
|
|
1462
|
+
for (let index = 0; index < string.length; index++) {
|
|
1463
|
+
const code = string.charCodeAt(index);
|
|
1464
|
+
bytes.push(code & 255, code >> 8 & 255);
|
|
1465
|
+
}
|
|
1466
|
+
return bytes;
|
|
1467
|
+
}
|
|
1468
|
+
if (encoding === "utf-16be") {
|
|
1469
|
+
const bytes = [];
|
|
1470
|
+
for (let index = 0; index < string.length; index++) {
|
|
1471
|
+
const code = string.charCodeAt(index);
|
|
1472
|
+
bytes.push(code >> 8 & 255, code & 255);
|
|
1473
|
+
}
|
|
1474
|
+
return bytes;
|
|
1475
|
+
}
|
|
1476
|
+
return [...string].map((character) => character.charCodeAt(0));
|
|
1477
|
+
}
|
|
1478
|
+
function tarHeaderChecksumMatches(arrayBuffer, offset = 0) {
|
|
1479
|
+
const readSum = Number.parseInt(new StringType(6).get(arrayBuffer, 148).replace(/\0.*$/, "").trim(), 8);
|
|
1480
|
+
if (Number.isNaN(readSum)) {
|
|
1481
|
+
return false;
|
|
1482
|
+
}
|
|
1483
|
+
let sum = 8 * 32;
|
|
1484
|
+
for (let index = offset; index < offset + 148; index++) {
|
|
1485
|
+
sum += arrayBuffer[index];
|
|
1486
|
+
}
|
|
1487
|
+
for (let index = offset + 156; index < offset + 512; index++) {
|
|
1488
|
+
sum += arrayBuffer[index];
|
|
1489
|
+
}
|
|
1490
|
+
return readSum === sum;
|
|
1491
|
+
}
|
|
1492
|
+
var uint32SyncSafeToken = {
|
|
1493
|
+
get: (buffer, offset) => buffer[offset + 3] & 127 | buffer[offset + 2] << 7 | buffer[offset + 1] << 14 | buffer[offset] << 21,
|
|
1494
|
+
len: 4
|
|
1495
|
+
};
|
|
1496
|
+
|
|
1497
|
+
// ../../node_modules/.bun/file-type@21.3.4/node_modules/file-type/supported.js
|
|
1498
|
+
var extensions = [
|
|
1499
|
+
"jpg",
|
|
1500
|
+
"png",
|
|
1501
|
+
"apng",
|
|
1502
|
+
"gif",
|
|
1503
|
+
"webp",
|
|
1504
|
+
"flif",
|
|
1505
|
+
"xcf",
|
|
1506
|
+
"cr2",
|
|
1507
|
+
"cr3",
|
|
1508
|
+
"orf",
|
|
1509
|
+
"arw",
|
|
1510
|
+
"dng",
|
|
1511
|
+
"nef",
|
|
1512
|
+
"rw2",
|
|
1513
|
+
"raf",
|
|
1514
|
+
"tif",
|
|
1515
|
+
"bmp",
|
|
1516
|
+
"icns",
|
|
1517
|
+
"jxr",
|
|
1518
|
+
"psd",
|
|
1519
|
+
"indd",
|
|
1520
|
+
"zip",
|
|
1521
|
+
"tar",
|
|
1522
|
+
"rar",
|
|
1523
|
+
"gz",
|
|
1524
|
+
"bz2",
|
|
1525
|
+
"7z",
|
|
1526
|
+
"dmg",
|
|
1527
|
+
"mp4",
|
|
1528
|
+
"mid",
|
|
1529
|
+
"mkv",
|
|
1530
|
+
"webm",
|
|
1531
|
+
"mov",
|
|
1532
|
+
"avi",
|
|
1533
|
+
"mpg",
|
|
1534
|
+
"mp2",
|
|
1535
|
+
"mp3",
|
|
1536
|
+
"m4a",
|
|
1537
|
+
"oga",
|
|
1538
|
+
"ogg",
|
|
1539
|
+
"ogv",
|
|
1540
|
+
"opus",
|
|
1541
|
+
"flac",
|
|
1542
|
+
"wav",
|
|
1543
|
+
"spx",
|
|
1544
|
+
"amr",
|
|
1545
|
+
"pdf",
|
|
1546
|
+
"epub",
|
|
1547
|
+
"elf",
|
|
1548
|
+
"macho",
|
|
1549
|
+
"exe",
|
|
1550
|
+
"swf",
|
|
1551
|
+
"rtf",
|
|
1552
|
+
"wasm",
|
|
1553
|
+
"woff",
|
|
1554
|
+
"woff2",
|
|
1555
|
+
"eot",
|
|
1556
|
+
"ttf",
|
|
1557
|
+
"otf",
|
|
1558
|
+
"ttc",
|
|
1559
|
+
"ico",
|
|
1560
|
+
"flv",
|
|
1561
|
+
"ps",
|
|
1562
|
+
"xz",
|
|
1563
|
+
"sqlite",
|
|
1564
|
+
"nes",
|
|
1565
|
+
"crx",
|
|
1566
|
+
"xpi",
|
|
1567
|
+
"cab",
|
|
1568
|
+
"deb",
|
|
1569
|
+
"ar",
|
|
1570
|
+
"rpm",
|
|
1571
|
+
"Z",
|
|
1572
|
+
"lz",
|
|
1573
|
+
"cfb",
|
|
1574
|
+
"mxf",
|
|
1575
|
+
"mts",
|
|
1576
|
+
"blend",
|
|
1577
|
+
"bpg",
|
|
1578
|
+
"docx",
|
|
1579
|
+
"pptx",
|
|
1580
|
+
"xlsx",
|
|
1581
|
+
"3gp",
|
|
1582
|
+
"3g2",
|
|
1583
|
+
"j2c",
|
|
1584
|
+
"jp2",
|
|
1585
|
+
"jpm",
|
|
1586
|
+
"jpx",
|
|
1587
|
+
"mj2",
|
|
1588
|
+
"aif",
|
|
1589
|
+
"qcp",
|
|
1590
|
+
"odt",
|
|
1591
|
+
"ods",
|
|
1592
|
+
"odp",
|
|
1593
|
+
"xml",
|
|
1594
|
+
"mobi",
|
|
1595
|
+
"heic",
|
|
1596
|
+
"cur",
|
|
1597
|
+
"ktx",
|
|
1598
|
+
"ape",
|
|
1599
|
+
"wv",
|
|
1600
|
+
"dcm",
|
|
1601
|
+
"ics",
|
|
1602
|
+
"glb",
|
|
1603
|
+
"pcap",
|
|
1604
|
+
"dsf",
|
|
1605
|
+
"lnk",
|
|
1606
|
+
"alias",
|
|
1607
|
+
"voc",
|
|
1608
|
+
"ac3",
|
|
1609
|
+
"m4v",
|
|
1610
|
+
"m4p",
|
|
1611
|
+
"m4b",
|
|
1612
|
+
"f4v",
|
|
1613
|
+
"f4p",
|
|
1614
|
+
"f4b",
|
|
1615
|
+
"f4a",
|
|
1616
|
+
"mie",
|
|
1617
|
+
"asf",
|
|
1618
|
+
"ogm",
|
|
1619
|
+
"ogx",
|
|
1620
|
+
"mpc",
|
|
1621
|
+
"arrow",
|
|
1622
|
+
"shp",
|
|
1623
|
+
"aac",
|
|
1624
|
+
"mp1",
|
|
1625
|
+
"it",
|
|
1626
|
+
"s3m",
|
|
1627
|
+
"xm",
|
|
1628
|
+
"skp",
|
|
1629
|
+
"avif",
|
|
1630
|
+
"eps",
|
|
1631
|
+
"lzh",
|
|
1632
|
+
"pgp",
|
|
1633
|
+
"asar",
|
|
1634
|
+
"stl",
|
|
1635
|
+
"chm",
|
|
1636
|
+
"3mf",
|
|
1637
|
+
"zst",
|
|
1638
|
+
"jxl",
|
|
1639
|
+
"vcf",
|
|
1640
|
+
"jls",
|
|
1641
|
+
"pst",
|
|
1642
|
+
"dwg",
|
|
1643
|
+
"parquet",
|
|
1644
|
+
"class",
|
|
1645
|
+
"arj",
|
|
1646
|
+
"cpio",
|
|
1647
|
+
"ace",
|
|
1648
|
+
"avro",
|
|
1649
|
+
"icc",
|
|
1650
|
+
"fbx",
|
|
1651
|
+
"vsdx",
|
|
1652
|
+
"vtt",
|
|
1653
|
+
"apk",
|
|
1654
|
+
"drc",
|
|
1655
|
+
"lz4",
|
|
1656
|
+
"potx",
|
|
1657
|
+
"xltx",
|
|
1658
|
+
"dotx",
|
|
1659
|
+
"xltm",
|
|
1660
|
+
"ott",
|
|
1661
|
+
"ots",
|
|
1662
|
+
"otp",
|
|
1663
|
+
"odg",
|
|
1664
|
+
"otg",
|
|
1665
|
+
"xlsm",
|
|
1666
|
+
"docm",
|
|
1667
|
+
"dotm",
|
|
1668
|
+
"potm",
|
|
1669
|
+
"pptm",
|
|
1670
|
+
"jar",
|
|
1671
|
+
"jmp",
|
|
1672
|
+
"rm",
|
|
1673
|
+
"sav",
|
|
1674
|
+
"ppsm",
|
|
1675
|
+
"ppsx",
|
|
1676
|
+
"tar.gz",
|
|
1677
|
+
"reg",
|
|
1678
|
+
"dat"
|
|
1679
|
+
];
|
|
1680
|
+
var mimeTypes = [
|
|
1681
|
+
"image/jpeg",
|
|
1682
|
+
"image/png",
|
|
1683
|
+
"image/gif",
|
|
1684
|
+
"image/webp",
|
|
1685
|
+
"image/flif",
|
|
1686
|
+
"image/x-xcf",
|
|
1687
|
+
"image/x-canon-cr2",
|
|
1688
|
+
"image/x-canon-cr3",
|
|
1689
|
+
"image/tiff",
|
|
1690
|
+
"image/bmp",
|
|
1691
|
+
"image/vnd.ms-photo",
|
|
1692
|
+
"image/vnd.adobe.photoshop",
|
|
1693
|
+
"application/x-indesign",
|
|
1694
|
+
"application/epub+zip",
|
|
1695
|
+
"application/x-xpinstall",
|
|
1696
|
+
"application/vnd.ms-powerpoint.slideshow.macroenabled.12",
|
|
1697
|
+
"application/vnd.oasis.opendocument.text",
|
|
1698
|
+
"application/vnd.oasis.opendocument.spreadsheet",
|
|
1699
|
+
"application/vnd.oasis.opendocument.presentation",
|
|
1700
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1701
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
1702
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
1703
|
+
"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
|
|
1704
|
+
"application/zip",
|
|
1705
|
+
"application/x-tar",
|
|
1706
|
+
"application/x-rar-compressed",
|
|
1707
|
+
"application/gzip",
|
|
1708
|
+
"application/x-bzip2",
|
|
1709
|
+
"application/x-7z-compressed",
|
|
1710
|
+
"application/x-apple-diskimage",
|
|
1711
|
+
"application/vnd.apache.arrow.file",
|
|
1712
|
+
"video/mp4",
|
|
1713
|
+
"audio/midi",
|
|
1714
|
+
"video/matroska",
|
|
1715
|
+
"video/webm",
|
|
1716
|
+
"video/quicktime",
|
|
1717
|
+
"video/vnd.avi",
|
|
1718
|
+
"audio/wav",
|
|
1719
|
+
"audio/qcelp",
|
|
1720
|
+
"audio/x-ms-asf",
|
|
1721
|
+
"video/x-ms-asf",
|
|
1722
|
+
"application/vnd.ms-asf",
|
|
1723
|
+
"video/mpeg",
|
|
1724
|
+
"video/3gpp",
|
|
1725
|
+
"audio/mpeg",
|
|
1726
|
+
"audio/mp4",
|
|
1727
|
+
// RFC 4337
|
|
1728
|
+
"video/ogg",
|
|
1729
|
+
"audio/ogg",
|
|
1730
|
+
"audio/ogg; codecs=opus",
|
|
1731
|
+
"application/ogg",
|
|
1732
|
+
"audio/flac",
|
|
1733
|
+
"audio/ape",
|
|
1734
|
+
"audio/wavpack",
|
|
1735
|
+
"audio/amr",
|
|
1736
|
+
"application/pdf",
|
|
1737
|
+
"application/x-elf",
|
|
1738
|
+
"application/x-mach-binary",
|
|
1739
|
+
"application/x-msdownload",
|
|
1740
|
+
"application/x-shockwave-flash",
|
|
1741
|
+
"application/rtf",
|
|
1742
|
+
"application/wasm",
|
|
1743
|
+
"font/woff",
|
|
1744
|
+
"font/woff2",
|
|
1745
|
+
"application/vnd.ms-fontobject",
|
|
1746
|
+
"font/ttf",
|
|
1747
|
+
"font/otf",
|
|
1748
|
+
"font/collection",
|
|
1749
|
+
"image/x-icon",
|
|
1750
|
+
"video/x-flv",
|
|
1751
|
+
"application/postscript",
|
|
1752
|
+
"application/eps",
|
|
1753
|
+
"application/x-xz",
|
|
1754
|
+
"application/x-sqlite3",
|
|
1755
|
+
"application/x-nintendo-nes-rom",
|
|
1756
|
+
"application/x-google-chrome-extension",
|
|
1757
|
+
"application/vnd.ms-cab-compressed",
|
|
1758
|
+
"application/x-deb",
|
|
1759
|
+
"application/x-unix-archive",
|
|
1760
|
+
"application/x-rpm",
|
|
1761
|
+
"application/x-compress",
|
|
1762
|
+
"application/x-lzip",
|
|
1763
|
+
"application/x-cfb",
|
|
1764
|
+
"application/x-mie",
|
|
1765
|
+
"application/mxf",
|
|
1766
|
+
"video/mp2t",
|
|
1767
|
+
"application/x-blender",
|
|
1768
|
+
"image/bpg",
|
|
1769
|
+
"image/j2c",
|
|
1770
|
+
"image/jp2",
|
|
1771
|
+
"image/jpx",
|
|
1772
|
+
"image/jpm",
|
|
1773
|
+
"image/mj2",
|
|
1774
|
+
"audio/aiff",
|
|
1775
|
+
"application/xml",
|
|
1776
|
+
"application/x-mobipocket-ebook",
|
|
1777
|
+
"image/heif",
|
|
1778
|
+
"image/heif-sequence",
|
|
1779
|
+
"image/heic",
|
|
1780
|
+
"image/heic-sequence",
|
|
1781
|
+
"image/icns",
|
|
1782
|
+
"image/ktx",
|
|
1783
|
+
"application/dicom",
|
|
1784
|
+
"audio/x-musepack",
|
|
1785
|
+
"text/calendar",
|
|
1786
|
+
"text/vcard",
|
|
1787
|
+
"text/vtt",
|
|
1788
|
+
"model/gltf-binary",
|
|
1789
|
+
"application/vnd.tcpdump.pcap",
|
|
1790
|
+
"audio/x-dsf",
|
|
1791
|
+
// Non-standard
|
|
1792
|
+
"application/x.ms.shortcut",
|
|
1793
|
+
// Invented by us
|
|
1794
|
+
"application/x.apple.alias",
|
|
1795
|
+
// Invented by us
|
|
1796
|
+
"audio/x-voc",
|
|
1797
|
+
"audio/vnd.dolby.dd-raw",
|
|
1798
|
+
"audio/x-m4a",
|
|
1799
|
+
"image/apng",
|
|
1800
|
+
"image/x-olympus-orf",
|
|
1801
|
+
"image/x-sony-arw",
|
|
1802
|
+
"image/x-adobe-dng",
|
|
1803
|
+
"image/x-nikon-nef",
|
|
1804
|
+
"image/x-panasonic-rw2",
|
|
1805
|
+
"image/x-fujifilm-raf",
|
|
1806
|
+
"video/x-m4v",
|
|
1807
|
+
"video/3gpp2",
|
|
1808
|
+
"application/x-esri-shape",
|
|
1809
|
+
"audio/aac",
|
|
1810
|
+
"audio/x-it",
|
|
1811
|
+
"audio/x-s3m",
|
|
1812
|
+
"audio/x-xm",
|
|
1813
|
+
"video/MP1S",
|
|
1814
|
+
"video/MP2P",
|
|
1815
|
+
"application/vnd.sketchup.skp",
|
|
1816
|
+
"image/avif",
|
|
1817
|
+
"application/x-lzh-compressed",
|
|
1818
|
+
"application/pgp-encrypted",
|
|
1819
|
+
"application/x-asar",
|
|
1820
|
+
"model/stl",
|
|
1821
|
+
"application/vnd.ms-htmlhelp",
|
|
1822
|
+
"model/3mf",
|
|
1823
|
+
"image/jxl",
|
|
1824
|
+
"application/zstd",
|
|
1825
|
+
"image/jls",
|
|
1826
|
+
"application/vnd.ms-outlook",
|
|
1827
|
+
"image/vnd.dwg",
|
|
1828
|
+
"application/vnd.apache.parquet",
|
|
1829
|
+
"application/java-vm",
|
|
1830
|
+
"application/x-arj",
|
|
1831
|
+
"application/x-cpio",
|
|
1832
|
+
"application/x-ace-compressed",
|
|
1833
|
+
"application/avro",
|
|
1834
|
+
"application/vnd.iccprofile",
|
|
1835
|
+
"application/x.autodesk.fbx",
|
|
1836
|
+
// Invented by us
|
|
1837
|
+
"application/vnd.visio",
|
|
1838
|
+
"application/vnd.android.package-archive",
|
|
1839
|
+
"application/vnd.google.draco",
|
|
1840
|
+
// Invented by us
|
|
1841
|
+
"application/x-lz4",
|
|
1842
|
+
// Invented by us
|
|
1843
|
+
"application/vnd.openxmlformats-officedocument.presentationml.template",
|
|
1844
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.template",
|
|
1845
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.template",
|
|
1846
|
+
"application/vnd.ms-excel.template.macroenabled.12",
|
|
1847
|
+
"application/vnd.oasis.opendocument.text-template",
|
|
1848
|
+
"application/vnd.oasis.opendocument.spreadsheet-template",
|
|
1849
|
+
"application/vnd.oasis.opendocument.presentation-template",
|
|
1850
|
+
"application/vnd.oasis.opendocument.graphics",
|
|
1851
|
+
"application/vnd.oasis.opendocument.graphics-template",
|
|
1852
|
+
"application/vnd.ms-excel.sheet.macroenabled.12",
|
|
1853
|
+
"application/vnd.ms-word.document.macroenabled.12",
|
|
1854
|
+
"application/vnd.ms-word.template.macroenabled.12",
|
|
1855
|
+
"application/vnd.ms-powerpoint.template.macroenabled.12",
|
|
1856
|
+
"application/vnd.ms-powerpoint.presentation.macroenabled.12",
|
|
1857
|
+
"application/java-archive",
|
|
1858
|
+
"application/vnd.rn-realmedia",
|
|
1859
|
+
"application/x-spss-sav",
|
|
1860
|
+
"application/x-ms-regedit",
|
|
1861
|
+
"application/x-ft-windows-registry-hive",
|
|
1862
|
+
"application/x-jmp-data"
|
|
1863
|
+
];
|
|
1864
|
+
|
|
1865
|
+
// ../../node_modules/.bun/file-type@21.3.4/node_modules/file-type/core.js
|
|
1866
|
+
var reasonableDetectionSizeInBytes = 4100;
|
|
1867
|
+
var maximumMpegOffsetTolerance = reasonableDetectionSizeInBytes - 2;
|
|
1868
|
+
var maximumZipEntrySizeInBytes = 1024 * 1024;
|
|
1869
|
+
var maximumZipEntryCount = 1024;
|
|
1870
|
+
var maximumZipBufferedReadSizeInBytes = 2 ** 31 - 1;
|
|
1871
|
+
var maximumUntrustedSkipSizeInBytes = 16 * 1024 * 1024;
|
|
1872
|
+
var maximumUnknownSizePayloadProbeSizeInBytes = maximumZipEntrySizeInBytes;
|
|
1873
|
+
var maximumZipTextEntrySizeInBytes = maximumZipEntrySizeInBytes;
|
|
1874
|
+
var maximumNestedGzipDetectionSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
1875
|
+
var maximumNestedGzipProbeDepth = 1;
|
|
1876
|
+
var unknownSizeGzipProbeTimeoutInMilliseconds = 100;
|
|
1877
|
+
var maximumId3HeaderSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
1878
|
+
var maximumEbmlDocumentTypeSizeInBytes = 64;
|
|
1879
|
+
var maximumEbmlElementPayloadSizeInBytes = maximumUnknownSizePayloadProbeSizeInBytes;
|
|
1880
|
+
var maximumEbmlElementCount = 256;
|
|
1881
|
+
var maximumPngChunkCount = 512;
|
|
1882
|
+
var maximumPngStreamScanBudgetInBytes = maximumUntrustedSkipSizeInBytes;
|
|
1883
|
+
var maximumAsfHeaderObjectCount = 512;
|
|
1884
|
+
var maximumTiffTagCount = 512;
|
|
1885
|
+
var maximumDetectionReentryCount = 256;
|
|
1886
|
+
var maximumPngChunkSizeInBytes = maximumUnknownSizePayloadProbeSizeInBytes;
|
|
1887
|
+
var maximumAsfHeaderPayloadSizeInBytes = maximumUnknownSizePayloadProbeSizeInBytes;
|
|
1888
|
+
var maximumTiffStreamIfdOffsetInBytes = maximumUnknownSizePayloadProbeSizeInBytes;
|
|
1889
|
+
var maximumTiffIfdOffsetInBytes = maximumUntrustedSkipSizeInBytes;
|
|
1890
|
+
var recoverableZipErrorMessages = /* @__PURE__ */ new Set([
|
|
1891
|
+
"Unexpected signature",
|
|
1892
|
+
"Encrypted ZIP",
|
|
1893
|
+
"Expected Central-File-Header signature"
|
|
1894
|
+
]);
|
|
1895
|
+
var recoverableZipErrorMessagePrefixes = [
|
|
1896
|
+
"ZIP entry count exceeds ",
|
|
1897
|
+
"Unsupported ZIP compression method:",
|
|
1898
|
+
"ZIP entry compressed data exceeds ",
|
|
1899
|
+
"ZIP entry decompressed data exceeds ",
|
|
1900
|
+
"Expected data-descriptor-signature at position "
|
|
1901
|
+
];
|
|
1902
|
+
var recoverableZipErrorCodes = /* @__PURE__ */ new Set([
|
|
1903
|
+
"Z_BUF_ERROR",
|
|
1904
|
+
"Z_DATA_ERROR",
|
|
1905
|
+
"ERR_INVALID_STATE"
|
|
1906
|
+
]);
|
|
1907
|
+
var ParserHardLimitError = class extends Error {
|
|
1908
|
+
};
|
|
1909
|
+
function patchWebByobTokenizerClose(tokenizer) {
|
|
1910
|
+
const streamReader = tokenizer?.streamReader;
|
|
1911
|
+
if (streamReader?.constructor?.name !== "WebStreamByobReader") {
|
|
1912
|
+
return tokenizer;
|
|
1913
|
+
}
|
|
1914
|
+
const { reader } = streamReader;
|
|
1915
|
+
const cancelAndRelease = async () => {
|
|
1916
|
+
await reader.cancel();
|
|
1917
|
+
reader.releaseLock();
|
|
1918
|
+
};
|
|
1919
|
+
streamReader.close = cancelAndRelease;
|
|
1920
|
+
streamReader.abort = async () => {
|
|
1921
|
+
streamReader.interrupted = true;
|
|
1922
|
+
await cancelAndRelease();
|
|
1923
|
+
};
|
|
1924
|
+
return tokenizer;
|
|
1925
|
+
}
|
|
1926
|
+
function getSafeBound(value, maximum, reason) {
|
|
1927
|
+
if (!Number.isFinite(value) || value < 0 || value > maximum) {
|
|
1928
|
+
throw new ParserHardLimitError(`${reason} has invalid size ${value} (maximum ${maximum} bytes)`);
|
|
1929
|
+
}
|
|
1930
|
+
return value;
|
|
1931
|
+
}
|
|
1932
|
+
async function safeIgnore(tokenizer, length, { maximumLength = maximumUntrustedSkipSizeInBytes, reason = "skip" } = {}) {
|
|
1933
|
+
const safeLength = getSafeBound(length, maximumLength, reason);
|
|
1934
|
+
await tokenizer.ignore(safeLength);
|
|
1935
|
+
}
|
|
1936
|
+
async function safeReadBuffer(tokenizer, buffer, options, { maximumLength = buffer.length, reason = "read" } = {}) {
|
|
1937
|
+
const length = options?.length ?? buffer.length;
|
|
1938
|
+
const safeLength = getSafeBound(length, maximumLength, reason);
|
|
1939
|
+
return tokenizer.readBuffer(buffer, {
|
|
1940
|
+
...options,
|
|
1941
|
+
length: safeLength
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
async function decompressDeflateRawWithLimit(data, { maximumLength = maximumZipEntrySizeInBytes } = {}) {
|
|
1945
|
+
const input = new ReadableStream({
|
|
1946
|
+
start(controller) {
|
|
1947
|
+
controller.enqueue(data);
|
|
1948
|
+
controller.close();
|
|
1949
|
+
}
|
|
1950
|
+
});
|
|
1951
|
+
const output = input.pipeThrough(new DecompressionStream("deflate-raw"));
|
|
1952
|
+
const reader = output.getReader();
|
|
1953
|
+
const chunks = [];
|
|
1954
|
+
let totalLength = 0;
|
|
1955
|
+
try {
|
|
1956
|
+
for (; ; ) {
|
|
1957
|
+
const { done, value } = await reader.read();
|
|
1958
|
+
if (done) {
|
|
1959
|
+
break;
|
|
1960
|
+
}
|
|
1961
|
+
totalLength += value.length;
|
|
1962
|
+
if (totalLength > maximumLength) {
|
|
1963
|
+
await reader.cancel();
|
|
1964
|
+
throw new Error(`ZIP entry decompressed data exceeds ${maximumLength} bytes`);
|
|
1965
|
+
}
|
|
1966
|
+
chunks.push(value);
|
|
1967
|
+
}
|
|
1968
|
+
} finally {
|
|
1969
|
+
reader.releaseLock();
|
|
1970
|
+
}
|
|
1971
|
+
const uncompressedData = new Uint8Array(totalLength);
|
|
1972
|
+
let offset = 0;
|
|
1973
|
+
for (const chunk of chunks) {
|
|
1974
|
+
uncompressedData.set(chunk, offset);
|
|
1975
|
+
offset += chunk.length;
|
|
1976
|
+
}
|
|
1977
|
+
return uncompressedData;
|
|
1978
|
+
}
|
|
1979
|
+
var zipDataDescriptorSignature = 134695760;
|
|
1980
|
+
var zipDataDescriptorLengthInBytes = 16;
|
|
1981
|
+
var zipDataDescriptorOverlapLengthInBytes = zipDataDescriptorLengthInBytes - 1;
|
|
1982
|
+
function findZipDataDescriptorOffset(buffer, bytesConsumed) {
|
|
1983
|
+
if (buffer.length < zipDataDescriptorLengthInBytes) {
|
|
1984
|
+
return -1;
|
|
1985
|
+
}
|
|
1986
|
+
const lastPossibleDescriptorOffset = buffer.length - zipDataDescriptorLengthInBytes;
|
|
1987
|
+
for (let index = 0; index <= lastPossibleDescriptorOffset; index++) {
|
|
1988
|
+
if (UINT32_LE.get(buffer, index) === zipDataDescriptorSignature && UINT32_LE.get(buffer, index + 8) === bytesConsumed + index) {
|
|
1989
|
+
return index;
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
return -1;
|
|
1993
|
+
}
|
|
1994
|
+
function isPngAncillaryChunk(type) {
|
|
1995
|
+
return (type.codePointAt(0) & 32) !== 0;
|
|
1996
|
+
}
|
|
1997
|
+
function mergeByteChunks(chunks, totalLength) {
|
|
1998
|
+
const merged = new Uint8Array(totalLength);
|
|
1999
|
+
let offset = 0;
|
|
2000
|
+
for (const chunk of chunks) {
|
|
2001
|
+
merged.set(chunk, offset);
|
|
2002
|
+
offset += chunk.length;
|
|
2003
|
+
}
|
|
2004
|
+
return merged;
|
|
2005
|
+
}
|
|
2006
|
+
async function readZipDataDescriptorEntryWithLimit(zipHandler, { shouldBuffer, maximumLength = maximumZipEntrySizeInBytes } = {}) {
|
|
2007
|
+
const { syncBuffer } = zipHandler;
|
|
2008
|
+
const { length: syncBufferLength } = syncBuffer;
|
|
2009
|
+
const chunks = [];
|
|
2010
|
+
let bytesConsumed = 0;
|
|
2011
|
+
for (; ; ) {
|
|
2012
|
+
const length = await zipHandler.tokenizer.peekBuffer(syncBuffer, { mayBeLess: true });
|
|
2013
|
+
const dataDescriptorOffset = findZipDataDescriptorOffset(syncBuffer.subarray(0, length), bytesConsumed);
|
|
2014
|
+
const retainedLength = dataDescriptorOffset >= 0 ? 0 : length === syncBufferLength ? Math.min(zipDataDescriptorOverlapLengthInBytes, length - 1) : 0;
|
|
2015
|
+
const chunkLength = dataDescriptorOffset >= 0 ? dataDescriptorOffset : length - retainedLength;
|
|
2016
|
+
if (chunkLength === 0) {
|
|
2017
|
+
break;
|
|
2018
|
+
}
|
|
2019
|
+
bytesConsumed += chunkLength;
|
|
2020
|
+
if (bytesConsumed > maximumLength) {
|
|
2021
|
+
throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
|
|
2022
|
+
}
|
|
2023
|
+
if (shouldBuffer) {
|
|
2024
|
+
const data = new Uint8Array(chunkLength);
|
|
2025
|
+
await zipHandler.tokenizer.readBuffer(data);
|
|
2026
|
+
chunks.push(data);
|
|
2027
|
+
} else {
|
|
2028
|
+
await zipHandler.tokenizer.ignore(chunkLength);
|
|
2029
|
+
}
|
|
2030
|
+
if (dataDescriptorOffset >= 0) {
|
|
2031
|
+
break;
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
if (!hasUnknownFileSize(zipHandler.tokenizer)) {
|
|
2035
|
+
zipHandler.knownSizeDescriptorScannedBytes += bytesConsumed;
|
|
2036
|
+
}
|
|
2037
|
+
if (!shouldBuffer) {
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
return mergeByteChunks(chunks, bytesConsumed);
|
|
2041
|
+
}
|
|
2042
|
+
function getRemainingZipScanBudget(zipHandler, startOffset) {
|
|
2043
|
+
if (hasUnknownFileSize(zipHandler.tokenizer)) {
|
|
2044
|
+
return Math.max(0, maximumUntrustedSkipSizeInBytes - (zipHandler.tokenizer.position - startOffset));
|
|
2045
|
+
}
|
|
2046
|
+
return Math.max(0, maximumZipEntrySizeInBytes - zipHandler.knownSizeDescriptorScannedBytes);
|
|
2047
|
+
}
|
|
2048
|
+
async function readZipEntryData(zipHandler, zipHeader, { shouldBuffer, maximumDescriptorLength = maximumZipEntrySizeInBytes } = {}) {
|
|
2049
|
+
if (zipHeader.dataDescriptor && zipHeader.compressedSize === 0) {
|
|
2050
|
+
return readZipDataDescriptorEntryWithLimit(zipHandler, {
|
|
2051
|
+
shouldBuffer,
|
|
2052
|
+
maximumLength: maximumDescriptorLength
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
if (!shouldBuffer) {
|
|
2056
|
+
await safeIgnore(zipHandler.tokenizer, zipHeader.compressedSize, {
|
|
2057
|
+
maximumLength: hasUnknownFileSize(zipHandler.tokenizer) ? maximumZipEntrySizeInBytes : zipHandler.tokenizer.fileInfo.size,
|
|
2058
|
+
reason: "ZIP entry compressed data"
|
|
2059
|
+
});
|
|
2060
|
+
return;
|
|
2061
|
+
}
|
|
2062
|
+
const maximumLength = getMaximumZipBufferedReadLength(zipHandler.tokenizer);
|
|
2063
|
+
if (!Number.isFinite(zipHeader.compressedSize) || zipHeader.compressedSize < 0 || zipHeader.compressedSize > maximumLength) {
|
|
2064
|
+
throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
|
|
2065
|
+
}
|
|
2066
|
+
const fileData = new Uint8Array(zipHeader.compressedSize);
|
|
2067
|
+
await zipHandler.tokenizer.readBuffer(fileData);
|
|
2068
|
+
return fileData;
|
|
2069
|
+
}
|
|
2070
|
+
ZipHandler.prototype.inflate = async function(zipHeader, fileData, callback) {
|
|
2071
|
+
if (zipHeader.compressedMethod === 0) {
|
|
2072
|
+
return callback(fileData);
|
|
2073
|
+
}
|
|
2074
|
+
if (zipHeader.compressedMethod !== 8) {
|
|
2075
|
+
throw new Error(`Unsupported ZIP compression method: ${zipHeader.compressedMethod}`);
|
|
2076
|
+
}
|
|
2077
|
+
const uncompressedData = await decompressDeflateRawWithLimit(fileData, { maximumLength: maximumZipEntrySizeInBytes });
|
|
2078
|
+
return callback(uncompressedData);
|
|
2079
|
+
};
|
|
2080
|
+
ZipHandler.prototype.unzip = async function(fileCallback) {
|
|
2081
|
+
let stop = false;
|
|
2082
|
+
let zipEntryCount = 0;
|
|
2083
|
+
const zipScanStart = this.tokenizer.position;
|
|
2084
|
+
this.knownSizeDescriptorScannedBytes = 0;
|
|
2085
|
+
do {
|
|
2086
|
+
if (hasExceededUnknownSizeScanBudget(this.tokenizer, zipScanStart, maximumUntrustedSkipSizeInBytes)) {
|
|
2087
|
+
throw new ParserHardLimitError(`ZIP stream probing exceeds ${maximumUntrustedSkipSizeInBytes} bytes`);
|
|
2088
|
+
}
|
|
2089
|
+
const zipHeader = await this.readLocalFileHeader();
|
|
2090
|
+
if (!zipHeader) {
|
|
2091
|
+
break;
|
|
2092
|
+
}
|
|
2093
|
+
zipEntryCount++;
|
|
2094
|
+
if (zipEntryCount > maximumZipEntryCount) {
|
|
2095
|
+
throw new Error(`ZIP entry count exceeds ${maximumZipEntryCount}`);
|
|
2096
|
+
}
|
|
2097
|
+
const next = fileCallback(zipHeader);
|
|
2098
|
+
stop = Boolean(next.stop);
|
|
2099
|
+
await this.tokenizer.ignore(zipHeader.extraFieldLength);
|
|
2100
|
+
const fileData = await readZipEntryData(this, zipHeader, {
|
|
2101
|
+
shouldBuffer: Boolean(next.handler),
|
|
2102
|
+
maximumDescriptorLength: Math.min(maximumZipEntrySizeInBytes, getRemainingZipScanBudget(this, zipScanStart))
|
|
2103
|
+
});
|
|
2104
|
+
if (next.handler) {
|
|
2105
|
+
await this.inflate(zipHeader, fileData, next.handler);
|
|
2106
|
+
}
|
|
2107
|
+
if (zipHeader.dataDescriptor) {
|
|
2108
|
+
const dataDescriptor = new Uint8Array(zipDataDescriptorLengthInBytes);
|
|
2109
|
+
await this.tokenizer.readBuffer(dataDescriptor);
|
|
2110
|
+
if (UINT32_LE.get(dataDescriptor, 0) !== zipDataDescriptorSignature) {
|
|
2111
|
+
throw new Error(`Expected data-descriptor-signature at position ${this.tokenizer.position - dataDescriptor.length}`);
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
if (hasExceededUnknownSizeScanBudget(this.tokenizer, zipScanStart, maximumUntrustedSkipSizeInBytes)) {
|
|
2115
|
+
throw new ParserHardLimitError(`ZIP stream probing exceeds ${maximumUntrustedSkipSizeInBytes} bytes`);
|
|
2116
|
+
}
|
|
2117
|
+
} while (!stop);
|
|
2118
|
+
};
|
|
2119
|
+
function createByteLimitedReadableStream(stream, maximumBytes) {
|
|
2120
|
+
const reader = stream.getReader();
|
|
2121
|
+
let emittedBytes = 0;
|
|
2122
|
+
let sourceDone = false;
|
|
2123
|
+
let sourceCanceled = false;
|
|
2124
|
+
const cancelSource = async (reason) => {
|
|
2125
|
+
if (sourceDone || sourceCanceled) {
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
sourceCanceled = true;
|
|
2129
|
+
await reader.cancel(reason);
|
|
2130
|
+
};
|
|
2131
|
+
return new ReadableStream({
|
|
2132
|
+
async pull(controller) {
|
|
2133
|
+
if (emittedBytes >= maximumBytes) {
|
|
2134
|
+
controller.close();
|
|
2135
|
+
await cancelSource();
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
const { done, value } = await reader.read();
|
|
2139
|
+
if (done || !value) {
|
|
2140
|
+
sourceDone = true;
|
|
2141
|
+
controller.close();
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2144
|
+
const remainingBytes = maximumBytes - emittedBytes;
|
|
2145
|
+
if (value.length > remainingBytes) {
|
|
2146
|
+
controller.enqueue(value.subarray(0, remainingBytes));
|
|
2147
|
+
emittedBytes += remainingBytes;
|
|
2148
|
+
controller.close();
|
|
2149
|
+
await cancelSource();
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
controller.enqueue(value);
|
|
2153
|
+
emittedBytes += value.length;
|
|
2154
|
+
},
|
|
2155
|
+
async cancel(reason) {
|
|
2156
|
+
await cancelSource(reason);
|
|
2157
|
+
}
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
async function fileTypeFromBuffer(input, options) {
|
|
2161
|
+
return new FileTypeParser(options).fromBuffer(input);
|
|
2162
|
+
}
|
|
2163
|
+
async function fileTypeFromBlob(blob, options) {
|
|
2164
|
+
return new FileTypeParser(options).fromBlob(blob);
|
|
2165
|
+
}
|
|
2166
|
+
function getFileTypeFromMimeType(mimeType) {
|
|
2167
|
+
mimeType = mimeType.toLowerCase();
|
|
2168
|
+
switch (mimeType) {
|
|
2169
|
+
case "application/epub+zip":
|
|
2170
|
+
return {
|
|
2171
|
+
ext: "epub",
|
|
2172
|
+
mime: mimeType
|
|
2173
|
+
};
|
|
2174
|
+
case "application/vnd.oasis.opendocument.text":
|
|
2175
|
+
return {
|
|
2176
|
+
ext: "odt",
|
|
2177
|
+
mime: mimeType
|
|
2178
|
+
};
|
|
2179
|
+
case "application/vnd.oasis.opendocument.text-template":
|
|
2180
|
+
return {
|
|
2181
|
+
ext: "ott",
|
|
2182
|
+
mime: mimeType
|
|
2183
|
+
};
|
|
2184
|
+
case "application/vnd.oasis.opendocument.spreadsheet":
|
|
2185
|
+
return {
|
|
2186
|
+
ext: "ods",
|
|
2187
|
+
mime: mimeType
|
|
2188
|
+
};
|
|
2189
|
+
case "application/vnd.oasis.opendocument.spreadsheet-template":
|
|
2190
|
+
return {
|
|
2191
|
+
ext: "ots",
|
|
2192
|
+
mime: mimeType
|
|
2193
|
+
};
|
|
2194
|
+
case "application/vnd.oasis.opendocument.presentation":
|
|
2195
|
+
return {
|
|
2196
|
+
ext: "odp",
|
|
2197
|
+
mime: mimeType
|
|
2198
|
+
};
|
|
2199
|
+
case "application/vnd.oasis.opendocument.presentation-template":
|
|
2200
|
+
return {
|
|
2201
|
+
ext: "otp",
|
|
2202
|
+
mime: mimeType
|
|
2203
|
+
};
|
|
2204
|
+
case "application/vnd.oasis.opendocument.graphics":
|
|
2205
|
+
return {
|
|
2206
|
+
ext: "odg",
|
|
2207
|
+
mime: mimeType
|
|
2208
|
+
};
|
|
2209
|
+
case "application/vnd.oasis.opendocument.graphics-template":
|
|
2210
|
+
return {
|
|
2211
|
+
ext: "otg",
|
|
2212
|
+
mime: mimeType
|
|
2213
|
+
};
|
|
2214
|
+
case "application/vnd.openxmlformats-officedocument.presentationml.slideshow":
|
|
2215
|
+
return {
|
|
2216
|
+
ext: "ppsx",
|
|
2217
|
+
mime: mimeType
|
|
2218
|
+
};
|
|
2219
|
+
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
|
2220
|
+
return {
|
|
2221
|
+
ext: "xlsx",
|
|
2222
|
+
mime: mimeType
|
|
2223
|
+
};
|
|
2224
|
+
case "application/vnd.ms-excel.sheet.macroenabled":
|
|
2225
|
+
return {
|
|
2226
|
+
ext: "xlsm",
|
|
2227
|
+
mime: "application/vnd.ms-excel.sheet.macroenabled.12"
|
|
2228
|
+
};
|
|
2229
|
+
case "application/vnd.openxmlformats-officedocument.spreadsheetml.template":
|
|
2230
|
+
return {
|
|
2231
|
+
ext: "xltx",
|
|
2232
|
+
mime: mimeType
|
|
2233
|
+
};
|
|
2234
|
+
case "application/vnd.ms-excel.template.macroenabled":
|
|
2235
|
+
return {
|
|
2236
|
+
ext: "xltm",
|
|
2237
|
+
mime: "application/vnd.ms-excel.template.macroenabled.12"
|
|
2238
|
+
};
|
|
2239
|
+
case "application/vnd.ms-powerpoint.slideshow.macroenabled":
|
|
2240
|
+
return {
|
|
2241
|
+
ext: "ppsm",
|
|
2242
|
+
mime: "application/vnd.ms-powerpoint.slideshow.macroenabled.12"
|
|
2243
|
+
};
|
|
2244
|
+
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
|
2245
|
+
return {
|
|
2246
|
+
ext: "docx",
|
|
2247
|
+
mime: mimeType
|
|
2248
|
+
};
|
|
2249
|
+
case "application/vnd.ms-word.document.macroenabled":
|
|
2250
|
+
return {
|
|
2251
|
+
ext: "docm",
|
|
2252
|
+
mime: "application/vnd.ms-word.document.macroenabled.12"
|
|
2253
|
+
};
|
|
2254
|
+
case "application/vnd.openxmlformats-officedocument.wordprocessingml.template":
|
|
2255
|
+
return {
|
|
2256
|
+
ext: "dotx",
|
|
2257
|
+
mime: mimeType
|
|
2258
|
+
};
|
|
2259
|
+
case "application/vnd.ms-word.template.macroenabledtemplate":
|
|
2260
|
+
return {
|
|
2261
|
+
ext: "dotm",
|
|
2262
|
+
mime: "application/vnd.ms-word.template.macroenabled.12"
|
|
2263
|
+
};
|
|
2264
|
+
case "application/vnd.openxmlformats-officedocument.presentationml.template":
|
|
2265
|
+
return {
|
|
2266
|
+
ext: "potx",
|
|
2267
|
+
mime: mimeType
|
|
2268
|
+
};
|
|
2269
|
+
case "application/vnd.ms-powerpoint.template.macroenabled":
|
|
2270
|
+
return {
|
|
2271
|
+
ext: "potm",
|
|
2272
|
+
mime: "application/vnd.ms-powerpoint.template.macroenabled.12"
|
|
2273
|
+
};
|
|
2274
|
+
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
|
|
2275
|
+
return {
|
|
2276
|
+
ext: "pptx",
|
|
2277
|
+
mime: mimeType
|
|
2278
|
+
};
|
|
2279
|
+
case "application/vnd.ms-powerpoint.presentation.macroenabled":
|
|
2280
|
+
return {
|
|
2281
|
+
ext: "pptm",
|
|
2282
|
+
mime: "application/vnd.ms-powerpoint.presentation.macroenabled.12"
|
|
2283
|
+
};
|
|
2284
|
+
case "application/vnd.ms-visio.drawing":
|
|
2285
|
+
return {
|
|
2286
|
+
ext: "vsdx",
|
|
2287
|
+
mime: "application/vnd.visio"
|
|
2288
|
+
};
|
|
2289
|
+
case "application/vnd.ms-package.3dmanufacturing-3dmodel+xml":
|
|
2290
|
+
return {
|
|
2291
|
+
ext: "3mf",
|
|
2292
|
+
mime: "model/3mf"
|
|
2293
|
+
};
|
|
2294
|
+
default:
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
function _check(buffer, headers, options) {
|
|
2298
|
+
options = {
|
|
2299
|
+
offset: 0,
|
|
2300
|
+
...options
|
|
2301
|
+
};
|
|
2302
|
+
for (const [index, header] of headers.entries()) {
|
|
2303
|
+
if (options.mask) {
|
|
2304
|
+
if (header !== (options.mask[index] & buffer[index + options.offset])) {
|
|
2305
|
+
return false;
|
|
2306
|
+
}
|
|
2307
|
+
} else if (header !== buffer[index + options.offset]) {
|
|
2308
|
+
return false;
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
return true;
|
|
2312
|
+
}
|
|
2313
|
+
function normalizeSampleSize(sampleSize) {
|
|
2314
|
+
if (!Number.isFinite(sampleSize)) {
|
|
2315
|
+
return reasonableDetectionSizeInBytes;
|
|
2316
|
+
}
|
|
2317
|
+
return Math.max(1, Math.trunc(sampleSize));
|
|
2318
|
+
}
|
|
2319
|
+
function readByobReaderWithSignal(reader, buffer, signal) {
|
|
2320
|
+
if (signal === void 0) {
|
|
2321
|
+
return reader.read(buffer);
|
|
2322
|
+
}
|
|
2323
|
+
signal.throwIfAborted();
|
|
2324
|
+
return new Promise((resolve, reject) => {
|
|
2325
|
+
const cleanup = () => {
|
|
2326
|
+
signal.removeEventListener("abort", onAbort);
|
|
2327
|
+
};
|
|
2328
|
+
const onAbort = () => {
|
|
2329
|
+
const abortReason = signal.reason;
|
|
2330
|
+
cleanup();
|
|
2331
|
+
(async () => {
|
|
2332
|
+
try {
|
|
2333
|
+
await reader.cancel(abortReason);
|
|
2334
|
+
} catch {
|
|
2335
|
+
}
|
|
2336
|
+
})();
|
|
2337
|
+
reject(abortReason);
|
|
2338
|
+
};
|
|
2339
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
2340
|
+
(async () => {
|
|
2341
|
+
try {
|
|
2342
|
+
const result = await reader.read(buffer);
|
|
2343
|
+
cleanup();
|
|
2344
|
+
resolve(result);
|
|
2345
|
+
} catch (error) {
|
|
2346
|
+
cleanup();
|
|
2347
|
+
reject(error);
|
|
2348
|
+
}
|
|
2349
|
+
})();
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
function normalizeMpegOffsetTolerance(mpegOffsetTolerance) {
|
|
2353
|
+
if (!Number.isFinite(mpegOffsetTolerance)) {
|
|
2354
|
+
return 0;
|
|
2355
|
+
}
|
|
2356
|
+
return Math.max(0, Math.min(maximumMpegOffsetTolerance, Math.trunc(mpegOffsetTolerance)));
|
|
2357
|
+
}
|
|
2358
|
+
function getKnownFileSizeOrMaximum(fileSize) {
|
|
2359
|
+
if (!Number.isFinite(fileSize)) {
|
|
2360
|
+
return Number.MAX_SAFE_INTEGER;
|
|
2361
|
+
}
|
|
2362
|
+
return Math.max(0, fileSize);
|
|
2363
|
+
}
|
|
2364
|
+
function hasUnknownFileSize(tokenizer) {
|
|
2365
|
+
const fileSize = tokenizer.fileInfo.size;
|
|
2366
|
+
return !Number.isFinite(fileSize) || fileSize === Number.MAX_SAFE_INTEGER;
|
|
2367
|
+
}
|
|
2368
|
+
function hasExceededUnknownSizeScanBudget(tokenizer, startOffset, maximumBytes) {
|
|
2369
|
+
return hasUnknownFileSize(tokenizer) && tokenizer.position - startOffset > maximumBytes;
|
|
2370
|
+
}
|
|
2371
|
+
function getMaximumZipBufferedReadLength(tokenizer) {
|
|
2372
|
+
const fileSize = tokenizer.fileInfo.size;
|
|
2373
|
+
const remainingBytes = Number.isFinite(fileSize) ? Math.max(0, fileSize - tokenizer.position) : Number.MAX_SAFE_INTEGER;
|
|
2374
|
+
return Math.min(remainingBytes, maximumZipBufferedReadSizeInBytes);
|
|
2375
|
+
}
|
|
2376
|
+
function isRecoverableZipError(error) {
|
|
2377
|
+
if (error instanceof EndOfStreamError) {
|
|
2378
|
+
return true;
|
|
2379
|
+
}
|
|
2380
|
+
if (error instanceof ParserHardLimitError) {
|
|
2381
|
+
return true;
|
|
2382
|
+
}
|
|
2383
|
+
if (!(error instanceof Error)) {
|
|
2384
|
+
return false;
|
|
2385
|
+
}
|
|
2386
|
+
if (recoverableZipErrorMessages.has(error.message)) {
|
|
2387
|
+
return true;
|
|
2388
|
+
}
|
|
2389
|
+
if (recoverableZipErrorCodes.has(error.code)) {
|
|
2390
|
+
return true;
|
|
2391
|
+
}
|
|
2392
|
+
for (const prefix of recoverableZipErrorMessagePrefixes) {
|
|
2393
|
+
if (error.message.startsWith(prefix)) {
|
|
2394
|
+
return true;
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
return false;
|
|
2398
|
+
}
|
|
2399
|
+
function canReadZipEntryForDetection(zipHeader, maximumSize = maximumZipEntrySizeInBytes) {
|
|
2400
|
+
const sizes = [zipHeader.compressedSize, zipHeader.uncompressedSize];
|
|
2401
|
+
for (const size of sizes) {
|
|
2402
|
+
if (!Number.isFinite(size) || size < 0 || size > maximumSize) {
|
|
2403
|
+
return false;
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
return true;
|
|
2407
|
+
}
|
|
2408
|
+
function createOpenXmlZipDetectionState() {
|
|
2409
|
+
return {
|
|
2410
|
+
hasContentTypesEntry: false,
|
|
2411
|
+
hasParsedContentTypesEntry: false,
|
|
2412
|
+
isParsingContentTypes: false,
|
|
2413
|
+
hasUnparseableContentTypes: false,
|
|
2414
|
+
hasWordDirectory: false,
|
|
2415
|
+
hasPresentationDirectory: false,
|
|
2416
|
+
hasSpreadsheetDirectory: false,
|
|
2417
|
+
hasThreeDimensionalModelEntry: false
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
function updateOpenXmlZipDetectionStateFromFilename(openXmlState, filename) {
|
|
2421
|
+
if (filename.startsWith("word/")) {
|
|
2422
|
+
openXmlState.hasWordDirectory = true;
|
|
2423
|
+
}
|
|
2424
|
+
if (filename.startsWith("ppt/")) {
|
|
2425
|
+
openXmlState.hasPresentationDirectory = true;
|
|
2426
|
+
}
|
|
2427
|
+
if (filename.startsWith("xl/")) {
|
|
2428
|
+
openXmlState.hasSpreadsheetDirectory = true;
|
|
2429
|
+
}
|
|
2430
|
+
if (filename.startsWith("3D/") && filename.endsWith(".model")) {
|
|
2431
|
+
openXmlState.hasThreeDimensionalModelEntry = true;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
function getOpenXmlFileTypeFromZipEntries(openXmlState) {
|
|
2435
|
+
if (!openXmlState.hasContentTypesEntry || openXmlState.hasUnparseableContentTypes || openXmlState.isParsingContentTypes || openXmlState.hasParsedContentTypesEntry) {
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
if (openXmlState.hasWordDirectory) {
|
|
2439
|
+
return {
|
|
2440
|
+
ext: "docx",
|
|
2441
|
+
mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2444
|
+
if (openXmlState.hasPresentationDirectory) {
|
|
2445
|
+
return {
|
|
2446
|
+
ext: "pptx",
|
|
2447
|
+
mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
2448
|
+
};
|
|
2449
|
+
}
|
|
2450
|
+
if (openXmlState.hasSpreadsheetDirectory) {
|
|
2451
|
+
return {
|
|
2452
|
+
ext: "xlsx",
|
|
2453
|
+
mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
2454
|
+
};
|
|
2455
|
+
}
|
|
2456
|
+
if (openXmlState.hasThreeDimensionalModelEntry) {
|
|
2457
|
+
return {
|
|
2458
|
+
ext: "3mf",
|
|
2459
|
+
mime: "model/3mf"
|
|
2460
|
+
};
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
function getOpenXmlMimeTypeFromContentTypesXml(xmlContent) {
|
|
2464
|
+
const endPosition = xmlContent.indexOf('.main+xml"');
|
|
2465
|
+
if (endPosition === -1) {
|
|
2466
|
+
const mimeType = "application/vnd.ms-package.3dmanufacturing-3dmodel+xml";
|
|
2467
|
+
if (xmlContent.includes(`ContentType="${mimeType}"`)) {
|
|
2468
|
+
return mimeType;
|
|
2469
|
+
}
|
|
2470
|
+
return;
|
|
2471
|
+
}
|
|
2472
|
+
const truncatedContent = xmlContent.slice(0, endPosition);
|
|
2473
|
+
const firstQuotePosition = truncatedContent.lastIndexOf('"');
|
|
2474
|
+
return truncatedContent.slice(firstQuotePosition + 1);
|
|
2475
|
+
}
|
|
2476
|
+
async function fileTypeFromTokenizer(tokenizer, options) {
|
|
2477
|
+
return new FileTypeParser(options).fromTokenizer(tokenizer);
|
|
2478
|
+
}
|
|
2479
|
+
var FileTypeParser = class _FileTypeParser {
|
|
2480
|
+
constructor(options) {
|
|
2481
|
+
const normalizedMpegOffsetTolerance = normalizeMpegOffsetTolerance(options?.mpegOffsetTolerance);
|
|
2482
|
+
this.options = {
|
|
2483
|
+
...options,
|
|
2484
|
+
mpegOffsetTolerance: normalizedMpegOffsetTolerance
|
|
2485
|
+
};
|
|
2486
|
+
this.detectors = [
|
|
2487
|
+
...this.options.customDetectors ?? [],
|
|
2488
|
+
{ id: "core", detect: this.detectConfident },
|
|
2489
|
+
{ id: "core.imprecise", detect: this.detectImprecise }
|
|
2490
|
+
];
|
|
2491
|
+
this.tokenizerOptions = {
|
|
2492
|
+
abortSignal: this.options.signal
|
|
2493
|
+
};
|
|
2494
|
+
this.gzipProbeDepth = 0;
|
|
2495
|
+
}
|
|
2496
|
+
getTokenizerOptions() {
|
|
2497
|
+
return {
|
|
2498
|
+
...this.tokenizerOptions
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
createTokenizerFromWebStream(stream) {
|
|
2502
|
+
return patchWebByobTokenizerClose(fromWebStream(stream, this.getTokenizerOptions()));
|
|
2503
|
+
}
|
|
2504
|
+
async parseTokenizer(tokenizer, detectionReentryCount = 0) {
|
|
2505
|
+
this.detectionReentryCount = detectionReentryCount;
|
|
2506
|
+
const initialPosition = tokenizer.position;
|
|
2507
|
+
for (const detector of this.detectors) {
|
|
2508
|
+
let fileType;
|
|
2509
|
+
try {
|
|
2510
|
+
fileType = await detector.detect(tokenizer);
|
|
2511
|
+
} catch (error) {
|
|
2512
|
+
if (error instanceof EndOfStreamError) {
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
if (error instanceof ParserHardLimitError) {
|
|
2516
|
+
return;
|
|
2517
|
+
}
|
|
2518
|
+
throw error;
|
|
2519
|
+
}
|
|
2520
|
+
if (fileType) {
|
|
2521
|
+
return fileType;
|
|
2522
|
+
}
|
|
2523
|
+
if (initialPosition !== tokenizer.position) {
|
|
2524
|
+
return void 0;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
async fromTokenizer(tokenizer) {
|
|
2529
|
+
try {
|
|
2530
|
+
return await this.parseTokenizer(tokenizer);
|
|
2531
|
+
} finally {
|
|
2532
|
+
await tokenizer.close();
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
async fromBuffer(input) {
|
|
2536
|
+
if (!(input instanceof Uint8Array || input instanceof ArrayBuffer)) {
|
|
2537
|
+
throw new TypeError(`Expected the \`input\` argument to be of type \`Uint8Array\` or \`ArrayBuffer\`, got \`${typeof input}\``);
|
|
2538
|
+
}
|
|
2539
|
+
const buffer = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
2540
|
+
if (!(buffer?.length > 1)) {
|
|
2541
|
+
return;
|
|
2542
|
+
}
|
|
2543
|
+
return this.fromTokenizer(fromBuffer(buffer, this.getTokenizerOptions()));
|
|
2544
|
+
}
|
|
2545
|
+
async fromBlob(blob) {
|
|
2546
|
+
this.options.signal?.throwIfAborted();
|
|
2547
|
+
const tokenizer = fromBlob(blob, this.getTokenizerOptions());
|
|
2548
|
+
return this.fromTokenizer(tokenizer);
|
|
2549
|
+
}
|
|
2550
|
+
async fromStream(stream) {
|
|
2551
|
+
this.options.signal?.throwIfAborted();
|
|
2552
|
+
const tokenizer = this.createTokenizerFromWebStream(stream);
|
|
2553
|
+
return this.fromTokenizer(tokenizer);
|
|
2554
|
+
}
|
|
2555
|
+
async toDetectionStream(stream, options) {
|
|
2556
|
+
const sampleSize = normalizeSampleSize(options?.sampleSize ?? reasonableDetectionSizeInBytes);
|
|
2557
|
+
let detectedFileType;
|
|
2558
|
+
let firstChunk;
|
|
2559
|
+
const reader = stream.getReader({ mode: "byob" });
|
|
2560
|
+
try {
|
|
2561
|
+
const { value: chunk, done } = await readByobReaderWithSignal(reader, new Uint8Array(sampleSize), this.options.signal);
|
|
2562
|
+
firstChunk = chunk;
|
|
2563
|
+
if (!done && chunk) {
|
|
2564
|
+
try {
|
|
2565
|
+
detectedFileType = await this.fromBuffer(chunk.subarray(0, sampleSize));
|
|
2566
|
+
} catch (error) {
|
|
2567
|
+
if (!(error instanceof EndOfStreamError)) {
|
|
2568
|
+
throw error;
|
|
2569
|
+
}
|
|
2570
|
+
detectedFileType = void 0;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
firstChunk = chunk;
|
|
2574
|
+
} finally {
|
|
2575
|
+
reader.releaseLock();
|
|
2576
|
+
}
|
|
2577
|
+
const transformStream = new TransformStream({
|
|
2578
|
+
async start(controller) {
|
|
2579
|
+
controller.enqueue(firstChunk);
|
|
2580
|
+
},
|
|
2581
|
+
transform(chunk, controller) {
|
|
2582
|
+
controller.enqueue(chunk);
|
|
2583
|
+
}
|
|
2584
|
+
});
|
|
2585
|
+
const newStream = stream.pipeThrough(transformStream);
|
|
2586
|
+
newStream.fileType = detectedFileType;
|
|
2587
|
+
return newStream;
|
|
2588
|
+
}
|
|
2589
|
+
async detectGzip(tokenizer) {
|
|
2590
|
+
if (this.gzipProbeDepth >= maximumNestedGzipProbeDepth) {
|
|
2591
|
+
return {
|
|
2592
|
+
ext: "gz",
|
|
2593
|
+
mime: "application/gzip"
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
const gzipHandler = new GzipHandler(tokenizer);
|
|
2597
|
+
const limitedInflatedStream = createByteLimitedReadableStream(gzipHandler.inflate(), maximumNestedGzipDetectionSizeInBytes);
|
|
2598
|
+
const hasUnknownSize = hasUnknownFileSize(tokenizer);
|
|
2599
|
+
let timeout;
|
|
2600
|
+
let probeSignal;
|
|
2601
|
+
let probeParser;
|
|
2602
|
+
let compressedFileType;
|
|
2603
|
+
if (hasUnknownSize) {
|
|
2604
|
+
const timeoutController = new AbortController();
|
|
2605
|
+
timeout = setTimeout(() => {
|
|
2606
|
+
timeoutController.abort(new DOMException(`Operation timed out after ${unknownSizeGzipProbeTimeoutInMilliseconds} ms`, "TimeoutError"));
|
|
2607
|
+
}, unknownSizeGzipProbeTimeoutInMilliseconds);
|
|
2608
|
+
probeSignal = this.options.signal === void 0 ? timeoutController.signal : AbortSignal.any([this.options.signal, timeoutController.signal]);
|
|
2609
|
+
probeParser = new _FileTypeParser({
|
|
2610
|
+
...this.options,
|
|
2611
|
+
signal: probeSignal
|
|
2612
|
+
});
|
|
2613
|
+
probeParser.gzipProbeDepth = this.gzipProbeDepth + 1;
|
|
2614
|
+
} else {
|
|
2615
|
+
this.gzipProbeDepth++;
|
|
2616
|
+
}
|
|
2617
|
+
try {
|
|
2618
|
+
compressedFileType = await (probeParser ?? this).fromStream(limitedInflatedStream);
|
|
2619
|
+
} catch (error) {
|
|
2620
|
+
if (error?.name === "AbortError" && probeSignal?.reason?.name !== "TimeoutError") {
|
|
2621
|
+
throw error;
|
|
2622
|
+
}
|
|
2623
|
+
} finally {
|
|
2624
|
+
clearTimeout(timeout);
|
|
2625
|
+
if (!hasUnknownSize) {
|
|
2626
|
+
this.gzipProbeDepth--;
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
if (compressedFileType?.ext === "tar") {
|
|
2630
|
+
return {
|
|
2631
|
+
ext: "tar.gz",
|
|
2632
|
+
mime: "application/gzip"
|
|
2633
|
+
};
|
|
2634
|
+
}
|
|
2635
|
+
return {
|
|
2636
|
+
ext: "gz",
|
|
2637
|
+
mime: "application/gzip"
|
|
2638
|
+
};
|
|
2639
|
+
}
|
|
2640
|
+
check(header, options) {
|
|
2641
|
+
return _check(this.buffer, header, options);
|
|
2642
|
+
}
|
|
2643
|
+
checkString(header, options) {
|
|
2644
|
+
return this.check(stringToBytes(header, options?.encoding), options);
|
|
2645
|
+
}
|
|
2646
|
+
// Detections with a high degree of certainty in identifying the correct file type
|
|
2647
|
+
detectConfident = async (tokenizer) => {
|
|
2648
|
+
this.buffer = new Uint8Array(reasonableDetectionSizeInBytes);
|
|
2649
|
+
if (tokenizer.fileInfo.size === void 0) {
|
|
2650
|
+
tokenizer.fileInfo.size = Number.MAX_SAFE_INTEGER;
|
|
2651
|
+
}
|
|
2652
|
+
this.tokenizer = tokenizer;
|
|
2653
|
+
if (hasUnknownFileSize(tokenizer)) {
|
|
2654
|
+
await tokenizer.peekBuffer(this.buffer, { length: 3, mayBeLess: true });
|
|
2655
|
+
if (this.check([31, 139, 8])) {
|
|
2656
|
+
return this.detectGzip(tokenizer);
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
await tokenizer.peekBuffer(this.buffer, { length: 32, mayBeLess: true });
|
|
2660
|
+
if (this.check([66, 77])) {
|
|
2661
|
+
return {
|
|
2662
|
+
ext: "bmp",
|
|
2663
|
+
mime: "image/bmp"
|
|
2664
|
+
};
|
|
2665
|
+
}
|
|
2666
|
+
if (this.check([11, 119])) {
|
|
2667
|
+
return {
|
|
2668
|
+
ext: "ac3",
|
|
2669
|
+
mime: "audio/vnd.dolby.dd-raw"
|
|
2670
|
+
};
|
|
2671
|
+
}
|
|
2672
|
+
if (this.check([120, 1])) {
|
|
2673
|
+
return {
|
|
2674
|
+
ext: "dmg",
|
|
2675
|
+
mime: "application/x-apple-diskimage"
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
if (this.check([77, 90])) {
|
|
2679
|
+
return {
|
|
2680
|
+
ext: "exe",
|
|
2681
|
+
mime: "application/x-msdownload"
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
if (this.check([37, 33])) {
|
|
2685
|
+
await tokenizer.peekBuffer(this.buffer, { length: 24, mayBeLess: true });
|
|
2686
|
+
if (this.checkString("PS-Adobe-", { offset: 2 }) && this.checkString(" EPSF-", { offset: 14 })) {
|
|
2687
|
+
return {
|
|
2688
|
+
ext: "eps",
|
|
2689
|
+
mime: "application/eps"
|
|
2690
|
+
};
|
|
2691
|
+
}
|
|
2692
|
+
return {
|
|
2693
|
+
ext: "ps",
|
|
2694
|
+
mime: "application/postscript"
|
|
2695
|
+
};
|
|
2696
|
+
}
|
|
2697
|
+
if (this.check([31, 160]) || this.check([31, 157])) {
|
|
2698
|
+
return {
|
|
2699
|
+
ext: "Z",
|
|
2700
|
+
mime: "application/x-compress"
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
if (this.check([199, 113])) {
|
|
2704
|
+
return {
|
|
2705
|
+
ext: "cpio",
|
|
2706
|
+
mime: "application/x-cpio"
|
|
2707
|
+
};
|
|
2708
|
+
}
|
|
2709
|
+
if (this.check([96, 234])) {
|
|
2710
|
+
return {
|
|
2711
|
+
ext: "arj",
|
|
2712
|
+
mime: "application/x-arj"
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
if (this.check([239, 187, 191])) {
|
|
2716
|
+
if (this.detectionReentryCount >= maximumDetectionReentryCount) {
|
|
2717
|
+
return;
|
|
2718
|
+
}
|
|
2719
|
+
this.detectionReentryCount++;
|
|
2720
|
+
await this.tokenizer.ignore(3);
|
|
2721
|
+
return this.detectConfident(tokenizer);
|
|
2722
|
+
}
|
|
2723
|
+
if (this.check([71, 73, 70])) {
|
|
2724
|
+
return {
|
|
2725
|
+
ext: "gif",
|
|
2726
|
+
mime: "image/gif"
|
|
2727
|
+
};
|
|
2728
|
+
}
|
|
2729
|
+
if (this.check([73, 73, 188])) {
|
|
2730
|
+
return {
|
|
2731
|
+
ext: "jxr",
|
|
2732
|
+
mime: "image/vnd.ms-photo"
|
|
2733
|
+
};
|
|
2734
|
+
}
|
|
2735
|
+
if (this.check([31, 139, 8])) {
|
|
2736
|
+
return this.detectGzip(tokenizer);
|
|
2737
|
+
}
|
|
2738
|
+
if (this.check([66, 90, 104])) {
|
|
2739
|
+
return {
|
|
2740
|
+
ext: "bz2",
|
|
2741
|
+
mime: "application/x-bzip2"
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
if (this.checkString("ID3")) {
|
|
2745
|
+
await safeIgnore(tokenizer, 6, {
|
|
2746
|
+
maximumLength: 6,
|
|
2747
|
+
reason: "ID3 header prefix"
|
|
2748
|
+
});
|
|
2749
|
+
const id3HeaderLength = await tokenizer.readToken(uint32SyncSafeToken);
|
|
2750
|
+
const isUnknownFileSize = hasUnknownFileSize(tokenizer);
|
|
2751
|
+
if (!Number.isFinite(id3HeaderLength) || id3HeaderLength < 0 || isUnknownFileSize && (id3HeaderLength > maximumId3HeaderSizeInBytes || tokenizer.position + id3HeaderLength > maximumId3HeaderSizeInBytes)) {
|
|
2752
|
+
return;
|
|
2753
|
+
}
|
|
2754
|
+
if (tokenizer.position + id3HeaderLength > tokenizer.fileInfo.size) {
|
|
2755
|
+
if (isUnknownFileSize) {
|
|
2756
|
+
return;
|
|
2757
|
+
}
|
|
2758
|
+
return {
|
|
2759
|
+
ext: "mp3",
|
|
2760
|
+
mime: "audio/mpeg"
|
|
2761
|
+
};
|
|
2762
|
+
}
|
|
2763
|
+
try {
|
|
2764
|
+
await safeIgnore(tokenizer, id3HeaderLength, {
|
|
2765
|
+
maximumLength: isUnknownFileSize ? maximumId3HeaderSizeInBytes : tokenizer.fileInfo.size,
|
|
2766
|
+
reason: "ID3 payload"
|
|
2767
|
+
});
|
|
2768
|
+
} catch (error) {
|
|
2769
|
+
if (error instanceof EndOfStreamError) {
|
|
2770
|
+
return;
|
|
2771
|
+
}
|
|
2772
|
+
throw error;
|
|
2773
|
+
}
|
|
2774
|
+
if (this.detectionReentryCount >= maximumDetectionReentryCount) {
|
|
2775
|
+
return;
|
|
2776
|
+
}
|
|
2777
|
+
this.detectionReentryCount++;
|
|
2778
|
+
return this.parseTokenizer(tokenizer, this.detectionReentryCount);
|
|
2779
|
+
}
|
|
2780
|
+
if (this.checkString("MP+")) {
|
|
2781
|
+
return {
|
|
2782
|
+
ext: "mpc",
|
|
2783
|
+
mime: "audio/x-musepack"
|
|
2784
|
+
};
|
|
2785
|
+
}
|
|
2786
|
+
if ((this.buffer[0] === 67 || this.buffer[0] === 70) && this.check([87, 83], { offset: 1 })) {
|
|
2787
|
+
return {
|
|
2788
|
+
ext: "swf",
|
|
2789
|
+
mime: "application/x-shockwave-flash"
|
|
2790
|
+
};
|
|
2791
|
+
}
|
|
2792
|
+
if (this.check([255, 216, 255])) {
|
|
2793
|
+
if (this.check([247], { offset: 3 })) {
|
|
2794
|
+
return {
|
|
2795
|
+
ext: "jls",
|
|
2796
|
+
mime: "image/jls"
|
|
2797
|
+
};
|
|
2798
|
+
}
|
|
2799
|
+
return {
|
|
2800
|
+
ext: "jpg",
|
|
2801
|
+
mime: "image/jpeg"
|
|
2802
|
+
};
|
|
2803
|
+
}
|
|
2804
|
+
if (this.check([79, 98, 106, 1])) {
|
|
2805
|
+
return {
|
|
2806
|
+
ext: "avro",
|
|
2807
|
+
mime: "application/avro"
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
if (this.checkString("FLIF")) {
|
|
2811
|
+
return {
|
|
2812
|
+
ext: "flif",
|
|
2813
|
+
mime: "image/flif"
|
|
2814
|
+
};
|
|
2815
|
+
}
|
|
2816
|
+
if (this.checkString("8BPS")) {
|
|
2817
|
+
return {
|
|
2818
|
+
ext: "psd",
|
|
2819
|
+
mime: "image/vnd.adobe.photoshop"
|
|
2820
|
+
};
|
|
2821
|
+
}
|
|
2822
|
+
if (this.checkString("MPCK")) {
|
|
2823
|
+
return {
|
|
2824
|
+
ext: "mpc",
|
|
2825
|
+
mime: "audio/x-musepack"
|
|
2826
|
+
};
|
|
2827
|
+
}
|
|
2828
|
+
if (this.checkString("FORM")) {
|
|
2829
|
+
return {
|
|
2830
|
+
ext: "aif",
|
|
2831
|
+
mime: "audio/aiff"
|
|
2832
|
+
};
|
|
2833
|
+
}
|
|
2834
|
+
if (this.checkString("icns", { offset: 0 })) {
|
|
2835
|
+
return {
|
|
2836
|
+
ext: "icns",
|
|
2837
|
+
mime: "image/icns"
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2840
|
+
if (this.check([80, 75, 3, 4])) {
|
|
2841
|
+
let fileType;
|
|
2842
|
+
const openXmlState = createOpenXmlZipDetectionState();
|
|
2843
|
+
try {
|
|
2844
|
+
await new ZipHandler(tokenizer).unzip((zipHeader) => {
|
|
2845
|
+
updateOpenXmlZipDetectionStateFromFilename(openXmlState, zipHeader.filename);
|
|
2846
|
+
const isOpenXmlContentTypesEntry = zipHeader.filename === "[Content_Types].xml";
|
|
2847
|
+
const openXmlFileTypeFromEntries = getOpenXmlFileTypeFromZipEntries(openXmlState);
|
|
2848
|
+
if (!isOpenXmlContentTypesEntry && openXmlFileTypeFromEntries) {
|
|
2849
|
+
fileType = openXmlFileTypeFromEntries;
|
|
2850
|
+
return {
|
|
2851
|
+
stop: true
|
|
2852
|
+
};
|
|
2853
|
+
}
|
|
2854
|
+
switch (zipHeader.filename) {
|
|
2855
|
+
case "META-INF/mozilla.rsa":
|
|
2856
|
+
fileType = {
|
|
2857
|
+
ext: "xpi",
|
|
2858
|
+
mime: "application/x-xpinstall"
|
|
2859
|
+
};
|
|
2860
|
+
return {
|
|
2861
|
+
stop: true
|
|
2862
|
+
};
|
|
2863
|
+
case "META-INF/MANIFEST.MF":
|
|
2864
|
+
fileType = {
|
|
2865
|
+
ext: "jar",
|
|
2866
|
+
mime: "application/java-archive"
|
|
2867
|
+
};
|
|
2868
|
+
return {
|
|
2869
|
+
stop: true
|
|
2870
|
+
};
|
|
2871
|
+
case "mimetype":
|
|
2872
|
+
if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) {
|
|
2873
|
+
return {};
|
|
2874
|
+
}
|
|
2875
|
+
return {
|
|
2876
|
+
async handler(fileData) {
|
|
2877
|
+
const mimeType = new TextDecoder("utf-8").decode(fileData).trim();
|
|
2878
|
+
fileType = getFileTypeFromMimeType(mimeType);
|
|
2879
|
+
},
|
|
2880
|
+
stop: true
|
|
2881
|
+
};
|
|
2882
|
+
case "[Content_Types].xml": {
|
|
2883
|
+
openXmlState.hasContentTypesEntry = true;
|
|
2884
|
+
if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) {
|
|
2885
|
+
openXmlState.hasUnparseableContentTypes = true;
|
|
2886
|
+
return {};
|
|
2887
|
+
}
|
|
2888
|
+
openXmlState.isParsingContentTypes = true;
|
|
2889
|
+
return {
|
|
2890
|
+
async handler(fileData) {
|
|
2891
|
+
const xmlContent = new TextDecoder("utf-8").decode(fileData);
|
|
2892
|
+
const mimeType = getOpenXmlMimeTypeFromContentTypesXml(xmlContent);
|
|
2893
|
+
if (mimeType) {
|
|
2894
|
+
fileType = getFileTypeFromMimeType(mimeType);
|
|
2895
|
+
}
|
|
2896
|
+
openXmlState.hasParsedContentTypesEntry = true;
|
|
2897
|
+
openXmlState.isParsingContentTypes = false;
|
|
2898
|
+
},
|
|
2899
|
+
stop: true
|
|
2900
|
+
};
|
|
2901
|
+
}
|
|
2902
|
+
default:
|
|
2903
|
+
if (/classes\d*\.dex/.test(zipHeader.filename)) {
|
|
2904
|
+
fileType = {
|
|
2905
|
+
ext: "apk",
|
|
2906
|
+
mime: "application/vnd.android.package-archive"
|
|
2907
|
+
};
|
|
2908
|
+
return { stop: true };
|
|
2909
|
+
}
|
|
2910
|
+
return {};
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
2913
|
+
} catch (error) {
|
|
2914
|
+
if (!isRecoverableZipError(error)) {
|
|
2915
|
+
throw error;
|
|
2916
|
+
}
|
|
2917
|
+
if (openXmlState.isParsingContentTypes) {
|
|
2918
|
+
openXmlState.isParsingContentTypes = false;
|
|
2919
|
+
openXmlState.hasUnparseableContentTypes = true;
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
return fileType ?? getOpenXmlFileTypeFromZipEntries(openXmlState) ?? {
|
|
2923
|
+
ext: "zip",
|
|
2924
|
+
mime: "application/zip"
|
|
2925
|
+
};
|
|
2926
|
+
}
|
|
2927
|
+
if (this.checkString("OggS")) {
|
|
2928
|
+
await tokenizer.ignore(28);
|
|
2929
|
+
const type = new Uint8Array(8);
|
|
2930
|
+
await tokenizer.readBuffer(type);
|
|
2931
|
+
if (_check(type, [79, 112, 117, 115, 72, 101, 97, 100])) {
|
|
2932
|
+
return {
|
|
2933
|
+
ext: "opus",
|
|
2934
|
+
mime: "audio/ogg; codecs=opus"
|
|
2935
|
+
};
|
|
2936
|
+
}
|
|
2937
|
+
if (_check(type, [128, 116, 104, 101, 111, 114, 97])) {
|
|
2938
|
+
return {
|
|
2939
|
+
ext: "ogv",
|
|
2940
|
+
mime: "video/ogg"
|
|
2941
|
+
};
|
|
2942
|
+
}
|
|
2943
|
+
if (_check(type, [1, 118, 105, 100, 101, 111, 0])) {
|
|
2944
|
+
return {
|
|
2945
|
+
ext: "ogm",
|
|
2946
|
+
mime: "video/ogg"
|
|
2947
|
+
};
|
|
2948
|
+
}
|
|
2949
|
+
if (_check(type, [127, 70, 76, 65, 67])) {
|
|
2950
|
+
return {
|
|
2951
|
+
ext: "oga",
|
|
2952
|
+
mime: "audio/ogg"
|
|
2953
|
+
};
|
|
2954
|
+
}
|
|
2955
|
+
if (_check(type, [83, 112, 101, 101, 120, 32, 32])) {
|
|
2956
|
+
return {
|
|
2957
|
+
ext: "spx",
|
|
2958
|
+
mime: "audio/ogg"
|
|
2959
|
+
};
|
|
2960
|
+
}
|
|
2961
|
+
if (_check(type, [1, 118, 111, 114, 98, 105, 115])) {
|
|
2962
|
+
return {
|
|
2963
|
+
ext: "ogg",
|
|
2964
|
+
mime: "audio/ogg"
|
|
2965
|
+
};
|
|
2966
|
+
}
|
|
2967
|
+
return {
|
|
2968
|
+
ext: "ogx",
|
|
2969
|
+
mime: "application/ogg"
|
|
2970
|
+
};
|
|
2971
|
+
}
|
|
2972
|
+
if (this.check([80, 75]) && (this.buffer[2] === 3 || this.buffer[2] === 5 || this.buffer[2] === 7) && (this.buffer[3] === 4 || this.buffer[3] === 6 || this.buffer[3] === 8)) {
|
|
2973
|
+
return {
|
|
2974
|
+
ext: "zip",
|
|
2975
|
+
mime: "application/zip"
|
|
2976
|
+
};
|
|
2977
|
+
}
|
|
2978
|
+
if (this.checkString("MThd")) {
|
|
2979
|
+
return {
|
|
2980
|
+
ext: "mid",
|
|
2981
|
+
mime: "audio/midi"
|
|
2982
|
+
};
|
|
2983
|
+
}
|
|
2984
|
+
if (this.checkString("wOFF") && (this.check([0, 1, 0, 0], { offset: 4 }) || this.checkString("OTTO", { offset: 4 }))) {
|
|
2985
|
+
return {
|
|
2986
|
+
ext: "woff",
|
|
2987
|
+
mime: "font/woff"
|
|
2988
|
+
};
|
|
2989
|
+
}
|
|
2990
|
+
if (this.checkString("wOF2") && (this.check([0, 1, 0, 0], { offset: 4 }) || this.checkString("OTTO", { offset: 4 }))) {
|
|
2991
|
+
return {
|
|
2992
|
+
ext: "woff2",
|
|
2993
|
+
mime: "font/woff2"
|
|
2994
|
+
};
|
|
2995
|
+
}
|
|
2996
|
+
if (this.check([212, 195, 178, 161]) || this.check([161, 178, 195, 212])) {
|
|
2997
|
+
return {
|
|
2998
|
+
ext: "pcap",
|
|
2999
|
+
mime: "application/vnd.tcpdump.pcap"
|
|
3000
|
+
};
|
|
3001
|
+
}
|
|
3002
|
+
if (this.checkString("DSD ")) {
|
|
3003
|
+
return {
|
|
3004
|
+
ext: "dsf",
|
|
3005
|
+
mime: "audio/x-dsf"
|
|
3006
|
+
// Non-standard
|
|
3007
|
+
};
|
|
3008
|
+
}
|
|
3009
|
+
if (this.checkString("LZIP")) {
|
|
3010
|
+
return {
|
|
3011
|
+
ext: "lz",
|
|
3012
|
+
mime: "application/x-lzip"
|
|
3013
|
+
};
|
|
3014
|
+
}
|
|
3015
|
+
if (this.checkString("fLaC")) {
|
|
3016
|
+
return {
|
|
3017
|
+
ext: "flac",
|
|
3018
|
+
mime: "audio/flac"
|
|
3019
|
+
};
|
|
3020
|
+
}
|
|
3021
|
+
if (this.check([66, 80, 71, 251])) {
|
|
3022
|
+
return {
|
|
3023
|
+
ext: "bpg",
|
|
3024
|
+
mime: "image/bpg"
|
|
3025
|
+
};
|
|
3026
|
+
}
|
|
3027
|
+
if (this.checkString("wvpk")) {
|
|
3028
|
+
return {
|
|
3029
|
+
ext: "wv",
|
|
3030
|
+
mime: "audio/wavpack"
|
|
3031
|
+
};
|
|
3032
|
+
}
|
|
3033
|
+
if (this.checkString("%PDF")) {
|
|
3034
|
+
return {
|
|
3035
|
+
ext: "pdf",
|
|
3036
|
+
mime: "application/pdf"
|
|
3037
|
+
};
|
|
3038
|
+
}
|
|
3039
|
+
if (this.check([0, 97, 115, 109])) {
|
|
3040
|
+
return {
|
|
3041
|
+
ext: "wasm",
|
|
3042
|
+
mime: "application/wasm"
|
|
3043
|
+
};
|
|
3044
|
+
}
|
|
3045
|
+
if (this.check([73, 73])) {
|
|
3046
|
+
const fileType = await this.readTiffHeader(false);
|
|
3047
|
+
if (fileType) {
|
|
3048
|
+
return fileType;
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
if (this.check([77, 77])) {
|
|
3052
|
+
const fileType = await this.readTiffHeader(true);
|
|
3053
|
+
if (fileType) {
|
|
3054
|
+
return fileType;
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
if (this.checkString("MAC ")) {
|
|
3058
|
+
return {
|
|
3059
|
+
ext: "ape",
|
|
3060
|
+
mime: "audio/ape"
|
|
3061
|
+
};
|
|
3062
|
+
}
|
|
3063
|
+
if (this.check([26, 69, 223, 163])) {
|
|
3064
|
+
async function readField() {
|
|
3065
|
+
const msb = await tokenizer.peekNumber(UINT8);
|
|
3066
|
+
let mask = 128;
|
|
3067
|
+
let ic = 0;
|
|
3068
|
+
while ((msb & mask) === 0 && mask !== 0) {
|
|
3069
|
+
++ic;
|
|
3070
|
+
mask >>= 1;
|
|
3071
|
+
}
|
|
3072
|
+
const id = new Uint8Array(ic + 1);
|
|
3073
|
+
await safeReadBuffer(tokenizer, id, void 0, {
|
|
3074
|
+
maximumLength: id.length,
|
|
3075
|
+
reason: "EBML field"
|
|
3076
|
+
});
|
|
3077
|
+
return id;
|
|
3078
|
+
}
|
|
3079
|
+
async function readElement() {
|
|
3080
|
+
const idField = await readField();
|
|
3081
|
+
const lengthField = await readField();
|
|
3082
|
+
lengthField[0] ^= 128 >> lengthField.length - 1;
|
|
3083
|
+
const nrLength = Math.min(6, lengthField.length);
|
|
3084
|
+
const idView = new DataView(idField.buffer);
|
|
3085
|
+
const lengthView = new DataView(lengthField.buffer, lengthField.length - nrLength, nrLength);
|
|
3086
|
+
return {
|
|
3087
|
+
id: getUintBE(idView),
|
|
3088
|
+
len: getUintBE(lengthView)
|
|
3089
|
+
};
|
|
3090
|
+
}
|
|
3091
|
+
async function readChildren(children) {
|
|
3092
|
+
let ebmlElementCount = 0;
|
|
3093
|
+
while (children > 0) {
|
|
3094
|
+
ebmlElementCount++;
|
|
3095
|
+
if (ebmlElementCount > maximumEbmlElementCount) {
|
|
3096
|
+
return;
|
|
3097
|
+
}
|
|
3098
|
+
if (hasExceededUnknownSizeScanBudget(tokenizer, ebmlScanStart, maximumUntrustedSkipSizeInBytes)) {
|
|
3099
|
+
return;
|
|
3100
|
+
}
|
|
3101
|
+
const previousPosition = tokenizer.position;
|
|
3102
|
+
const element = await readElement();
|
|
3103
|
+
if (element.id === 17026) {
|
|
3104
|
+
if (element.len > maximumEbmlDocumentTypeSizeInBytes) {
|
|
3105
|
+
return;
|
|
3106
|
+
}
|
|
3107
|
+
const documentTypeLength = getSafeBound(element.len, maximumEbmlDocumentTypeSizeInBytes, "EBML DocType");
|
|
3108
|
+
const rawValue = await tokenizer.readToken(new StringType(documentTypeLength));
|
|
3109
|
+
return rawValue.replaceAll(/\00.*$/g, "");
|
|
3110
|
+
}
|
|
3111
|
+
if (hasUnknownFileSize(tokenizer) && (!Number.isFinite(element.len) || element.len < 0 || element.len > maximumEbmlElementPayloadSizeInBytes)) {
|
|
3112
|
+
return;
|
|
3113
|
+
}
|
|
3114
|
+
await safeIgnore(tokenizer, element.len, {
|
|
3115
|
+
maximumLength: hasUnknownFileSize(tokenizer) ? maximumEbmlElementPayloadSizeInBytes : tokenizer.fileInfo.size,
|
|
3116
|
+
reason: "EBML payload"
|
|
3117
|
+
});
|
|
3118
|
+
--children;
|
|
3119
|
+
if (tokenizer.position <= previousPosition) {
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
const rootElement = await readElement();
|
|
3125
|
+
const ebmlScanStart = tokenizer.position;
|
|
3126
|
+
const documentType = await readChildren(rootElement.len);
|
|
3127
|
+
switch (documentType) {
|
|
3128
|
+
case "webm":
|
|
3129
|
+
return {
|
|
3130
|
+
ext: "webm",
|
|
3131
|
+
mime: "video/webm"
|
|
3132
|
+
};
|
|
3133
|
+
case "matroska":
|
|
3134
|
+
return {
|
|
3135
|
+
ext: "mkv",
|
|
3136
|
+
mime: "video/matroska"
|
|
3137
|
+
};
|
|
3138
|
+
default:
|
|
3139
|
+
return;
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
if (this.checkString("SQLi")) {
|
|
3143
|
+
return {
|
|
3144
|
+
ext: "sqlite",
|
|
3145
|
+
mime: "application/x-sqlite3"
|
|
3146
|
+
};
|
|
3147
|
+
}
|
|
3148
|
+
if (this.check([78, 69, 83, 26])) {
|
|
3149
|
+
return {
|
|
3150
|
+
ext: "nes",
|
|
3151
|
+
mime: "application/x-nintendo-nes-rom"
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
if (this.checkString("Cr24")) {
|
|
3155
|
+
return {
|
|
3156
|
+
ext: "crx",
|
|
3157
|
+
mime: "application/x-google-chrome-extension"
|
|
3158
|
+
};
|
|
3159
|
+
}
|
|
3160
|
+
if (this.checkString("MSCF") || this.checkString("ISc(")) {
|
|
3161
|
+
return {
|
|
3162
|
+
ext: "cab",
|
|
3163
|
+
mime: "application/vnd.ms-cab-compressed"
|
|
3164
|
+
};
|
|
3165
|
+
}
|
|
3166
|
+
if (this.check([237, 171, 238, 219])) {
|
|
3167
|
+
return {
|
|
3168
|
+
ext: "rpm",
|
|
3169
|
+
mime: "application/x-rpm"
|
|
3170
|
+
};
|
|
3171
|
+
}
|
|
3172
|
+
if (this.check([197, 208, 211, 198])) {
|
|
3173
|
+
return {
|
|
3174
|
+
ext: "eps",
|
|
3175
|
+
mime: "application/eps"
|
|
3176
|
+
};
|
|
3177
|
+
}
|
|
3178
|
+
if (this.check([40, 181, 47, 253])) {
|
|
3179
|
+
return {
|
|
3180
|
+
ext: "zst",
|
|
3181
|
+
mime: "application/zstd"
|
|
3182
|
+
};
|
|
3183
|
+
}
|
|
3184
|
+
if (this.check([127, 69, 76, 70])) {
|
|
3185
|
+
return {
|
|
3186
|
+
ext: "elf",
|
|
3187
|
+
mime: "application/x-elf"
|
|
3188
|
+
};
|
|
3189
|
+
}
|
|
3190
|
+
if (this.check([33, 66, 68, 78])) {
|
|
3191
|
+
return {
|
|
3192
|
+
ext: "pst",
|
|
3193
|
+
mime: "application/vnd.ms-outlook"
|
|
3194
|
+
};
|
|
3195
|
+
}
|
|
3196
|
+
if (this.checkString("PAR1") || this.checkString("PARE")) {
|
|
3197
|
+
return {
|
|
3198
|
+
ext: "parquet",
|
|
3199
|
+
mime: "application/vnd.apache.parquet"
|
|
3200
|
+
};
|
|
3201
|
+
}
|
|
3202
|
+
if (this.checkString("ttcf")) {
|
|
3203
|
+
return {
|
|
3204
|
+
ext: "ttc",
|
|
3205
|
+
mime: "font/collection"
|
|
3206
|
+
};
|
|
3207
|
+
}
|
|
3208
|
+
if (this.check([254, 237, 250, 206]) || this.check([254, 237, 250, 207]) || this.check([206, 250, 237, 254]) || this.check([207, 250, 237, 254])) {
|
|
3209
|
+
return {
|
|
3210
|
+
ext: "macho",
|
|
3211
|
+
mime: "application/x-mach-binary"
|
|
3212
|
+
};
|
|
3213
|
+
}
|
|
3214
|
+
if (this.check([4, 34, 77, 24])) {
|
|
3215
|
+
return {
|
|
3216
|
+
ext: "lz4",
|
|
3217
|
+
mime: "application/x-lz4"
|
|
3218
|
+
// Invented by us
|
|
3219
|
+
};
|
|
3220
|
+
}
|
|
3221
|
+
if (this.checkString("regf")) {
|
|
3222
|
+
return {
|
|
3223
|
+
ext: "dat",
|
|
3224
|
+
mime: "application/x-ft-windows-registry-hive"
|
|
3225
|
+
};
|
|
3226
|
+
}
|
|
3227
|
+
if (this.checkString("$FL2") || this.checkString("$FL3")) {
|
|
3228
|
+
return {
|
|
3229
|
+
ext: "sav",
|
|
3230
|
+
mime: "application/x-spss-sav"
|
|
3231
|
+
};
|
|
3232
|
+
}
|
|
3233
|
+
if (this.check([79, 84, 84, 79, 0])) {
|
|
3234
|
+
return {
|
|
3235
|
+
ext: "otf",
|
|
3236
|
+
mime: "font/otf"
|
|
3237
|
+
};
|
|
3238
|
+
}
|
|
3239
|
+
if (this.checkString("#!AMR")) {
|
|
3240
|
+
return {
|
|
3241
|
+
ext: "amr",
|
|
3242
|
+
mime: "audio/amr"
|
|
3243
|
+
};
|
|
3244
|
+
}
|
|
3245
|
+
if (this.checkString("{\\rtf")) {
|
|
3246
|
+
return {
|
|
3247
|
+
ext: "rtf",
|
|
3248
|
+
mime: "application/rtf"
|
|
3249
|
+
};
|
|
3250
|
+
}
|
|
3251
|
+
if (this.check([70, 76, 86, 1])) {
|
|
3252
|
+
return {
|
|
3253
|
+
ext: "flv",
|
|
3254
|
+
mime: "video/x-flv"
|
|
3255
|
+
};
|
|
3256
|
+
}
|
|
3257
|
+
if (this.checkString("IMPM")) {
|
|
3258
|
+
return {
|
|
3259
|
+
ext: "it",
|
|
3260
|
+
mime: "audio/x-it"
|
|
3261
|
+
};
|
|
3262
|
+
}
|
|
3263
|
+
if (this.checkString("-lh0-", { offset: 2 }) || this.checkString("-lh1-", { offset: 2 }) || this.checkString("-lh2-", { offset: 2 }) || this.checkString("-lh3-", { offset: 2 }) || this.checkString("-lh4-", { offset: 2 }) || this.checkString("-lh5-", { offset: 2 }) || this.checkString("-lh6-", { offset: 2 }) || this.checkString("-lh7-", { offset: 2 }) || this.checkString("-lzs-", { offset: 2 }) || this.checkString("-lz4-", { offset: 2 }) || this.checkString("-lz5-", { offset: 2 }) || this.checkString("-lhd-", { offset: 2 })) {
|
|
3264
|
+
return {
|
|
3265
|
+
ext: "lzh",
|
|
3266
|
+
mime: "application/x-lzh-compressed"
|
|
3267
|
+
};
|
|
3268
|
+
}
|
|
3269
|
+
if (this.check([0, 0, 1, 186])) {
|
|
3270
|
+
if (this.check([33], { offset: 4, mask: [241] })) {
|
|
3271
|
+
return {
|
|
3272
|
+
ext: "mpg",
|
|
3273
|
+
// May also be .ps, .mpeg
|
|
3274
|
+
mime: "video/MP1S"
|
|
3275
|
+
};
|
|
3276
|
+
}
|
|
3277
|
+
if (this.check([68], { offset: 4, mask: [196] })) {
|
|
3278
|
+
return {
|
|
3279
|
+
ext: "mpg",
|
|
3280
|
+
// May also be .mpg, .m2p, .vob or .sub
|
|
3281
|
+
mime: "video/MP2P"
|
|
3282
|
+
};
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
if (this.checkString("ITSF")) {
|
|
3286
|
+
return {
|
|
3287
|
+
ext: "chm",
|
|
3288
|
+
mime: "application/vnd.ms-htmlhelp"
|
|
3289
|
+
};
|
|
3290
|
+
}
|
|
3291
|
+
if (this.check([202, 254, 186, 190])) {
|
|
3292
|
+
const machOArchitectureCount = UINT32_BE.get(this.buffer, 4);
|
|
3293
|
+
const javaClassFileMajorVersion = UINT16_BE.get(this.buffer, 6);
|
|
3294
|
+
if (machOArchitectureCount > 0 && machOArchitectureCount <= 30) {
|
|
3295
|
+
return {
|
|
3296
|
+
ext: "macho",
|
|
3297
|
+
mime: "application/x-mach-binary"
|
|
3298
|
+
};
|
|
3299
|
+
}
|
|
3300
|
+
if (javaClassFileMajorVersion > 30) {
|
|
3301
|
+
return {
|
|
3302
|
+
ext: "class",
|
|
3303
|
+
mime: "application/java-vm"
|
|
3304
|
+
};
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
if (this.checkString(".RMF")) {
|
|
3308
|
+
return {
|
|
3309
|
+
ext: "rm",
|
|
3310
|
+
mime: "application/vnd.rn-realmedia"
|
|
3311
|
+
};
|
|
3312
|
+
}
|
|
3313
|
+
if (this.checkString("DRACO")) {
|
|
3314
|
+
return {
|
|
3315
|
+
ext: "drc",
|
|
3316
|
+
mime: "application/vnd.google.draco"
|
|
3317
|
+
// Invented by us
|
|
3318
|
+
};
|
|
3319
|
+
}
|
|
3320
|
+
if (this.check([253, 55, 122, 88, 90, 0])) {
|
|
3321
|
+
return {
|
|
3322
|
+
ext: "xz",
|
|
3323
|
+
mime: "application/x-xz"
|
|
3324
|
+
};
|
|
3325
|
+
}
|
|
3326
|
+
if (this.checkString("<?xml ")) {
|
|
3327
|
+
return {
|
|
3328
|
+
ext: "xml",
|
|
3329
|
+
mime: "application/xml"
|
|
3330
|
+
};
|
|
3331
|
+
}
|
|
3332
|
+
if (this.check([55, 122, 188, 175, 39, 28])) {
|
|
3333
|
+
return {
|
|
3334
|
+
ext: "7z",
|
|
3335
|
+
mime: "application/x-7z-compressed"
|
|
3336
|
+
};
|
|
3337
|
+
}
|
|
3338
|
+
if (this.check([82, 97, 114, 33, 26, 7]) && (this.buffer[6] === 0 || this.buffer[6] === 1)) {
|
|
3339
|
+
return {
|
|
3340
|
+
ext: "rar",
|
|
3341
|
+
mime: "application/x-rar-compressed"
|
|
3342
|
+
};
|
|
3343
|
+
}
|
|
3344
|
+
if (this.checkString("solid ")) {
|
|
3345
|
+
return {
|
|
3346
|
+
ext: "stl",
|
|
3347
|
+
mime: "model/stl"
|
|
3348
|
+
};
|
|
3349
|
+
}
|
|
3350
|
+
if (this.checkString("AC")) {
|
|
3351
|
+
const version = new StringType(4, "latin1").get(this.buffer, 2);
|
|
3352
|
+
if (version.match("^d*") && version >= 1e3 && version <= 1050) {
|
|
3353
|
+
return {
|
|
3354
|
+
ext: "dwg",
|
|
3355
|
+
mime: "image/vnd.dwg"
|
|
3356
|
+
};
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3359
|
+
if (this.checkString("070707")) {
|
|
3360
|
+
return {
|
|
3361
|
+
ext: "cpio",
|
|
3362
|
+
mime: "application/x-cpio"
|
|
3363
|
+
};
|
|
3364
|
+
}
|
|
3365
|
+
if (this.checkString("BLENDER")) {
|
|
3366
|
+
return {
|
|
3367
|
+
ext: "blend",
|
|
3368
|
+
mime: "application/x-blender"
|
|
3369
|
+
};
|
|
3370
|
+
}
|
|
3371
|
+
if (this.checkString("!<arch>")) {
|
|
3372
|
+
await tokenizer.ignore(8);
|
|
3373
|
+
const string = await tokenizer.readToken(new StringType(13, "ascii"));
|
|
3374
|
+
if (string === "debian-binary") {
|
|
3375
|
+
return {
|
|
3376
|
+
ext: "deb",
|
|
3377
|
+
mime: "application/x-deb"
|
|
3378
|
+
};
|
|
3379
|
+
}
|
|
3380
|
+
return {
|
|
3381
|
+
ext: "ar",
|
|
3382
|
+
mime: "application/x-unix-archive"
|
|
3383
|
+
};
|
|
3384
|
+
}
|
|
3385
|
+
if (this.checkString("WEBVTT") && // One of LF, CR, tab, space, or end of file must follow "WEBVTT" per the spec (see `fixture/fixture-vtt-*.vtt` for examples). Note that `\0` is technically the null character (there is no such thing as an EOF character). However, checking for `\0` gives us the same result as checking for the end of the stream.
|
|
3386
|
+
["\n", "\r", " ", " ", "\0"].some((char7) => this.checkString(char7, { offset: 6 }))) {
|
|
3387
|
+
return {
|
|
3388
|
+
ext: "vtt",
|
|
3389
|
+
mime: "text/vtt"
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
if (this.check([137, 80, 78, 71, 13, 10, 26, 10])) {
|
|
3393
|
+
const pngFileType = {
|
|
3394
|
+
ext: "png",
|
|
3395
|
+
mime: "image/png"
|
|
3396
|
+
};
|
|
3397
|
+
const apngFileType = {
|
|
3398
|
+
ext: "apng",
|
|
3399
|
+
mime: "image/apng"
|
|
3400
|
+
};
|
|
3401
|
+
await tokenizer.ignore(8);
|
|
3402
|
+
async function readChunkHeader() {
|
|
3403
|
+
return {
|
|
3404
|
+
length: await tokenizer.readToken(INT32_BE),
|
|
3405
|
+
type: await tokenizer.readToken(new StringType(4, "latin1"))
|
|
3406
|
+
};
|
|
3407
|
+
}
|
|
3408
|
+
const isUnknownPngStream = hasUnknownFileSize(tokenizer);
|
|
3409
|
+
const pngScanStart = tokenizer.position;
|
|
3410
|
+
let pngChunkCount = 0;
|
|
3411
|
+
let hasSeenImageHeader = false;
|
|
3412
|
+
do {
|
|
3413
|
+
pngChunkCount++;
|
|
3414
|
+
if (pngChunkCount > maximumPngChunkCount) {
|
|
3415
|
+
break;
|
|
3416
|
+
}
|
|
3417
|
+
if (hasExceededUnknownSizeScanBudget(tokenizer, pngScanStart, maximumPngStreamScanBudgetInBytes)) {
|
|
3418
|
+
break;
|
|
3419
|
+
}
|
|
3420
|
+
const previousPosition = tokenizer.position;
|
|
3421
|
+
const chunk = await readChunkHeader();
|
|
3422
|
+
if (chunk.length < 0) {
|
|
3423
|
+
return;
|
|
3424
|
+
}
|
|
3425
|
+
if (chunk.type === "IHDR") {
|
|
3426
|
+
if (chunk.length !== 13) {
|
|
3427
|
+
return;
|
|
3428
|
+
}
|
|
3429
|
+
hasSeenImageHeader = true;
|
|
3430
|
+
}
|
|
3431
|
+
switch (chunk.type) {
|
|
3432
|
+
case "IDAT":
|
|
3433
|
+
return pngFileType;
|
|
3434
|
+
case "acTL":
|
|
3435
|
+
return apngFileType;
|
|
3436
|
+
default:
|
|
3437
|
+
if (!hasSeenImageHeader && chunk.type !== "CgBI") {
|
|
3438
|
+
return;
|
|
3439
|
+
}
|
|
3440
|
+
if (isUnknownPngStream && chunk.length > maximumPngChunkSizeInBytes) {
|
|
3441
|
+
return hasSeenImageHeader && isPngAncillaryChunk(chunk.type) ? pngFileType : void 0;
|
|
3442
|
+
}
|
|
3443
|
+
try {
|
|
3444
|
+
await safeIgnore(tokenizer, chunk.length + 4, {
|
|
3445
|
+
maximumLength: isUnknownPngStream ? maximumPngChunkSizeInBytes + 4 : tokenizer.fileInfo.size,
|
|
3446
|
+
reason: "PNG chunk payload"
|
|
3447
|
+
});
|
|
3448
|
+
} catch (error) {
|
|
3449
|
+
if (!isUnknownPngStream && (error instanceof ParserHardLimitError || error instanceof EndOfStreamError)) {
|
|
3450
|
+
return pngFileType;
|
|
3451
|
+
}
|
|
3452
|
+
throw error;
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
if (tokenizer.position <= previousPosition) {
|
|
3456
|
+
break;
|
|
3457
|
+
}
|
|
3458
|
+
} while (tokenizer.position + 8 < tokenizer.fileInfo.size);
|
|
3459
|
+
return pngFileType;
|
|
3460
|
+
}
|
|
3461
|
+
if (this.check([65, 82, 82, 79, 87, 49, 0, 0])) {
|
|
3462
|
+
return {
|
|
3463
|
+
ext: "arrow",
|
|
3464
|
+
mime: "application/vnd.apache.arrow.file"
|
|
3465
|
+
};
|
|
3466
|
+
}
|
|
3467
|
+
if (this.check([103, 108, 84, 70, 2, 0, 0, 0])) {
|
|
3468
|
+
return {
|
|
3469
|
+
ext: "glb",
|
|
3470
|
+
mime: "model/gltf-binary"
|
|
3471
|
+
};
|
|
3472
|
+
}
|
|
3473
|
+
if (this.check([102, 114, 101, 101], { offset: 4 }) || this.check([109, 100, 97, 116], { offset: 4 }) || this.check([109, 111, 111, 118], { offset: 4 }) || this.check([119, 105, 100, 101], { offset: 4 })) {
|
|
3474
|
+
return {
|
|
3475
|
+
ext: "mov",
|
|
3476
|
+
mime: "video/quicktime"
|
|
3477
|
+
};
|
|
3478
|
+
}
|
|
3479
|
+
if (this.check([73, 73, 82, 79, 8, 0, 0, 0, 24])) {
|
|
3480
|
+
return {
|
|
3481
|
+
ext: "orf",
|
|
3482
|
+
mime: "image/x-olympus-orf"
|
|
3483
|
+
};
|
|
3484
|
+
}
|
|
3485
|
+
if (this.checkString("gimp xcf ")) {
|
|
3486
|
+
return {
|
|
3487
|
+
ext: "xcf",
|
|
3488
|
+
mime: "image/x-xcf"
|
|
3489
|
+
};
|
|
3490
|
+
}
|
|
3491
|
+
if (this.checkString("ftyp", { offset: 4 }) && (this.buffer[8] & 96) !== 0) {
|
|
3492
|
+
const brandMajor = new StringType(4, "latin1").get(this.buffer, 8).replace("\0", " ").trim();
|
|
3493
|
+
switch (brandMajor) {
|
|
3494
|
+
case "avif":
|
|
3495
|
+
case "avis":
|
|
3496
|
+
return { ext: "avif", mime: "image/avif" };
|
|
3497
|
+
case "mif1":
|
|
3498
|
+
return { ext: "heic", mime: "image/heif" };
|
|
3499
|
+
case "msf1":
|
|
3500
|
+
return { ext: "heic", mime: "image/heif-sequence" };
|
|
3501
|
+
case "heic":
|
|
3502
|
+
case "heix":
|
|
3503
|
+
return { ext: "heic", mime: "image/heic" };
|
|
3504
|
+
case "hevc":
|
|
3505
|
+
case "hevx":
|
|
3506
|
+
return { ext: "heic", mime: "image/heic-sequence" };
|
|
3507
|
+
case "qt":
|
|
3508
|
+
return { ext: "mov", mime: "video/quicktime" };
|
|
3509
|
+
case "M4V":
|
|
3510
|
+
case "M4VH":
|
|
3511
|
+
case "M4VP":
|
|
3512
|
+
return { ext: "m4v", mime: "video/x-m4v" };
|
|
3513
|
+
case "M4P":
|
|
3514
|
+
return { ext: "m4p", mime: "video/mp4" };
|
|
3515
|
+
case "M4B":
|
|
3516
|
+
return { ext: "m4b", mime: "audio/mp4" };
|
|
3517
|
+
case "M4A":
|
|
3518
|
+
return { ext: "m4a", mime: "audio/x-m4a" };
|
|
3519
|
+
case "F4V":
|
|
3520
|
+
return { ext: "f4v", mime: "video/mp4" };
|
|
3521
|
+
case "F4P":
|
|
3522
|
+
return { ext: "f4p", mime: "video/mp4" };
|
|
3523
|
+
case "F4A":
|
|
3524
|
+
return { ext: "f4a", mime: "audio/mp4" };
|
|
3525
|
+
case "F4B":
|
|
3526
|
+
return { ext: "f4b", mime: "audio/mp4" };
|
|
3527
|
+
case "crx":
|
|
3528
|
+
return { ext: "cr3", mime: "image/x-canon-cr3" };
|
|
3529
|
+
default:
|
|
3530
|
+
if (brandMajor.startsWith("3g")) {
|
|
3531
|
+
if (brandMajor.startsWith("3g2")) {
|
|
3532
|
+
return { ext: "3g2", mime: "video/3gpp2" };
|
|
3533
|
+
}
|
|
3534
|
+
return { ext: "3gp", mime: "video/3gpp" };
|
|
3535
|
+
}
|
|
3536
|
+
return { ext: "mp4", mime: "video/mp4" };
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
if (this.checkString("REGEDIT4\r\n")) {
|
|
3540
|
+
return {
|
|
3541
|
+
ext: "reg",
|
|
3542
|
+
mime: "application/x-ms-regedit"
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
3545
|
+
if (this.check([82, 73, 70, 70])) {
|
|
3546
|
+
if (this.checkString("WEBP", { offset: 8 })) {
|
|
3547
|
+
return {
|
|
3548
|
+
ext: "webp",
|
|
3549
|
+
mime: "image/webp"
|
|
3550
|
+
};
|
|
3551
|
+
}
|
|
3552
|
+
if (this.check([65, 86, 73], { offset: 8 })) {
|
|
3553
|
+
return {
|
|
3554
|
+
ext: "avi",
|
|
3555
|
+
mime: "video/vnd.avi"
|
|
3556
|
+
};
|
|
3557
|
+
}
|
|
3558
|
+
if (this.check([87, 65, 86, 69], { offset: 8 })) {
|
|
3559
|
+
return {
|
|
3560
|
+
ext: "wav",
|
|
3561
|
+
mime: "audio/wav"
|
|
3562
|
+
};
|
|
3563
|
+
}
|
|
3564
|
+
if (this.check([81, 76, 67, 77], { offset: 8 })) {
|
|
3565
|
+
return {
|
|
3566
|
+
ext: "qcp",
|
|
3567
|
+
mime: "audio/qcelp"
|
|
3568
|
+
};
|
|
3569
|
+
}
|
|
3570
|
+
}
|
|
3571
|
+
if (this.check([73, 73, 85, 0, 24, 0, 0, 0, 136, 231, 116, 216])) {
|
|
3572
|
+
return {
|
|
3573
|
+
ext: "rw2",
|
|
3574
|
+
mime: "image/x-panasonic-rw2"
|
|
3575
|
+
};
|
|
3576
|
+
}
|
|
3577
|
+
if (this.check([48, 38, 178, 117, 142, 102, 207, 17, 166, 217])) {
|
|
3578
|
+
let isMalformedAsf = false;
|
|
3579
|
+
try {
|
|
3580
|
+
async function readHeader() {
|
|
3581
|
+
const guid = new Uint8Array(16);
|
|
3582
|
+
await safeReadBuffer(tokenizer, guid, void 0, {
|
|
3583
|
+
maximumLength: guid.length,
|
|
3584
|
+
reason: "ASF header GUID"
|
|
3585
|
+
});
|
|
3586
|
+
return {
|
|
3587
|
+
id: guid,
|
|
3588
|
+
size: Number(await tokenizer.readToken(UINT64_LE))
|
|
3589
|
+
};
|
|
3590
|
+
}
|
|
3591
|
+
await safeIgnore(tokenizer, 30, {
|
|
3592
|
+
maximumLength: 30,
|
|
3593
|
+
reason: "ASF header prelude"
|
|
3594
|
+
});
|
|
3595
|
+
const isUnknownFileSize = hasUnknownFileSize(tokenizer);
|
|
3596
|
+
const asfHeaderScanStart = tokenizer.position;
|
|
3597
|
+
let asfHeaderObjectCount = 0;
|
|
3598
|
+
while (tokenizer.position + 24 < tokenizer.fileInfo.size) {
|
|
3599
|
+
asfHeaderObjectCount++;
|
|
3600
|
+
if (asfHeaderObjectCount > maximumAsfHeaderObjectCount) {
|
|
3601
|
+
break;
|
|
3602
|
+
}
|
|
3603
|
+
if (hasExceededUnknownSizeScanBudget(tokenizer, asfHeaderScanStart, maximumUntrustedSkipSizeInBytes)) {
|
|
3604
|
+
break;
|
|
3605
|
+
}
|
|
3606
|
+
const previousPosition = tokenizer.position;
|
|
3607
|
+
const header = await readHeader();
|
|
3608
|
+
let payload = header.size - 24;
|
|
3609
|
+
if (!Number.isFinite(payload) || payload < 0) {
|
|
3610
|
+
isMalformedAsf = true;
|
|
3611
|
+
break;
|
|
3612
|
+
}
|
|
3613
|
+
if (_check(header.id, [145, 7, 220, 183, 183, 169, 207, 17, 142, 230, 0, 192, 12, 32, 83, 101])) {
|
|
3614
|
+
const typeId = new Uint8Array(16);
|
|
3615
|
+
payload -= await safeReadBuffer(tokenizer, typeId, void 0, {
|
|
3616
|
+
maximumLength: typeId.length,
|
|
3617
|
+
reason: "ASF stream type GUID"
|
|
3618
|
+
});
|
|
3619
|
+
if (_check(typeId, [64, 158, 105, 248, 77, 91, 207, 17, 168, 253, 0, 128, 95, 92, 68, 43])) {
|
|
3620
|
+
return {
|
|
3621
|
+
ext: "asf",
|
|
3622
|
+
mime: "audio/x-ms-asf"
|
|
3623
|
+
};
|
|
3624
|
+
}
|
|
3625
|
+
if (_check(typeId, [192, 239, 25, 188, 77, 91, 207, 17, 168, 253, 0, 128, 95, 92, 68, 43])) {
|
|
3626
|
+
return {
|
|
3627
|
+
ext: "asf",
|
|
3628
|
+
mime: "video/x-ms-asf"
|
|
3629
|
+
};
|
|
3630
|
+
}
|
|
3631
|
+
break;
|
|
3632
|
+
}
|
|
3633
|
+
if (isUnknownFileSize && payload > maximumAsfHeaderPayloadSizeInBytes) {
|
|
3634
|
+
isMalformedAsf = true;
|
|
3635
|
+
break;
|
|
3636
|
+
}
|
|
3637
|
+
await safeIgnore(tokenizer, payload, {
|
|
3638
|
+
maximumLength: isUnknownFileSize ? maximumAsfHeaderPayloadSizeInBytes : tokenizer.fileInfo.size,
|
|
3639
|
+
reason: "ASF header payload"
|
|
3640
|
+
});
|
|
3641
|
+
if (tokenizer.position <= previousPosition) {
|
|
3642
|
+
isMalformedAsf = true;
|
|
3643
|
+
break;
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
} catch (error) {
|
|
3647
|
+
if (error instanceof EndOfStreamError || error instanceof ParserHardLimitError) {
|
|
3648
|
+
if (hasUnknownFileSize(tokenizer)) {
|
|
3649
|
+
isMalformedAsf = true;
|
|
3650
|
+
}
|
|
3651
|
+
} else {
|
|
3652
|
+
throw error;
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
if (isMalformedAsf) {
|
|
3656
|
+
return;
|
|
3657
|
+
}
|
|
3658
|
+
return {
|
|
3659
|
+
ext: "asf",
|
|
3660
|
+
mime: "application/vnd.ms-asf"
|
|
3661
|
+
};
|
|
3662
|
+
}
|
|
3663
|
+
if (this.check([171, 75, 84, 88, 32, 49, 49, 187, 13, 10, 26, 10])) {
|
|
3664
|
+
return {
|
|
3665
|
+
ext: "ktx",
|
|
3666
|
+
mime: "image/ktx"
|
|
3667
|
+
};
|
|
3668
|
+
}
|
|
3669
|
+
if ((this.check([126, 16, 4]) || this.check([126, 24, 4])) && this.check([48, 77, 73, 69], { offset: 4 })) {
|
|
3670
|
+
return {
|
|
3671
|
+
ext: "mie",
|
|
3672
|
+
mime: "application/x-mie"
|
|
3673
|
+
};
|
|
3674
|
+
}
|
|
3675
|
+
if (this.check([39, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], { offset: 2 })) {
|
|
3676
|
+
return {
|
|
3677
|
+
ext: "shp",
|
|
3678
|
+
mime: "application/x-esri-shape"
|
|
3679
|
+
};
|
|
3680
|
+
}
|
|
3681
|
+
if (this.check([255, 79, 255, 81])) {
|
|
3682
|
+
return {
|
|
3683
|
+
ext: "j2c",
|
|
3684
|
+
mime: "image/j2c"
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
if (this.check([0, 0, 0, 12, 106, 80, 32, 32, 13, 10, 135, 10])) {
|
|
3688
|
+
await tokenizer.ignore(20);
|
|
3689
|
+
const type = await tokenizer.readToken(new StringType(4, "ascii"));
|
|
3690
|
+
switch (type) {
|
|
3691
|
+
case "jp2 ":
|
|
3692
|
+
return {
|
|
3693
|
+
ext: "jp2",
|
|
3694
|
+
mime: "image/jp2"
|
|
3695
|
+
};
|
|
3696
|
+
case "jpx ":
|
|
3697
|
+
return {
|
|
3698
|
+
ext: "jpx",
|
|
3699
|
+
mime: "image/jpx"
|
|
3700
|
+
};
|
|
3701
|
+
case "jpm ":
|
|
3702
|
+
return {
|
|
3703
|
+
ext: "jpm",
|
|
3704
|
+
mime: "image/jpm"
|
|
3705
|
+
};
|
|
3706
|
+
case "mjp2":
|
|
3707
|
+
return {
|
|
3708
|
+
ext: "mj2",
|
|
3709
|
+
mime: "image/mj2"
|
|
3710
|
+
};
|
|
3711
|
+
default:
|
|
3712
|
+
return;
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3715
|
+
if (this.check([255, 10]) || this.check([0, 0, 0, 12, 74, 88, 76, 32, 13, 10, 135, 10])) {
|
|
3716
|
+
return {
|
|
3717
|
+
ext: "jxl",
|
|
3718
|
+
mime: "image/jxl"
|
|
3719
|
+
};
|
|
3720
|
+
}
|
|
3721
|
+
if (this.check([254, 255])) {
|
|
3722
|
+
if (this.checkString("<?xml ", { offset: 2, encoding: "utf-16be" })) {
|
|
3723
|
+
return {
|
|
3724
|
+
ext: "xml",
|
|
3725
|
+
mime: "application/xml"
|
|
3726
|
+
};
|
|
3727
|
+
}
|
|
3728
|
+
return void 0;
|
|
3729
|
+
}
|
|
3730
|
+
if (this.check([208, 207, 17, 224, 161, 177, 26, 225])) {
|
|
3731
|
+
return {
|
|
3732
|
+
ext: "cfb",
|
|
3733
|
+
mime: "application/x-cfb"
|
|
3734
|
+
};
|
|
3735
|
+
}
|
|
3736
|
+
await tokenizer.peekBuffer(this.buffer, { length: Math.min(256, tokenizer.fileInfo.size), mayBeLess: true });
|
|
3737
|
+
if (this.check([97, 99, 115, 112], { offset: 36 })) {
|
|
3738
|
+
return {
|
|
3739
|
+
ext: "icc",
|
|
3740
|
+
mime: "application/vnd.iccprofile"
|
|
3741
|
+
};
|
|
3742
|
+
}
|
|
3743
|
+
if (this.checkString("**ACE", { offset: 7 }) && this.checkString("**", { offset: 12 })) {
|
|
3744
|
+
return {
|
|
3745
|
+
ext: "ace",
|
|
3746
|
+
mime: "application/x-ace-compressed"
|
|
3747
|
+
};
|
|
3748
|
+
}
|
|
3749
|
+
if (this.checkString("BEGIN:")) {
|
|
3750
|
+
if (this.checkString("VCARD", { offset: 6 })) {
|
|
3751
|
+
return {
|
|
3752
|
+
ext: "vcf",
|
|
3753
|
+
mime: "text/vcard"
|
|
3754
|
+
};
|
|
3755
|
+
}
|
|
3756
|
+
if (this.checkString("VCALENDAR", { offset: 6 })) {
|
|
3757
|
+
return {
|
|
3758
|
+
ext: "ics",
|
|
3759
|
+
mime: "text/calendar"
|
|
3760
|
+
};
|
|
3761
|
+
}
|
|
3762
|
+
}
|
|
3763
|
+
if (this.checkString("FUJIFILMCCD-RAW")) {
|
|
3764
|
+
return {
|
|
3765
|
+
ext: "raf",
|
|
3766
|
+
mime: "image/x-fujifilm-raf"
|
|
3767
|
+
};
|
|
3768
|
+
}
|
|
3769
|
+
if (this.checkString("Extended Module:")) {
|
|
3770
|
+
return {
|
|
3771
|
+
ext: "xm",
|
|
3772
|
+
mime: "audio/x-xm"
|
|
3773
|
+
};
|
|
3774
|
+
}
|
|
3775
|
+
if (this.checkString("Creative Voice File")) {
|
|
3776
|
+
return {
|
|
3777
|
+
ext: "voc",
|
|
3778
|
+
mime: "audio/x-voc"
|
|
3779
|
+
};
|
|
3780
|
+
}
|
|
3781
|
+
if (this.check([4, 0, 0, 0]) && this.buffer.length >= 16) {
|
|
3782
|
+
const jsonSize = new DataView(this.buffer.buffer).getUint32(12, true);
|
|
3783
|
+
if (jsonSize > 12 && this.buffer.length >= jsonSize + 16) {
|
|
3784
|
+
try {
|
|
3785
|
+
const header = new TextDecoder().decode(this.buffer.subarray(16, jsonSize + 16));
|
|
3786
|
+
const json = JSON.parse(header);
|
|
3787
|
+
if (json.files) {
|
|
3788
|
+
return {
|
|
3789
|
+
ext: "asar",
|
|
3790
|
+
mime: "application/x-asar"
|
|
3791
|
+
};
|
|
3792
|
+
}
|
|
3793
|
+
} catch {
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
if (this.check([6, 14, 43, 52, 2, 5, 1, 1, 13, 1, 2, 1, 1, 2])) {
|
|
3798
|
+
return {
|
|
3799
|
+
ext: "mxf",
|
|
3800
|
+
mime: "application/mxf"
|
|
3801
|
+
};
|
|
3802
|
+
}
|
|
3803
|
+
if (this.checkString("SCRM", { offset: 44 })) {
|
|
3804
|
+
return {
|
|
3805
|
+
ext: "s3m",
|
|
3806
|
+
mime: "audio/x-s3m"
|
|
3807
|
+
};
|
|
3808
|
+
}
|
|
3809
|
+
if (this.check([71]) && this.check([71], { offset: 188 })) {
|
|
3810
|
+
return {
|
|
3811
|
+
ext: "mts",
|
|
3812
|
+
mime: "video/mp2t"
|
|
3813
|
+
};
|
|
3814
|
+
}
|
|
3815
|
+
if (this.check([71], { offset: 4 }) && this.check([71], { offset: 196 })) {
|
|
3816
|
+
return {
|
|
3817
|
+
ext: "mts",
|
|
3818
|
+
mime: "video/mp2t"
|
|
3819
|
+
};
|
|
3820
|
+
}
|
|
3821
|
+
if (this.check([66, 79, 79, 75, 77, 79, 66, 73], { offset: 60 })) {
|
|
3822
|
+
return {
|
|
3823
|
+
ext: "mobi",
|
|
3824
|
+
mime: "application/x-mobipocket-ebook"
|
|
3825
|
+
};
|
|
3826
|
+
}
|
|
3827
|
+
if (this.check([68, 73, 67, 77], { offset: 128 })) {
|
|
3828
|
+
return {
|
|
3829
|
+
ext: "dcm",
|
|
3830
|
+
mime: "application/dicom"
|
|
3831
|
+
};
|
|
3832
|
+
}
|
|
3833
|
+
if (this.check([76, 0, 0, 0, 1, 20, 2, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 70])) {
|
|
3834
|
+
return {
|
|
3835
|
+
ext: "lnk",
|
|
3836
|
+
mime: "application/x.ms.shortcut"
|
|
3837
|
+
// Invented by us
|
|
3838
|
+
};
|
|
3839
|
+
}
|
|
3840
|
+
if (this.check([98, 111, 111, 107, 0, 0, 0, 0, 109, 97, 114, 107, 0, 0, 0, 0])) {
|
|
3841
|
+
return {
|
|
3842
|
+
ext: "alias",
|
|
3843
|
+
mime: "application/x.apple.alias"
|
|
3844
|
+
// Invented by us
|
|
3845
|
+
};
|
|
3846
|
+
}
|
|
3847
|
+
if (this.checkString("Kaydara FBX Binary \0")) {
|
|
3848
|
+
return {
|
|
3849
|
+
ext: "fbx",
|
|
3850
|
+
mime: "application/x.autodesk.fbx"
|
|
3851
|
+
// Invented by us
|
|
3852
|
+
};
|
|
3853
|
+
}
|
|
3854
|
+
if (this.check([76, 80], { offset: 34 }) && (this.check([0, 0, 1], { offset: 8 }) || this.check([1, 0, 2], { offset: 8 }) || this.check([2, 0, 2], { offset: 8 }))) {
|
|
3855
|
+
return {
|
|
3856
|
+
ext: "eot",
|
|
3857
|
+
mime: "application/vnd.ms-fontobject"
|
|
3858
|
+
};
|
|
3859
|
+
}
|
|
3860
|
+
if (this.check([6, 6, 237, 245, 216, 29, 70, 229, 189, 49, 239, 231, 254, 116, 183, 29])) {
|
|
3861
|
+
return {
|
|
3862
|
+
ext: "indd",
|
|
3863
|
+
mime: "application/x-indesign"
|
|
3864
|
+
};
|
|
3865
|
+
}
|
|
3866
|
+
if (this.check([255, 255, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 1, 0, 1, 0]) || this.check([0, 0, 255, 255, 0, 0, 0, 7, 0, 0, 0, 4, 0, 1, 0, 1])) {
|
|
3867
|
+
return {
|
|
3868
|
+
ext: "jmp",
|
|
3869
|
+
mime: "application/x-jmp-data"
|
|
3870
|
+
};
|
|
3871
|
+
}
|
|
3872
|
+
await tokenizer.peekBuffer(this.buffer, { length: Math.min(512, tokenizer.fileInfo.size), mayBeLess: true });
|
|
3873
|
+
if (this.checkString("ustar", { offset: 257 }) && (this.checkString("\0", { offset: 262 }) || this.checkString(" ", { offset: 262 })) || this.check([0, 0, 0, 0, 0, 0], { offset: 257 }) && tarHeaderChecksumMatches(this.buffer)) {
|
|
3874
|
+
return {
|
|
3875
|
+
ext: "tar",
|
|
3876
|
+
mime: "application/x-tar"
|
|
3877
|
+
};
|
|
3878
|
+
}
|
|
3879
|
+
if (this.check([255, 254])) {
|
|
3880
|
+
const encoding = "utf-16le";
|
|
3881
|
+
if (this.checkString("<?xml ", { offset: 2, encoding })) {
|
|
3882
|
+
return {
|
|
3883
|
+
ext: "xml",
|
|
3884
|
+
mime: "application/xml"
|
|
3885
|
+
};
|
|
3886
|
+
}
|
|
3887
|
+
if (this.check([255, 14], { offset: 2 }) && this.checkString("SketchUp Model", { offset: 4, encoding })) {
|
|
3888
|
+
return {
|
|
3889
|
+
ext: "skp",
|
|
3890
|
+
mime: "application/vnd.sketchup.skp"
|
|
3891
|
+
};
|
|
3892
|
+
}
|
|
3893
|
+
if (this.checkString("Windows Registry Editor Version 5.00\r\n", { offset: 2, encoding })) {
|
|
3894
|
+
return {
|
|
3895
|
+
ext: "reg",
|
|
3896
|
+
mime: "application/x-ms-regedit"
|
|
3897
|
+
};
|
|
3898
|
+
}
|
|
3899
|
+
return void 0;
|
|
3900
|
+
}
|
|
3901
|
+
if (this.checkString("-----BEGIN PGP MESSAGE-----")) {
|
|
3902
|
+
return {
|
|
3903
|
+
ext: "pgp",
|
|
3904
|
+
mime: "application/pgp-encrypted"
|
|
3905
|
+
};
|
|
3906
|
+
}
|
|
3907
|
+
};
|
|
3908
|
+
// Detections with limited supporting data, resulting in a higher likelihood of false positives
|
|
3909
|
+
detectImprecise = async (tokenizer) => {
|
|
3910
|
+
this.buffer = new Uint8Array(reasonableDetectionSizeInBytes);
|
|
3911
|
+
const fileSize = getKnownFileSizeOrMaximum(tokenizer.fileInfo.size);
|
|
3912
|
+
await tokenizer.peekBuffer(this.buffer, { length: Math.min(8, fileSize), mayBeLess: true });
|
|
3913
|
+
if (this.check([0, 0, 1, 186]) || this.check([0, 0, 1, 179])) {
|
|
3914
|
+
return {
|
|
3915
|
+
ext: "mpg",
|
|
3916
|
+
mime: "video/mpeg"
|
|
3917
|
+
};
|
|
3918
|
+
}
|
|
3919
|
+
if (this.check([0, 1, 0, 0, 0])) {
|
|
3920
|
+
return {
|
|
3921
|
+
ext: "ttf",
|
|
3922
|
+
mime: "font/ttf"
|
|
3923
|
+
};
|
|
3924
|
+
}
|
|
3925
|
+
if (this.check([0, 0, 1, 0])) {
|
|
3926
|
+
return {
|
|
3927
|
+
ext: "ico",
|
|
3928
|
+
mime: "image/x-icon"
|
|
3929
|
+
};
|
|
3930
|
+
}
|
|
3931
|
+
if (this.check([0, 0, 2, 0])) {
|
|
3932
|
+
return {
|
|
3933
|
+
ext: "cur",
|
|
3934
|
+
mime: "image/x-icon"
|
|
3935
|
+
};
|
|
3936
|
+
}
|
|
3937
|
+
await tokenizer.peekBuffer(this.buffer, { length: Math.min(2 + this.options.mpegOffsetTolerance, fileSize), mayBeLess: true });
|
|
3938
|
+
if (this.buffer.length >= 2 + this.options.mpegOffsetTolerance) {
|
|
3939
|
+
for (let depth = 0; depth <= this.options.mpegOffsetTolerance; ++depth) {
|
|
3940
|
+
const type = this.scanMpeg(depth);
|
|
3941
|
+
if (type) {
|
|
3942
|
+
return type;
|
|
3943
|
+
}
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
};
|
|
3947
|
+
async readTiffTag(bigEndian) {
|
|
3948
|
+
const tagId = await this.tokenizer.readToken(bigEndian ? UINT16_BE : UINT16_LE);
|
|
3949
|
+
await this.tokenizer.ignore(10);
|
|
3950
|
+
switch (tagId) {
|
|
3951
|
+
case 50341:
|
|
3952
|
+
return {
|
|
3953
|
+
ext: "arw",
|
|
3954
|
+
mime: "image/x-sony-arw"
|
|
3955
|
+
};
|
|
3956
|
+
case 50706:
|
|
3957
|
+
return {
|
|
3958
|
+
ext: "dng",
|
|
3959
|
+
mime: "image/x-adobe-dng"
|
|
3960
|
+
};
|
|
3961
|
+
default:
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
async readTiffIFD(bigEndian) {
|
|
3965
|
+
const numberOfTags = await this.tokenizer.readToken(bigEndian ? UINT16_BE : UINT16_LE);
|
|
3966
|
+
if (numberOfTags > maximumTiffTagCount) {
|
|
3967
|
+
return;
|
|
3968
|
+
}
|
|
3969
|
+
if (hasUnknownFileSize(this.tokenizer) && 2 + numberOfTags * 12 > maximumTiffIfdOffsetInBytes) {
|
|
3970
|
+
return;
|
|
3971
|
+
}
|
|
3972
|
+
for (let n = 0; n < numberOfTags; ++n) {
|
|
3973
|
+
const fileType = await this.readTiffTag(bigEndian);
|
|
3974
|
+
if (fileType) {
|
|
3975
|
+
return fileType;
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3979
|
+
async readTiffHeader(bigEndian) {
|
|
3980
|
+
const tiffFileType = {
|
|
3981
|
+
ext: "tif",
|
|
3982
|
+
mime: "image/tiff"
|
|
3983
|
+
};
|
|
3984
|
+
const version = (bigEndian ? UINT16_BE : UINT16_LE).get(this.buffer, 2);
|
|
3985
|
+
const ifdOffset = (bigEndian ? UINT32_BE : UINT32_LE).get(this.buffer, 4);
|
|
3986
|
+
if (version === 42) {
|
|
3987
|
+
if (ifdOffset >= 6) {
|
|
3988
|
+
if (this.checkString("CR", { offset: 8 })) {
|
|
3989
|
+
return {
|
|
3990
|
+
ext: "cr2",
|
|
3991
|
+
mime: "image/x-canon-cr2"
|
|
3992
|
+
};
|
|
3993
|
+
}
|
|
3994
|
+
if (ifdOffset >= 8) {
|
|
3995
|
+
const someId1 = (bigEndian ? UINT16_BE : UINT16_LE).get(this.buffer, 8);
|
|
3996
|
+
const someId2 = (bigEndian ? UINT16_BE : UINT16_LE).get(this.buffer, 10);
|
|
3997
|
+
if (someId1 === 28 && someId2 === 254 || someId1 === 31 && someId2 === 11) {
|
|
3998
|
+
return {
|
|
3999
|
+
ext: "nef",
|
|
4000
|
+
mime: "image/x-nikon-nef"
|
|
4001
|
+
};
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
if (hasUnknownFileSize(this.tokenizer) && ifdOffset > maximumTiffStreamIfdOffsetInBytes) {
|
|
4006
|
+
return tiffFileType;
|
|
4007
|
+
}
|
|
4008
|
+
const maximumTiffOffset = hasUnknownFileSize(this.tokenizer) ? maximumTiffIfdOffsetInBytes : this.tokenizer.fileInfo.size;
|
|
4009
|
+
try {
|
|
4010
|
+
await safeIgnore(this.tokenizer, ifdOffset, {
|
|
4011
|
+
maximumLength: maximumTiffOffset,
|
|
4012
|
+
reason: "TIFF IFD offset"
|
|
4013
|
+
});
|
|
4014
|
+
} catch (error) {
|
|
4015
|
+
if (error instanceof EndOfStreamError) {
|
|
4016
|
+
return;
|
|
4017
|
+
}
|
|
4018
|
+
throw error;
|
|
4019
|
+
}
|
|
4020
|
+
let fileType;
|
|
4021
|
+
try {
|
|
4022
|
+
fileType = await this.readTiffIFD(bigEndian);
|
|
4023
|
+
} catch (error) {
|
|
4024
|
+
if (error instanceof EndOfStreamError) {
|
|
4025
|
+
return;
|
|
4026
|
+
}
|
|
4027
|
+
throw error;
|
|
4028
|
+
}
|
|
4029
|
+
return fileType ?? tiffFileType;
|
|
4030
|
+
}
|
|
4031
|
+
if (version === 43) {
|
|
4032
|
+
return tiffFileType;
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
4035
|
+
/**
|
|
4036
|
+
Scan check MPEG 1 or 2 Layer 3 header, or 'layer 0' for ADTS (MPEG sync-word 0xFFE).
|
|
4037
|
+
|
|
4038
|
+
@param offset - Offset to scan for sync-preamble.
|
|
4039
|
+
@returns {{ext: string, mime: string}}
|
|
4040
|
+
*/
|
|
4041
|
+
scanMpeg(offset) {
|
|
4042
|
+
if (this.check([255, 224], { offset, mask: [255, 224] })) {
|
|
4043
|
+
if (this.check([16], { offset: offset + 1, mask: [22] })) {
|
|
4044
|
+
if (this.check([8], { offset: offset + 1, mask: [8] })) {
|
|
4045
|
+
return {
|
|
4046
|
+
ext: "aac",
|
|
4047
|
+
mime: "audio/aac"
|
|
4048
|
+
};
|
|
4049
|
+
}
|
|
4050
|
+
return {
|
|
4051
|
+
ext: "aac",
|
|
4052
|
+
mime: "audio/aac"
|
|
4053
|
+
};
|
|
4054
|
+
}
|
|
4055
|
+
if (this.check([2], { offset: offset + 1, mask: [6] })) {
|
|
4056
|
+
return {
|
|
4057
|
+
ext: "mp3",
|
|
4058
|
+
mime: "audio/mpeg"
|
|
4059
|
+
};
|
|
4060
|
+
}
|
|
4061
|
+
if (this.check([4], { offset: offset + 1, mask: [6] })) {
|
|
4062
|
+
return {
|
|
4063
|
+
ext: "mp2",
|
|
4064
|
+
mime: "audio/mpeg"
|
|
4065
|
+
};
|
|
4066
|
+
}
|
|
4067
|
+
if (this.check([6], { offset: offset + 1, mask: [6] })) {
|
|
4068
|
+
return {
|
|
4069
|
+
ext: "mp1",
|
|
4070
|
+
mime: "audio/mpeg"
|
|
4071
|
+
};
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
}
|
|
4075
|
+
};
|
|
4076
|
+
var supportedExtensions = new Set(extensions);
|
|
4077
|
+
var supportedMimeTypes = new Set(mimeTypes);
|
|
4078
|
+
|
|
4079
|
+
// ../../node_modules/.bun/file-type@21.3.4/node_modules/file-type/index.js
|
|
4080
|
+
function isTokenizerStreamBoundsError(error) {
|
|
4081
|
+
if (!(error instanceof RangeError) || error.message !== "offset is out of bounds" || typeof error.stack !== "string") {
|
|
4082
|
+
return false;
|
|
4083
|
+
}
|
|
4084
|
+
return /strtok3[/\\]lib[/\\]stream[/\\]/.test(error.stack);
|
|
4085
|
+
}
|
|
4086
|
+
var FileTypeParser2 = class extends FileTypeParser {
|
|
4087
|
+
async fromStream(stream) {
|
|
4088
|
+
this.options.signal?.throwIfAborted();
|
|
4089
|
+
const tokenizer = await (stream instanceof WebReadableStream ? this.createTokenizerFromWebStream(stream) : fromStream2(stream, this.getTokenizerOptions()));
|
|
4090
|
+
try {
|
|
4091
|
+
return await super.fromTokenizer(tokenizer);
|
|
4092
|
+
} catch (error) {
|
|
4093
|
+
if (isTokenizerStreamBoundsError(error)) {
|
|
4094
|
+
return;
|
|
4095
|
+
}
|
|
4096
|
+
throw error;
|
|
4097
|
+
} finally {
|
|
4098
|
+
if (stream instanceof Readable && !stream.destroyed) {
|
|
4099
|
+
stream.destroy();
|
|
4100
|
+
}
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
async fromFile(path) {
|
|
4104
|
+
this.options.signal?.throwIfAborted();
|
|
4105
|
+
const fileHandle = await fs.open(path, fileSystemConstants.O_RDONLY | fileSystemConstants.O_NONBLOCK);
|
|
4106
|
+
const fileStat = await fileHandle.stat();
|
|
4107
|
+
if (!fileStat.isFile()) {
|
|
4108
|
+
await fileHandle.close();
|
|
4109
|
+
return;
|
|
4110
|
+
}
|
|
4111
|
+
const tokenizer = new FileTokenizer(fileHandle, {
|
|
4112
|
+
...this.getTokenizerOptions(),
|
|
4113
|
+
fileInfo: {
|
|
4114
|
+
path,
|
|
4115
|
+
size: fileStat.size
|
|
4116
|
+
}
|
|
4117
|
+
});
|
|
4118
|
+
return super.fromTokenizer(tokenizer);
|
|
4119
|
+
}
|
|
4120
|
+
async toDetectionStream(readableStream, options = {}) {
|
|
4121
|
+
if (!(readableStream instanceof Readable)) {
|
|
4122
|
+
return super.toDetectionStream(readableStream, options);
|
|
4123
|
+
}
|
|
4124
|
+
const { sampleSize = reasonableDetectionSizeInBytes } = options;
|
|
4125
|
+
const { signal } = this.options;
|
|
4126
|
+
const normalizedSampleSize = normalizeSampleSize(sampleSize);
|
|
4127
|
+
signal?.throwIfAborted();
|
|
4128
|
+
return new Promise((resolve, reject) => {
|
|
4129
|
+
let isSettled = false;
|
|
4130
|
+
const cleanup = () => {
|
|
4131
|
+
readableStream.off("error", onError);
|
|
4132
|
+
readableStream.off("readable", onReadable);
|
|
4133
|
+
signal?.removeEventListener("abort", onAbort);
|
|
4134
|
+
};
|
|
4135
|
+
const settle = (callback, value) => {
|
|
4136
|
+
if (isSettled) {
|
|
4137
|
+
return;
|
|
4138
|
+
}
|
|
4139
|
+
isSettled = true;
|
|
4140
|
+
cleanup();
|
|
4141
|
+
callback(value);
|
|
4142
|
+
};
|
|
4143
|
+
const onError = (error) => {
|
|
4144
|
+
settle(reject, error);
|
|
4145
|
+
};
|
|
4146
|
+
const onAbort = () => {
|
|
4147
|
+
if (!readableStream.destroyed) {
|
|
4148
|
+
readableStream.destroy();
|
|
4149
|
+
}
|
|
4150
|
+
settle(reject, signal.reason);
|
|
4151
|
+
};
|
|
4152
|
+
const onReadable = () => {
|
|
4153
|
+
(async () => {
|
|
4154
|
+
try {
|
|
4155
|
+
const pass = new PassThrough();
|
|
4156
|
+
const outputStream = pipeline ? pipeline(readableStream, pass, () => {
|
|
4157
|
+
}) : readableStream.pipe(pass);
|
|
4158
|
+
const chunk = readableStream.read(normalizedSampleSize) ?? readableStream.read() ?? new Uint8Array(0);
|
|
4159
|
+
try {
|
|
4160
|
+
pass.fileType = await this.fromBuffer(chunk);
|
|
4161
|
+
} catch (error) {
|
|
4162
|
+
if (error instanceof EndOfStreamError) {
|
|
4163
|
+
pass.fileType = void 0;
|
|
4164
|
+
} else {
|
|
4165
|
+
settle(reject, error);
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
settle(resolve, outputStream);
|
|
4169
|
+
} catch (error) {
|
|
4170
|
+
settle(reject, error);
|
|
4171
|
+
}
|
|
4172
|
+
})();
|
|
4173
|
+
};
|
|
4174
|
+
readableStream.on("error", onError);
|
|
4175
|
+
readableStream.once("readable", onReadable);
|
|
4176
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
4177
|
+
});
|
|
4178
|
+
}
|
|
4179
|
+
};
|
|
4180
|
+
async function fileTypeFromFile(path, options) {
|
|
4181
|
+
return new FileTypeParser2(options).fromFile(path, options);
|
|
4182
|
+
}
|
|
4183
|
+
async function fileTypeFromStream(stream, options) {
|
|
4184
|
+
return new FileTypeParser2(options).fromStream(stream);
|
|
4185
|
+
}
|
|
4186
|
+
async function fileTypeStream(readableStream, options = {}) {
|
|
4187
|
+
return new FileTypeParser2(options).toDetectionStream(readableStream, options);
|
|
4188
|
+
}
|
|
4189
|
+
export {
|
|
4190
|
+
FileTypeParser2 as FileTypeParser,
|
|
4191
|
+
fileTypeFromBlob,
|
|
4192
|
+
fileTypeFromBuffer,
|
|
4193
|
+
fileTypeFromFile,
|
|
4194
|
+
fileTypeFromStream,
|
|
4195
|
+
fileTypeFromTokenizer,
|
|
4196
|
+
fileTypeStream,
|
|
4197
|
+
supportedExtensions,
|
|
4198
|
+
supportedMimeTypes
|
|
4199
|
+
};
|
|
4200
|
+
/*! Bundled license information:
|
|
4201
|
+
|
|
4202
|
+
ieee754/index.js:
|
|
4203
|
+
(*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> *)
|
|
4204
|
+
*/
|
|
4205
|
+
//# sourceMappingURL=file-type-S3UUBVCT.js.map
|