ghc-proxy 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +166 -107
- package/dist/{GptEncoding-DdY2evDX.mjs → GptEncoding-DGbju5p-.mjs} +11 -9
- package/dist/{cl100k_base-ChJqEXhP.mjs → cl100k_base-CR_-ZzWY.mjs} +2 -2
- package/dist/main.mjs +4297 -4566
- package/dist/{o200k_base-DXNwToXP.mjs → o200k_base-8n5G7cJ5.mjs} +2 -2
- package/dist/{p50k_base-Cab7w92R.mjs → p50k_base-Coo3riw5.mjs} +2 -2
- package/dist/{p50k_edit-DkrRw_em.mjs → p50k_edit-Df1WiLDq.mjs} +2 -2
- package/dist/{prompt-DsMdjS4d.mjs → prompt-B9CExZli.mjs} +66 -28
- package/dist/{r50k_base-1vVxWqTY.mjs → r50k_base-CrlP1QVX.mjs} +2 -2
- package/dist/{file-type-BwbWtW7C.mjs → source-BpNO27ea.mjs} +1417 -1248
- package/package.json +12 -12
|
@@ -1,6 +1,320 @@
|
|
|
1
1
|
import { i as __toESM, r as __require, t as __commonJSMin } from "./main.mjs";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
//#region node_modules/@borewit/text-codec/lib/index.js
|
|
3
|
+
const WINDOWS_1252_EXTRA = {
|
|
4
|
+
128: "€",
|
|
5
|
+
130: "‚",
|
|
6
|
+
131: "ƒ",
|
|
7
|
+
132: "„",
|
|
8
|
+
133: "…",
|
|
9
|
+
134: "†",
|
|
10
|
+
135: "‡",
|
|
11
|
+
136: "ˆ",
|
|
12
|
+
137: "‰",
|
|
13
|
+
138: "Š",
|
|
14
|
+
139: "‹",
|
|
15
|
+
140: "Œ",
|
|
16
|
+
142: "Ž",
|
|
17
|
+
145: "‘",
|
|
18
|
+
146: "’",
|
|
19
|
+
147: "“",
|
|
20
|
+
148: "”",
|
|
21
|
+
149: "•",
|
|
22
|
+
150: "–",
|
|
23
|
+
151: "—",
|
|
24
|
+
152: "˜",
|
|
25
|
+
153: "™",
|
|
26
|
+
154: "š",
|
|
27
|
+
155: "›",
|
|
28
|
+
156: "œ",
|
|
29
|
+
158: "ž",
|
|
30
|
+
159: "Ÿ"
|
|
31
|
+
};
|
|
32
|
+
const WINDOWS_1252_REVERSE = {};
|
|
33
|
+
for (const [code, char] of Object.entries(WINDOWS_1252_EXTRA)) WINDOWS_1252_REVERSE[char] = Number.parseInt(code, 10);
|
|
34
|
+
let _utf8Decoder;
|
|
35
|
+
function utf8Decoder() {
|
|
36
|
+
if (typeof globalThis.TextDecoder === "undefined") return void 0;
|
|
37
|
+
return _utf8Decoder !== null && _utf8Decoder !== void 0 ? _utf8Decoder : _utf8Decoder = new globalThis.TextDecoder("utf-8");
|
|
38
|
+
}
|
|
39
|
+
const CHUNK = 32768;
|
|
40
|
+
const REPLACEMENT = 65533;
|
|
41
|
+
/**
|
|
42
|
+
* Decode text from binary data
|
|
43
|
+
*/
|
|
44
|
+
function textDecode(bytes, encoding = "utf-8") {
|
|
45
|
+
switch (encoding.toLowerCase()) {
|
|
46
|
+
case "utf-8":
|
|
47
|
+
case "utf8": {
|
|
48
|
+
const dec = utf8Decoder();
|
|
49
|
+
return dec ? dec.decode(bytes) : decodeUTF8(bytes);
|
|
50
|
+
}
|
|
51
|
+
case "utf-16le": return decodeUTF16LE(bytes);
|
|
52
|
+
case "us-ascii":
|
|
53
|
+
case "ascii": return decodeASCII(bytes);
|
|
54
|
+
case "latin1":
|
|
55
|
+
case "iso-8859-1": return decodeLatin1(bytes);
|
|
56
|
+
case "windows-1252": return decodeWindows1252(bytes);
|
|
57
|
+
default: throw new RangeError(`Encoding '${encoding}' not supported`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function flushChunk(parts, chunk) {
|
|
61
|
+
if (chunk.length === 0) return;
|
|
62
|
+
parts.push(String.fromCharCode.apply(null, chunk));
|
|
63
|
+
chunk.length = 0;
|
|
64
|
+
}
|
|
65
|
+
function pushCodeUnit(parts, chunk, codeUnit) {
|
|
66
|
+
chunk.push(codeUnit);
|
|
67
|
+
if (chunk.length >= CHUNK) flushChunk(parts, chunk);
|
|
68
|
+
}
|
|
69
|
+
function pushCodePoint(parts, chunk, cp) {
|
|
70
|
+
if (cp <= 65535) {
|
|
71
|
+
pushCodeUnit(parts, chunk, cp);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
cp -= 65536;
|
|
75
|
+
pushCodeUnit(parts, chunk, 55296 + (cp >> 10));
|
|
76
|
+
pushCodeUnit(parts, chunk, 56320 + (cp & 1023));
|
|
77
|
+
}
|
|
78
|
+
function decodeUTF8(bytes) {
|
|
79
|
+
const parts = [];
|
|
80
|
+
const chunk = [];
|
|
81
|
+
let i = 0;
|
|
82
|
+
if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) i = 3;
|
|
83
|
+
while (i < bytes.length) {
|
|
84
|
+
const b1 = bytes[i];
|
|
85
|
+
if (b1 <= 127) {
|
|
86
|
+
pushCodeUnit(parts, chunk, b1);
|
|
87
|
+
i++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (b1 < 194 || b1 > 244) {
|
|
91
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
92
|
+
i++;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (b1 <= 223) {
|
|
96
|
+
if (i + 1 >= bytes.length) {
|
|
97
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
98
|
+
i++;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const b2 = bytes[i + 1];
|
|
102
|
+
if ((b2 & 192) !== 128) {
|
|
103
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
104
|
+
i++;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
pushCodeUnit(parts, chunk, (b1 & 31) << 6 | b2 & 63);
|
|
108
|
+
i += 2;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (b1 <= 239) {
|
|
112
|
+
if (i + 2 >= bytes.length) {
|
|
113
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
114
|
+
i++;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const b2 = bytes[i + 1];
|
|
118
|
+
const b3 = bytes[i + 2];
|
|
119
|
+
if (!((b2 & 192) === 128 && (b3 & 192) === 128 && !(b1 === 224 && b2 < 160) && !(b1 === 237 && b2 >= 160))) {
|
|
120
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
121
|
+
i++;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
pushCodeUnit(parts, chunk, (b1 & 15) << 12 | (b2 & 63) << 6 | b3 & 63);
|
|
125
|
+
i += 3;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (i + 3 >= bytes.length) {
|
|
129
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
130
|
+
i++;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const b2 = bytes[i + 1];
|
|
134
|
+
const b3 = bytes[i + 2];
|
|
135
|
+
const b4 = bytes[i + 3];
|
|
136
|
+
if (!((b2 & 192) === 128 && (b3 & 192) === 128 && (b4 & 192) === 128 && !(b1 === 240 && b2 < 144) && !(b1 === 244 && b2 > 143))) {
|
|
137
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
138
|
+
i++;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
pushCodePoint(parts, chunk, (b1 & 7) << 18 | (b2 & 63) << 12 | (b3 & 63) << 6 | b4 & 63);
|
|
142
|
+
i += 4;
|
|
143
|
+
}
|
|
144
|
+
flushChunk(parts, chunk);
|
|
145
|
+
return parts.join("");
|
|
146
|
+
}
|
|
147
|
+
function decodeUTF16LE(bytes) {
|
|
148
|
+
const parts = [];
|
|
149
|
+
const chunk = [];
|
|
150
|
+
const len = bytes.length;
|
|
151
|
+
let i = 0;
|
|
152
|
+
while (i + 1 < len) {
|
|
153
|
+
const u1 = bytes[i] | bytes[i + 1] << 8;
|
|
154
|
+
i += 2;
|
|
155
|
+
if (u1 >= 55296 && u1 <= 56319) {
|
|
156
|
+
if (i + 1 < len) {
|
|
157
|
+
const u2 = bytes[i] | bytes[i + 1] << 8;
|
|
158
|
+
if (u2 >= 56320 && u2 <= 57343) {
|
|
159
|
+
pushCodeUnit(parts, chunk, u1);
|
|
160
|
+
pushCodeUnit(parts, chunk, u2);
|
|
161
|
+
i += 2;
|
|
162
|
+
} else pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
163
|
+
} else pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (u1 >= 56320 && u1 <= 57343) {
|
|
167
|
+
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
pushCodeUnit(parts, chunk, u1);
|
|
171
|
+
}
|
|
172
|
+
if (i < len) pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
173
|
+
flushChunk(parts, chunk);
|
|
174
|
+
return parts.join("");
|
|
175
|
+
}
|
|
176
|
+
function decodeASCII(bytes) {
|
|
177
|
+
const parts = [];
|
|
178
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
179
|
+
const end = Math.min(bytes.length, i + CHUNK);
|
|
180
|
+
const codes = new Array(end - i);
|
|
181
|
+
for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j] & 127;
|
|
182
|
+
parts.push(String.fromCharCode.apply(null, codes));
|
|
183
|
+
}
|
|
184
|
+
return parts.join("");
|
|
185
|
+
}
|
|
186
|
+
function decodeLatin1(bytes) {
|
|
187
|
+
const parts = [];
|
|
188
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
189
|
+
const end = Math.min(bytes.length, i + CHUNK);
|
|
190
|
+
const codes = new Array(end - i);
|
|
191
|
+
for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j];
|
|
192
|
+
parts.push(String.fromCharCode.apply(null, codes));
|
|
193
|
+
}
|
|
194
|
+
return parts.join("");
|
|
195
|
+
}
|
|
196
|
+
function decodeWindows1252(bytes) {
|
|
197
|
+
const parts = [];
|
|
198
|
+
let out = "";
|
|
199
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
200
|
+
const b = bytes[i];
|
|
201
|
+
const extra = b >= 128 && b <= 159 ? WINDOWS_1252_EXTRA[b] : void 0;
|
|
202
|
+
out += extra !== null && extra !== void 0 ? extra : String.fromCharCode(b);
|
|
203
|
+
if (out.length >= CHUNK) {
|
|
204
|
+
parts.push(out);
|
|
205
|
+
out = "";
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (out) parts.push(out);
|
|
209
|
+
return parts.join("");
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region node_modules/token-types/lib/index.js
|
|
213
|
+
function dv(array) {
|
|
214
|
+
return new DataView(array.buffer, array.byteOffset);
|
|
215
|
+
}
|
|
216
|
+
const UINT8 = {
|
|
217
|
+
len: 1,
|
|
218
|
+
get(array, offset) {
|
|
219
|
+
return dv(array).getUint8(offset);
|
|
220
|
+
},
|
|
221
|
+
put(array, offset, value) {
|
|
222
|
+
dv(array).setUint8(offset, value);
|
|
223
|
+
return offset + 1;
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* 16-bit unsigned integer, Little Endian byte order
|
|
228
|
+
*/
|
|
229
|
+
const UINT16_LE = {
|
|
230
|
+
len: 2,
|
|
231
|
+
get(array, offset) {
|
|
232
|
+
return dv(array).getUint16(offset, true);
|
|
233
|
+
},
|
|
234
|
+
put(array, offset, value) {
|
|
235
|
+
dv(array).setUint16(offset, value, true);
|
|
236
|
+
return offset + 2;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* 16-bit unsigned integer, Big Endian byte order
|
|
241
|
+
*/
|
|
242
|
+
const UINT16_BE = {
|
|
243
|
+
len: 2,
|
|
244
|
+
get(array, offset) {
|
|
245
|
+
return dv(array).getUint16(offset);
|
|
246
|
+
},
|
|
247
|
+
put(array, offset, value) {
|
|
248
|
+
dv(array).setUint16(offset, value);
|
|
249
|
+
return offset + 2;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* 32-bit unsigned integer, Little Endian byte order
|
|
254
|
+
*/
|
|
255
|
+
const UINT32_LE = {
|
|
256
|
+
len: 4,
|
|
257
|
+
get(array, offset) {
|
|
258
|
+
return dv(array).getUint32(offset, true);
|
|
259
|
+
},
|
|
260
|
+
put(array, offset, value) {
|
|
261
|
+
dv(array).setUint32(offset, value, true);
|
|
262
|
+
return offset + 4;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* 32-bit unsigned integer, Big Endian byte order
|
|
267
|
+
*/
|
|
268
|
+
const UINT32_BE = {
|
|
269
|
+
len: 4,
|
|
270
|
+
get(array, offset) {
|
|
271
|
+
return dv(array).getUint32(offset);
|
|
272
|
+
},
|
|
273
|
+
put(array, offset, value) {
|
|
274
|
+
dv(array).setUint32(offset, value);
|
|
275
|
+
return offset + 4;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* 32-bit signed integer, Big Endian byte order
|
|
280
|
+
*/
|
|
281
|
+
const INT32_BE = {
|
|
282
|
+
len: 4,
|
|
283
|
+
get(array, offset) {
|
|
284
|
+
return dv(array).getInt32(offset);
|
|
285
|
+
},
|
|
286
|
+
put(array, offset, value) {
|
|
287
|
+
dv(array).setInt32(offset, value);
|
|
288
|
+
return offset + 4;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
/**
|
|
292
|
+
* 64-bit unsigned integer, Little Endian byte order
|
|
293
|
+
*/
|
|
294
|
+
const UINT64_LE = {
|
|
295
|
+
len: 8,
|
|
296
|
+
get(array, offset) {
|
|
297
|
+
return dv(array).getBigUint64(offset, true);
|
|
298
|
+
},
|
|
299
|
+
put(array, offset, value) {
|
|
300
|
+
dv(array).setBigUint64(offset, value, true);
|
|
301
|
+
return offset + 8;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* Consume a fixed number of bytes from the stream and return a string with a specified encoding.
|
|
306
|
+
* Supports all encodings supported by TextDecoder, plus 'windows-1252'.
|
|
307
|
+
*/
|
|
308
|
+
var StringType = class {
|
|
309
|
+
constructor(len, encoding) {
|
|
310
|
+
this.len = len;
|
|
311
|
+
this.encoding = encoding;
|
|
312
|
+
}
|
|
313
|
+
get(data, offset = 0) {
|
|
314
|
+
return textDecode(data.subarray(offset, offset + this.len), this.encoding);
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
//#endregion
|
|
4
318
|
//#region node_modules/strtok3/lib/stream/Errors.js
|
|
5
319
|
const defaultMessages = "End-Of-Stream";
|
|
6
320
|
/**
|
|
@@ -183,7 +497,7 @@ var AbstractTokenizer = class {
|
|
|
183
497
|
* @protected
|
|
184
498
|
*/
|
|
185
499
|
constructor(options) {
|
|
186
|
-
this.numBuffer = new Uint8Array(8);
|
|
500
|
+
this.numBuffer = /* @__PURE__ */ new Uint8Array(8);
|
|
187
501
|
/**
|
|
188
502
|
* Tokenizer-stream position
|
|
189
503
|
*/
|
|
@@ -234,637 +548,271 @@ var AbstractTokenizer = class {
|
|
|
234
548
|
return token.get(this.numBuffer, 0);
|
|
235
549
|
}
|
|
236
550
|
/**
|
|
237
|
-
* Ignore number of bytes, advances the pointer in under tokenizer-stream.
|
|
238
|
-
* @param length - Number of bytes to ignore
|
|
239
|
-
* @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
|
|
240
|
-
*/
|
|
241
|
-
async ignore(length) {
|
|
242
|
-
if (this.fileInfo.size !== void 0) {
|
|
243
|
-
const bytesLeft = this.fileInfo.size - this.position;
|
|
244
|
-
if (length > bytesLeft) {
|
|
245
|
-
this.position += bytesLeft;
|
|
246
|
-
return bytesLeft;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
this.position += length;
|
|
250
|
-
return length;
|
|
251
|
-
}
|
|
252
|
-
async close() {
|
|
253
|
-
await this.abort();
|
|
254
|
-
await this.onClose?.();
|
|
255
|
-
}
|
|
256
|
-
normalizeOptions(uint8Array, options) {
|
|
257
|
-
if (!this.supportsRandomAccess() && options && options.position !== void 0 && options.position < this.position) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
|
|
258
|
-
return {
|
|
259
|
-
mayBeLess: false,
|
|
260
|
-
offset: 0,
|
|
261
|
-
length: uint8Array.length,
|
|
262
|
-
position: this.position,
|
|
263
|
-
...options
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
abort() {
|
|
267
|
-
return Promise.resolve();
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
//#endregion
|
|
271
|
-
//#region node_modules/strtok3/lib/ReadStreamTokenizer.js
|
|
272
|
-
const maxBufferSize = 256e3;
|
|
273
|
-
var ReadStreamTokenizer = class extends AbstractTokenizer {
|
|
274
|
-
/**
|
|
275
|
-
* Constructor
|
|
276
|
-
* @param streamReader stream-reader to read from
|
|
277
|
-
* @param options Tokenizer options
|
|
278
|
-
*/
|
|
279
|
-
constructor(streamReader, options) {
|
|
280
|
-
super(options);
|
|
281
|
-
this.streamReader = streamReader;
|
|
282
|
-
this.fileInfo = options?.fileInfo ?? {};
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Read buffer from tokenizer
|
|
286
|
-
* @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream
|
|
287
|
-
* @param options - Read behaviour options
|
|
288
|
-
* @returns Promise with number of bytes read
|
|
289
|
-
*/
|
|
290
|
-
async readBuffer(uint8Array, options) {
|
|
291
|
-
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
292
|
-
const skipBytes = normOptions.position - this.position;
|
|
293
|
-
if (skipBytes > 0) {
|
|
294
|
-
await this.ignore(skipBytes);
|
|
295
|
-
return this.readBuffer(uint8Array, options);
|
|
296
|
-
}
|
|
297
|
-
if (skipBytes < 0) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
|
|
298
|
-
if (normOptions.length === 0) return 0;
|
|
299
|
-
const bytesRead = await this.streamReader.read(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
|
|
300
|
-
this.position += bytesRead;
|
|
301
|
-
if ((!options || !options.mayBeLess) && bytesRead < normOptions.length) throw new EndOfStreamError();
|
|
302
|
-
return bytesRead;
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Peek (read ahead) buffer from tokenizer
|
|
306
|
-
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
307
|
-
* @param options - Read behaviour options
|
|
308
|
-
* @returns Promise with number of bytes peeked
|
|
309
|
-
*/
|
|
310
|
-
async peekBuffer(uint8Array, options) {
|
|
311
|
-
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
312
|
-
let bytesRead = 0;
|
|
313
|
-
if (normOptions.position) {
|
|
314
|
-
const skipBytes = normOptions.position - this.position;
|
|
315
|
-
if (skipBytes > 0) {
|
|
316
|
-
const skipBuffer = new Uint8Array(normOptions.length + skipBytes);
|
|
317
|
-
bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: normOptions.mayBeLess });
|
|
318
|
-
uint8Array.set(skipBuffer.subarray(skipBytes));
|
|
319
|
-
return bytesRead - skipBytes;
|
|
320
|
-
}
|
|
321
|
-
if (skipBytes < 0) throw new Error("Cannot peek from a negative offset in a stream");
|
|
322
|
-
}
|
|
323
|
-
if (normOptions.length > 0) {
|
|
324
|
-
try {
|
|
325
|
-
bytesRead = await this.streamReader.peek(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
|
|
326
|
-
} catch (err) {
|
|
327
|
-
if (options?.mayBeLess && err instanceof EndOfStreamError) return 0;
|
|
328
|
-
throw err;
|
|
329
|
-
}
|
|
330
|
-
if (!normOptions.mayBeLess && bytesRead < normOptions.length) throw new EndOfStreamError();
|
|
331
|
-
}
|
|
332
|
-
return bytesRead;
|
|
333
|
-
}
|
|
334
|
-
async ignore(length) {
|
|
335
|
-
const bufSize = Math.min(maxBufferSize, length);
|
|
336
|
-
const buf = new Uint8Array(bufSize);
|
|
337
|
-
let totBytesRead = 0;
|
|
338
|
-
while (totBytesRead < length) {
|
|
339
|
-
const remaining = length - totBytesRead;
|
|
340
|
-
const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) });
|
|
341
|
-
if (bytesRead < 0) return bytesRead;
|
|
342
|
-
totBytesRead += bytesRead;
|
|
343
|
-
}
|
|
344
|
-
return totBytesRead;
|
|
345
|
-
}
|
|
346
|
-
abort() {
|
|
347
|
-
return this.streamReader.abort();
|
|
348
|
-
}
|
|
349
|
-
async close() {
|
|
350
|
-
return this.streamReader.close();
|
|
351
|
-
}
|
|
352
|
-
supportsRandomAccess() {
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
//#endregion
|
|
357
|
-
//#region node_modules/strtok3/lib/BufferTokenizer.js
|
|
358
|
-
var BufferTokenizer = class extends AbstractTokenizer {
|
|
359
|
-
/**
|
|
360
|
-
* Construct BufferTokenizer
|
|
361
|
-
* @param uint8Array - Uint8Array to tokenize
|
|
362
|
-
* @param options Tokenizer options
|
|
363
|
-
*/
|
|
364
|
-
constructor(uint8Array, options) {
|
|
365
|
-
super(options);
|
|
366
|
-
this.uint8Array = uint8Array;
|
|
367
|
-
this.fileInfo = {
|
|
368
|
-
...options?.fileInfo ?? {},
|
|
369
|
-
size: uint8Array.length
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Read buffer from tokenizer
|
|
374
|
-
* @param uint8Array - Uint8Array to tokenize
|
|
375
|
-
* @param options - Read behaviour options
|
|
376
|
-
* @returns {Promise<number>}
|
|
377
|
-
*/
|
|
378
|
-
async readBuffer(uint8Array, options) {
|
|
379
|
-
if (options?.position) this.position = options.position;
|
|
380
|
-
const bytesRead = await this.peekBuffer(uint8Array, options);
|
|
381
|
-
this.position += bytesRead;
|
|
382
|
-
return bytesRead;
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Peek (read ahead) buffer from tokenizer
|
|
386
|
-
* @param uint8Array
|
|
387
|
-
* @param options - Read behaviour options
|
|
388
|
-
* @returns {Promise<number>}
|
|
389
|
-
*/
|
|
390
|
-
async peekBuffer(uint8Array, options) {
|
|
391
|
-
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
392
|
-
const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length);
|
|
393
|
-
if (!normOptions.mayBeLess && bytes2read < normOptions.length) throw new EndOfStreamError();
|
|
394
|
-
uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read));
|
|
395
|
-
return bytes2read;
|
|
396
|
-
}
|
|
397
|
-
close() {
|
|
398
|
-
return super.close();
|
|
399
|
-
}
|
|
400
|
-
supportsRandomAccess() {
|
|
401
|
-
return true;
|
|
402
|
-
}
|
|
403
|
-
setPosition(position) {
|
|
404
|
-
this.position = position;
|
|
405
|
-
}
|
|
406
|
-
};
|
|
407
|
-
//#endregion
|
|
408
|
-
//#region node_modules/strtok3/lib/BlobTokenizer.js
|
|
409
|
-
var BlobTokenizer = class extends AbstractTokenizer {
|
|
410
|
-
/**
|
|
411
|
-
* Construct BufferTokenizer
|
|
412
|
-
* @param blob - Uint8Array to tokenize
|
|
413
|
-
* @param options Tokenizer options
|
|
414
|
-
*/
|
|
415
|
-
constructor(blob, options) {
|
|
416
|
-
super(options);
|
|
417
|
-
this.blob = blob;
|
|
418
|
-
this.fileInfo = {
|
|
419
|
-
...options?.fileInfo ?? {},
|
|
420
|
-
size: blob.size,
|
|
421
|
-
mimeType: blob.type
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Read buffer from tokenizer
|
|
426
|
-
* @param uint8Array - Uint8Array to tokenize
|
|
427
|
-
* @param options - Read behaviour options
|
|
428
|
-
* @returns {Promise<number>}
|
|
429
|
-
*/
|
|
430
|
-
async readBuffer(uint8Array, options) {
|
|
431
|
-
if (options?.position) this.position = options.position;
|
|
432
|
-
const bytesRead = await this.peekBuffer(uint8Array, options);
|
|
433
|
-
this.position += bytesRead;
|
|
434
|
-
return bytesRead;
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Peek (read ahead) buffer from tokenizer
|
|
438
|
-
* @param buffer
|
|
439
|
-
* @param options - Read behaviour options
|
|
440
|
-
* @returns {Promise<number>}
|
|
551
|
+
* Ignore number of bytes, advances the pointer in under tokenizer-stream.
|
|
552
|
+
* @param length - Number of bytes to ignore. Must be ≥ 0.
|
|
553
|
+
* @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available
|
|
441
554
|
*/
|
|
442
|
-
async
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
555
|
+
async ignore(length) {
|
|
556
|
+
if (length < 0) throw new RangeError("ignore length must be ≥ 0 bytes");
|
|
557
|
+
if (this.fileInfo.size !== void 0) {
|
|
558
|
+
const bytesLeft = this.fileInfo.size - this.position;
|
|
559
|
+
if (length > bytesLeft) {
|
|
560
|
+
this.position += bytesLeft;
|
|
561
|
+
return bytesLeft;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
this.position += length;
|
|
565
|
+
return length;
|
|
449
566
|
}
|
|
450
|
-
close() {
|
|
451
|
-
|
|
567
|
+
async close() {
|
|
568
|
+
await this.abort();
|
|
569
|
+
await this.onClose?.();
|
|
452
570
|
}
|
|
453
|
-
|
|
454
|
-
|
|
571
|
+
normalizeOptions(uint8Array, options) {
|
|
572
|
+
if (!this.supportsRandomAccess() && options && options.position !== void 0 && options.position < this.position) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
|
|
573
|
+
return {
|
|
574
|
+
mayBeLess: false,
|
|
575
|
+
offset: 0,
|
|
576
|
+
length: uint8Array.length,
|
|
577
|
+
position: this.position,
|
|
578
|
+
...options
|
|
579
|
+
};
|
|
455
580
|
}
|
|
456
|
-
|
|
457
|
-
|
|
581
|
+
abort() {
|
|
582
|
+
return Promise.resolve();
|
|
458
583
|
}
|
|
459
584
|
};
|
|
460
585
|
//#endregion
|
|
461
|
-
//#region node_modules/strtok3/lib/
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
* Will set fileSize, if provided given Stream has set the .path property/
|
|
465
|
-
* @param webStream - Read from Node.js Stream.Readable (must be a byte stream)
|
|
466
|
-
* @param options - Tokenizer options
|
|
467
|
-
* @returns ReadStreamTokenizer
|
|
468
|
-
*/
|
|
469
|
-
function fromWebStream(webStream, options) {
|
|
470
|
-
const webStreamReader = makeWebStreamReader(webStream);
|
|
471
|
-
const _options = options ?? {};
|
|
472
|
-
const chainedClose = _options.onClose;
|
|
473
|
-
_options.onClose = async () => {
|
|
474
|
-
await webStreamReader.close();
|
|
475
|
-
if (chainedClose) return chainedClose();
|
|
476
|
-
};
|
|
477
|
-
return new ReadStreamTokenizer(webStreamReader, _options);
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Construct ReadStreamTokenizer from given Buffer.
|
|
481
|
-
* @param uint8Array - Uint8Array to tokenize
|
|
482
|
-
* @param options - Tokenizer options
|
|
483
|
-
* @returns BufferTokenizer
|
|
484
|
-
*/
|
|
485
|
-
function fromBuffer(uint8Array, options) {
|
|
486
|
-
return new BufferTokenizer(uint8Array, options);
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* Construct ReadStreamTokenizer from given Blob.
|
|
490
|
-
* @param blob - Uint8Array to tokenize
|
|
491
|
-
* @param options - Tokenizer options
|
|
492
|
-
* @returns BufferTokenizer
|
|
493
|
-
*/
|
|
494
|
-
function fromBlob(blob, options) {
|
|
495
|
-
return new BlobTokenizer(blob, options);
|
|
496
|
-
}
|
|
497
|
-
(class FileTokenizer extends AbstractTokenizer {
|
|
586
|
+
//#region node_modules/strtok3/lib/ReadStreamTokenizer.js
|
|
587
|
+
const maxBufferSize = 256e3;
|
|
588
|
+
var ReadStreamTokenizer = class extends AbstractTokenizer {
|
|
498
589
|
/**
|
|
499
|
-
*
|
|
500
|
-
* @param
|
|
590
|
+
* Constructor
|
|
591
|
+
* @param streamReader stream-reader to read from
|
|
592
|
+
* @param options Tokenizer options
|
|
501
593
|
*/
|
|
502
|
-
|
|
503
|
-
const fileHandle = await open(sourceFilePath, "r");
|
|
504
|
-
return new FileTokenizer(fileHandle, { fileInfo: {
|
|
505
|
-
path: sourceFilePath,
|
|
506
|
-
size: (await fileHandle.stat()).size
|
|
507
|
-
} });
|
|
508
|
-
}
|
|
509
|
-
constructor(fileHandle, options) {
|
|
594
|
+
constructor(streamReader, options) {
|
|
510
595
|
super(options);
|
|
511
|
-
this.
|
|
512
|
-
this.fileInfo = options
|
|
596
|
+
this.streamReader = streamReader;
|
|
597
|
+
this.fileInfo = options?.fileInfo ?? {};
|
|
513
598
|
}
|
|
514
599
|
/**
|
|
515
|
-
* Read buffer from
|
|
516
|
-
* @param uint8Array - Uint8Array to
|
|
600
|
+
* Read buffer from tokenizer
|
|
601
|
+
* @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream
|
|
517
602
|
* @param options - Read behaviour options
|
|
518
|
-
* @returns Promise number of bytes read
|
|
603
|
+
* @returns Promise with number of bytes read
|
|
519
604
|
*/
|
|
520
605
|
async readBuffer(uint8Array, options) {
|
|
521
606
|
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
522
|
-
|
|
607
|
+
const skipBytes = normOptions.position - this.position;
|
|
608
|
+
if (skipBytes > 0) {
|
|
609
|
+
await this.ignore(skipBytes);
|
|
610
|
+
return this.readBuffer(uint8Array, options);
|
|
611
|
+
}
|
|
612
|
+
if (skipBytes < 0) throw new Error("`options.position` must be equal or greater than `tokenizer.position`");
|
|
523
613
|
if (normOptions.length === 0) return 0;
|
|
524
|
-
const
|
|
525
|
-
this.position +=
|
|
526
|
-
if (
|
|
527
|
-
return
|
|
614
|
+
const bytesRead = await this.streamReader.read(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
|
|
615
|
+
this.position += bytesRead;
|
|
616
|
+
if ((!options || !options.mayBeLess) && bytesRead < normOptions.length) throw new EndOfStreamError();
|
|
617
|
+
return bytesRead;
|
|
528
618
|
}
|
|
529
619
|
/**
|
|
530
|
-
* Peek buffer from
|
|
620
|
+
* Peek (read ahead) buffer from tokenizer
|
|
531
621
|
* @param uint8Array - Uint8Array (or Buffer) to write data to
|
|
532
622
|
* @param options - Read behaviour options
|
|
533
|
-
* @returns Promise number of bytes
|
|
623
|
+
* @returns Promise with number of bytes peeked
|
|
534
624
|
*/
|
|
535
625
|
async peekBuffer(uint8Array, options) {
|
|
536
626
|
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
537
|
-
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
setPosition(position) {
|
|
546
|
-
this.position = position;
|
|
547
|
-
}
|
|
548
|
-
supportsRandomAccess() {
|
|
549
|
-
return true;
|
|
550
|
-
}
|
|
551
|
-
}).fromFile;
|
|
552
|
-
//#endregion
|
|
553
|
-
//#region node_modules/@borewit/text-codec/lib/index.js
|
|
554
|
-
const WINDOWS_1252_EXTRA = {
|
|
555
|
-
128: "€",
|
|
556
|
-
130: "‚",
|
|
557
|
-
131: "ƒ",
|
|
558
|
-
132: "„",
|
|
559
|
-
133: "…",
|
|
560
|
-
134: "†",
|
|
561
|
-
135: "‡",
|
|
562
|
-
136: "ˆ",
|
|
563
|
-
137: "‰",
|
|
564
|
-
138: "Š",
|
|
565
|
-
139: "‹",
|
|
566
|
-
140: "Œ",
|
|
567
|
-
142: "Ž",
|
|
568
|
-
145: "‘",
|
|
569
|
-
146: "’",
|
|
570
|
-
147: "“",
|
|
571
|
-
148: "”",
|
|
572
|
-
149: "•",
|
|
573
|
-
150: "–",
|
|
574
|
-
151: "—",
|
|
575
|
-
152: "˜",
|
|
576
|
-
153: "™",
|
|
577
|
-
154: "š",
|
|
578
|
-
155: "›",
|
|
579
|
-
156: "œ",
|
|
580
|
-
158: "ž",
|
|
581
|
-
159: "Ÿ"
|
|
582
|
-
};
|
|
583
|
-
const WINDOWS_1252_REVERSE = {};
|
|
584
|
-
for (const [code, char] of Object.entries(WINDOWS_1252_EXTRA)) WINDOWS_1252_REVERSE[char] = Number.parseInt(code, 10);
|
|
585
|
-
let _utf8Decoder;
|
|
586
|
-
function utf8Decoder() {
|
|
587
|
-
if (typeof globalThis.TextDecoder === "undefined") return void 0;
|
|
588
|
-
return _utf8Decoder !== null && _utf8Decoder !== void 0 ? _utf8Decoder : _utf8Decoder = new globalThis.TextDecoder("utf-8");
|
|
589
|
-
}
|
|
590
|
-
const CHUNK = 32 * 1024;
|
|
591
|
-
const REPLACEMENT = 65533;
|
|
592
|
-
/**
|
|
593
|
-
* Decode text from binary data
|
|
594
|
-
*/
|
|
595
|
-
function textDecode(bytes, encoding = "utf-8") {
|
|
596
|
-
switch (encoding.toLowerCase()) {
|
|
597
|
-
case "utf-8":
|
|
598
|
-
case "utf8": {
|
|
599
|
-
const dec = utf8Decoder();
|
|
600
|
-
return dec ? dec.decode(bytes) : decodeUTF8(bytes);
|
|
601
|
-
}
|
|
602
|
-
case "utf-16le": return decodeUTF16LE(bytes);
|
|
603
|
-
case "us-ascii":
|
|
604
|
-
case "ascii": return decodeASCII(bytes);
|
|
605
|
-
case "latin1":
|
|
606
|
-
case "iso-8859-1": return decodeLatin1(bytes);
|
|
607
|
-
case "windows-1252": return decodeWindows1252(bytes);
|
|
608
|
-
default: throw new RangeError(`Encoding '${encoding}' not supported`);
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
function flushChunk(parts, chunk) {
|
|
612
|
-
if (chunk.length === 0) return;
|
|
613
|
-
parts.push(String.fromCharCode.apply(null, chunk));
|
|
614
|
-
chunk.length = 0;
|
|
615
|
-
}
|
|
616
|
-
function pushCodeUnit(parts, chunk, codeUnit) {
|
|
617
|
-
chunk.push(codeUnit);
|
|
618
|
-
if (chunk.length >= CHUNK) flushChunk(parts, chunk);
|
|
619
|
-
}
|
|
620
|
-
function pushCodePoint(parts, chunk, cp) {
|
|
621
|
-
if (cp <= 65535) {
|
|
622
|
-
pushCodeUnit(parts, chunk, cp);
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
cp -= 65536;
|
|
626
|
-
pushCodeUnit(parts, chunk, 55296 + (cp >> 10));
|
|
627
|
-
pushCodeUnit(parts, chunk, 56320 + (cp & 1023));
|
|
628
|
-
}
|
|
629
|
-
function decodeUTF8(bytes) {
|
|
630
|
-
const parts = [];
|
|
631
|
-
const chunk = [];
|
|
632
|
-
let i = 0;
|
|
633
|
-
if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) i = 3;
|
|
634
|
-
while (i < bytes.length) {
|
|
635
|
-
const b1 = bytes[i];
|
|
636
|
-
if (b1 <= 127) {
|
|
637
|
-
pushCodeUnit(parts, chunk, b1);
|
|
638
|
-
i++;
|
|
639
|
-
continue;
|
|
640
|
-
}
|
|
641
|
-
if (b1 < 194 || b1 > 244) {
|
|
642
|
-
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
643
|
-
i++;
|
|
644
|
-
continue;
|
|
645
|
-
}
|
|
646
|
-
if (b1 <= 223) {
|
|
647
|
-
if (i + 1 >= bytes.length) {
|
|
648
|
-
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
649
|
-
i++;
|
|
650
|
-
continue;
|
|
651
|
-
}
|
|
652
|
-
const b2 = bytes[i + 1];
|
|
653
|
-
if ((b2 & 192) !== 128) {
|
|
654
|
-
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
655
|
-
i++;
|
|
656
|
-
continue;
|
|
657
|
-
}
|
|
658
|
-
pushCodeUnit(parts, chunk, (b1 & 31) << 6 | b2 & 63);
|
|
659
|
-
i += 2;
|
|
660
|
-
continue;
|
|
661
|
-
}
|
|
662
|
-
if (b1 <= 239) {
|
|
663
|
-
if (i + 2 >= bytes.length) {
|
|
664
|
-
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
665
|
-
i++;
|
|
666
|
-
continue;
|
|
667
|
-
}
|
|
668
|
-
const b2 = bytes[i + 1];
|
|
669
|
-
const b3 = bytes[i + 2];
|
|
670
|
-
if (!((b2 & 192) === 128 && (b3 & 192) === 128 && !(b1 === 224 && b2 < 160) && !(b1 === 237 && b2 >= 160))) {
|
|
671
|
-
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
672
|
-
i++;
|
|
673
|
-
continue;
|
|
627
|
+
let bytesRead = 0;
|
|
628
|
+
if (normOptions.position) {
|
|
629
|
+
const skipBytes = normOptions.position - this.position;
|
|
630
|
+
if (skipBytes > 0) {
|
|
631
|
+
const skipBuffer = new Uint8Array(normOptions.length + skipBytes);
|
|
632
|
+
bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: normOptions.mayBeLess });
|
|
633
|
+
uint8Array.set(skipBuffer.subarray(skipBytes));
|
|
634
|
+
return bytesRead - skipBytes;
|
|
674
635
|
}
|
|
675
|
-
|
|
676
|
-
i += 3;
|
|
677
|
-
continue;
|
|
678
|
-
}
|
|
679
|
-
if (i + 3 >= bytes.length) {
|
|
680
|
-
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
681
|
-
i++;
|
|
682
|
-
continue;
|
|
636
|
+
if (skipBytes < 0) throw new Error("Cannot peek from a negative offset in a stream");
|
|
683
637
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
638
|
+
if (normOptions.length > 0) {
|
|
639
|
+
try {
|
|
640
|
+
bytesRead = await this.streamReader.peek(uint8Array.subarray(0, normOptions.length), normOptions.mayBeLess);
|
|
641
|
+
} catch (err) {
|
|
642
|
+
if (options?.mayBeLess && err instanceof EndOfStreamError) return 0;
|
|
643
|
+
throw err;
|
|
644
|
+
}
|
|
645
|
+
if (!normOptions.mayBeLess && bytesRead < normOptions.length) throw new EndOfStreamError();
|
|
691
646
|
}
|
|
692
|
-
|
|
693
|
-
i += 4;
|
|
647
|
+
return bytesRead;
|
|
694
648
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
const u2 = bytes[i] | bytes[i + 1] << 8;
|
|
709
|
-
if (u2 >= 56320 && u2 <= 57343) {
|
|
710
|
-
pushCodeUnit(parts, chunk, u1);
|
|
711
|
-
pushCodeUnit(parts, chunk, u2);
|
|
712
|
-
i += 2;
|
|
713
|
-
} else pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
714
|
-
} else pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
715
|
-
continue;
|
|
716
|
-
}
|
|
717
|
-
if (u1 >= 56320 && u1 <= 57343) {
|
|
718
|
-
pushCodeUnit(parts, chunk, REPLACEMENT);
|
|
719
|
-
continue;
|
|
649
|
+
/**
|
|
650
|
+
* @param length Number of bytes to ignore. Must be ≥ 0.
|
|
651
|
+
*/
|
|
652
|
+
async ignore(length) {
|
|
653
|
+
if (length < 0) throw new RangeError("ignore length must be ≥ 0 bytes");
|
|
654
|
+
const bufSize = Math.min(maxBufferSize, length);
|
|
655
|
+
const buf = new Uint8Array(bufSize);
|
|
656
|
+
let totBytesRead = 0;
|
|
657
|
+
while (totBytesRead < length) {
|
|
658
|
+
const remaining = length - totBytesRead;
|
|
659
|
+
const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) });
|
|
660
|
+
if (bytesRead < 0) return bytesRead;
|
|
661
|
+
totBytesRead += bytesRead;
|
|
720
662
|
}
|
|
721
|
-
|
|
663
|
+
return totBytesRead;
|
|
722
664
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
return parts.join("");
|
|
726
|
-
}
|
|
727
|
-
function decodeASCII(bytes) {
|
|
728
|
-
const parts = [];
|
|
729
|
-
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
730
|
-
const end = Math.min(bytes.length, i + CHUNK);
|
|
731
|
-
const codes = new Array(end - i);
|
|
732
|
-
for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j] & 127;
|
|
733
|
-
parts.push(String.fromCharCode.apply(null, codes));
|
|
665
|
+
abort() {
|
|
666
|
+
return this.streamReader.abort();
|
|
734
667
|
}
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
function decodeLatin1(bytes) {
|
|
738
|
-
const parts = [];
|
|
739
|
-
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
740
|
-
const end = Math.min(bytes.length, i + CHUNK);
|
|
741
|
-
const codes = new Array(end - i);
|
|
742
|
-
for (let j = i, k = 0; j < end; j++, k++) codes[k] = bytes[j];
|
|
743
|
-
parts.push(String.fromCharCode.apply(null, codes));
|
|
668
|
+
async close() {
|
|
669
|
+
return this.streamReader.close();
|
|
744
670
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
function decodeWindows1252(bytes) {
|
|
748
|
-
const parts = [];
|
|
749
|
-
let out = "";
|
|
750
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
751
|
-
const b = bytes[i];
|
|
752
|
-
const extra = b >= 128 && b <= 159 ? WINDOWS_1252_EXTRA[b] : void 0;
|
|
753
|
-
out += extra !== null && extra !== void 0 ? extra : String.fromCharCode(b);
|
|
754
|
-
if (out.length >= CHUNK) {
|
|
755
|
-
parts.push(out);
|
|
756
|
-
out = "";
|
|
757
|
-
}
|
|
671
|
+
supportsRandomAccess() {
|
|
672
|
+
return false;
|
|
758
673
|
}
|
|
759
|
-
|
|
760
|
-
return parts.join("");
|
|
761
|
-
}
|
|
674
|
+
};
|
|
762
675
|
//#endregion
|
|
763
|
-
//#region node_modules/
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
676
|
+
//#region node_modules/strtok3/lib/BufferTokenizer.js
|
|
677
|
+
var BufferTokenizer = class extends AbstractTokenizer {
|
|
678
|
+
/**
|
|
679
|
+
* Construct BufferTokenizer
|
|
680
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
681
|
+
* @param options Tokenizer options
|
|
682
|
+
*/
|
|
683
|
+
constructor(uint8Array, options) {
|
|
684
|
+
super(options);
|
|
685
|
+
this.uint8Array = uint8Array;
|
|
686
|
+
this.fileInfo = {
|
|
687
|
+
...options?.fileInfo ?? {},
|
|
688
|
+
size: uint8Array.length
|
|
689
|
+
};
|
|
775
690
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
*
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
return offset + 2;
|
|
691
|
+
/**
|
|
692
|
+
* Read buffer from tokenizer
|
|
693
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
694
|
+
* @param options - Read behaviour options
|
|
695
|
+
* @returns {Promise<number>}
|
|
696
|
+
*/
|
|
697
|
+
async readBuffer(uint8Array, options) {
|
|
698
|
+
if (options?.position) this.position = options.position;
|
|
699
|
+
const bytesRead = await this.peekBuffer(uint8Array, options);
|
|
700
|
+
this.position += bytesRead;
|
|
701
|
+
return bytesRead;
|
|
788
702
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
*
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
return
|
|
703
|
+
/**
|
|
704
|
+
* Peek (read ahead) buffer from tokenizer
|
|
705
|
+
* @param uint8Array
|
|
706
|
+
* @param options - Read behaviour options
|
|
707
|
+
* @returns {Promise<number>}
|
|
708
|
+
*/
|
|
709
|
+
async peekBuffer(uint8Array, options) {
|
|
710
|
+
const normOptions = this.normalizeOptions(uint8Array, options);
|
|
711
|
+
const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length);
|
|
712
|
+
if (!normOptions.mayBeLess && bytes2read < normOptions.length) throw new EndOfStreamError();
|
|
713
|
+
uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read));
|
|
714
|
+
return bytes2read;
|
|
801
715
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
* 32-bit unsigned integer, Little Endian byte order
|
|
805
|
-
*/
|
|
806
|
-
const UINT32_LE = {
|
|
807
|
-
len: 4,
|
|
808
|
-
get(array, offset) {
|
|
809
|
-
return dv(array).getUint32(offset, true);
|
|
810
|
-
},
|
|
811
|
-
put(array, offset, value) {
|
|
812
|
-
dv(array).setUint32(offset, value, true);
|
|
813
|
-
return offset + 4;
|
|
716
|
+
close() {
|
|
717
|
+
return super.close();
|
|
814
718
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
len: 4,
|
|
821
|
-
get(array, offset) {
|
|
822
|
-
return dv(array).getUint32(offset);
|
|
823
|
-
},
|
|
824
|
-
put(array, offset, value) {
|
|
825
|
-
dv(array).setUint32(offset, value);
|
|
826
|
-
return offset + 4;
|
|
719
|
+
supportsRandomAccess() {
|
|
720
|
+
return true;
|
|
721
|
+
}
|
|
722
|
+
setPosition(position) {
|
|
723
|
+
this.position = position;
|
|
827
724
|
}
|
|
828
725
|
};
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
726
|
+
//#endregion
|
|
727
|
+
//#region node_modules/strtok3/lib/BlobTokenizer.js
|
|
728
|
+
var BlobTokenizer = class extends AbstractTokenizer {
|
|
729
|
+
/**
|
|
730
|
+
* Construct BufferTokenizer
|
|
731
|
+
* @param blob - Uint8Array to tokenize
|
|
732
|
+
* @param options Tokenizer options
|
|
733
|
+
*/
|
|
734
|
+
constructor(blob, options) {
|
|
735
|
+
super(options);
|
|
736
|
+
this.blob = blob;
|
|
737
|
+
this.fileInfo = {
|
|
738
|
+
...options?.fileInfo ?? {},
|
|
739
|
+
size: blob.size,
|
|
740
|
+
mimeType: blob.type
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Read buffer from tokenizer
|
|
745
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
746
|
+
* @param options - Read behaviour options
|
|
747
|
+
* @returns {Promise<number>}
|
|
748
|
+
*/
|
|
749
|
+
async readBuffer(uint8Array, options) {
|
|
750
|
+
if (options?.position) this.position = options.position;
|
|
751
|
+
const bytesRead = await this.peekBuffer(uint8Array, options);
|
|
752
|
+
this.position += bytesRead;
|
|
753
|
+
return bytesRead;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Peek (read ahead) buffer from tokenizer
|
|
757
|
+
* @param buffer
|
|
758
|
+
* @param options - Read behaviour options
|
|
759
|
+
* @returns {Promise<number>}
|
|
760
|
+
*/
|
|
761
|
+
async peekBuffer(buffer, options) {
|
|
762
|
+
const normOptions = this.normalizeOptions(buffer, options);
|
|
763
|
+
const bytes2read = Math.min(this.blob.size - normOptions.position, normOptions.length);
|
|
764
|
+
if (!normOptions.mayBeLess && bytes2read < normOptions.length) throw new EndOfStreamError();
|
|
765
|
+
const arrayBuffer = await this.blob.slice(normOptions.position, normOptions.position + bytes2read).arrayBuffer();
|
|
766
|
+
buffer.set(new Uint8Array(arrayBuffer));
|
|
767
|
+
return bytes2read;
|
|
768
|
+
}
|
|
769
|
+
close() {
|
|
770
|
+
return super.close();
|
|
771
|
+
}
|
|
772
|
+
supportsRandomAccess() {
|
|
773
|
+
return true;
|
|
774
|
+
}
|
|
775
|
+
setPosition(position) {
|
|
776
|
+
this.position = position;
|
|
840
777
|
}
|
|
841
778
|
};
|
|
779
|
+
//#endregion
|
|
780
|
+
//#region node_modules/strtok3/lib/core.js
|
|
842
781
|
/**
|
|
843
|
-
*
|
|
782
|
+
* Construct ReadStreamTokenizer from given ReadableStream (WebStream API).
|
|
783
|
+
* Will set fileSize, if provided given Stream has set the .path property/
|
|
784
|
+
* @param webStream - Read from Node.js Stream.Readable (must be a byte stream)
|
|
785
|
+
* @param options - Tokenizer options
|
|
786
|
+
* @returns ReadStreamTokenizer
|
|
844
787
|
*/
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
}
|
|
788
|
+
function fromWebStream(webStream, options) {
|
|
789
|
+
const webStreamReader = makeWebStreamReader(webStream);
|
|
790
|
+
const _options = options ?? {};
|
|
791
|
+
const chainedClose = _options.onClose;
|
|
792
|
+
_options.onClose = async () => {
|
|
793
|
+
await webStreamReader.close();
|
|
794
|
+
if (chainedClose) return chainedClose();
|
|
795
|
+
};
|
|
796
|
+
return new ReadStreamTokenizer(webStreamReader, _options);
|
|
797
|
+
}
|
|
855
798
|
/**
|
|
856
|
-
*
|
|
857
|
-
*
|
|
799
|
+
* Construct ReadStreamTokenizer from given Buffer.
|
|
800
|
+
* @param uint8Array - Uint8Array to tokenize
|
|
801
|
+
* @param options - Tokenizer options
|
|
802
|
+
* @returns BufferTokenizer
|
|
858
803
|
*/
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
804
|
+
function fromBuffer(uint8Array, options) {
|
|
805
|
+
return new BufferTokenizer(uint8Array, options);
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Construct ReadStreamTokenizer from given Blob.
|
|
809
|
+
* @param blob - Uint8Array to tokenize
|
|
810
|
+
* @param options - Tokenizer options
|
|
811
|
+
* @returns BufferTokenizer
|
|
812
|
+
*/
|
|
813
|
+
function fromBlob(blob, options) {
|
|
814
|
+
return new BlobTokenizer(blob, options);
|
|
815
|
+
}
|
|
868
816
|
//#endregion
|
|
869
817
|
//#region node_modules/ms/index.js
|
|
870
818
|
var require_ms = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -1123,15 +1071,16 @@ var require_common = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1123
1071
|
let templateIndex = 0;
|
|
1124
1072
|
let starIndex = -1;
|
|
1125
1073
|
let matchIndex = 0;
|
|
1126
|
-
while (searchIndex < search.length) if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*"))
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1074
|
+
while (searchIndex < search.length) if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) {
|
|
1075
|
+
if (template[templateIndex] === "*") {
|
|
1076
|
+
starIndex = templateIndex;
|
|
1077
|
+
matchIndex = searchIndex;
|
|
1078
|
+
templateIndex++;
|
|
1079
|
+
} else {
|
|
1080
|
+
searchIndex++;
|
|
1081
|
+
templateIndex++;
|
|
1082
|
+
}
|
|
1083
|
+
} else if (starIndex !== -1) {
|
|
1135
1084
|
templateIndex = starIndex + 1;
|
|
1136
1085
|
matchIndex++;
|
|
1137
1086
|
searchIndex = matchIndex;
|
|
@@ -1726,7 +1675,7 @@ function signatureToArray(signature) {
|
|
|
1726
1675
|
return signatureBytes;
|
|
1727
1676
|
}
|
|
1728
1677
|
const debug = (0, import_src.default)("tokenizer:inflate");
|
|
1729
|
-
const syncBufferSize =
|
|
1678
|
+
const syncBufferSize = 262144;
|
|
1730
1679
|
const ddSignatureArray = signatureToArray(Signature.DataDescriptor);
|
|
1731
1680
|
const eocdSignatureBytes = signatureToArray(Signature.EndOfCentralDirectory);
|
|
1732
1681
|
var ZipHandler = class ZipHandler {
|
|
@@ -1742,7 +1691,7 @@ var ZipHandler = class ZipHandler {
|
|
|
1742
1691
|
}
|
|
1743
1692
|
async findEndOfCentralDirectoryLocator() {
|
|
1744
1693
|
const randomReadTokenizer = this.tokenizer;
|
|
1745
|
-
const chunkLength = Math.min(
|
|
1694
|
+
const chunkLength = Math.min(16384, randomReadTokenizer.fileInfo.size);
|
|
1746
1695
|
const buffer = this.syncBuffer.subarray(0, chunkLength);
|
|
1747
1696
|
await this.tokenizer.readBuffer(buffer, { position: randomReadTokenizer.fileInfo.size - chunkLength });
|
|
1748
1697
|
for (let i = buffer.length - 4; i >= 0; i--) if (buffer[i] === eocdSignatureBytes[0] && buffer[i + 1] === eocdSignatureBytes[1] && buffer[i + 2] === eocdSignatureBytes[2] && buffer[i + 3] === eocdSignatureBytes[3]) return randomReadTokenizer.fileInfo.size - chunkLength + i;
|
|
@@ -1900,7 +1849,7 @@ var GzipHandler = class {
|
|
|
1900
1849
|
inflate() {
|
|
1901
1850
|
const tokenizer = this.tokenizer;
|
|
1902
1851
|
return new ReadableStream({ async pull(controller) {
|
|
1903
|
-
const buffer = new Uint8Array(1024);
|
|
1852
|
+
const buffer = /* @__PURE__ */ new Uint8Array(1024);
|
|
1904
1853
|
const size = await tokenizer.readBuffer(buffer, { mayBeLess: true });
|
|
1905
1854
|
if (size === 0) {
|
|
1906
1855
|
controller.close();
|
|
@@ -1910,6 +1859,33 @@ var GzipHandler = class {
|
|
|
1910
1859
|
} }).pipeThrough(new DecompressionStream("gzip"));
|
|
1911
1860
|
}
|
|
1912
1861
|
};
|
|
1862
|
+
//#endregion
|
|
1863
|
+
//#region node_modules/uint8array-extras/index.js
|
|
1864
|
+
const objectToString = Object.prototype.toString;
|
|
1865
|
+
const uint8ArrayStringified = "[object Uint8Array]";
|
|
1866
|
+
function isType(value, typeConstructor, typeStringified) {
|
|
1867
|
+
if (!value) return false;
|
|
1868
|
+
if (value.constructor === typeConstructor) return true;
|
|
1869
|
+
return objectToString.call(value) === typeStringified;
|
|
1870
|
+
}
|
|
1871
|
+
function isUint8Array(value) {
|
|
1872
|
+
return isType(value, Uint8Array, uint8ArrayStringified);
|
|
1873
|
+
}
|
|
1874
|
+
function assertUint8Array(value) {
|
|
1875
|
+
if (!isUint8Array(value)) throw new TypeError(`Expected \`Uint8Array\`, got \`${typeof value}\``);
|
|
1876
|
+
}
|
|
1877
|
+
function concatUint8Arrays(arrays, totalLength) {
|
|
1878
|
+
if (arrays.length === 0) return /* @__PURE__ */ new Uint8Array(0);
|
|
1879
|
+
totalLength ??= arrays.reduce((accumulator, currentValue) => accumulator + currentValue.length, 0);
|
|
1880
|
+
const returnValue = new Uint8Array(totalLength);
|
|
1881
|
+
let offset = 0;
|
|
1882
|
+
for (const array of arrays) {
|
|
1883
|
+
assertUint8Array(array);
|
|
1884
|
+
returnValue.set(array, offset);
|
|
1885
|
+
offset += array.length;
|
|
1886
|
+
}
|
|
1887
|
+
return returnValue;
|
|
1888
|
+
}
|
|
1913
1889
|
new globalThis.TextDecoder("utf8");
|
|
1914
1890
|
new globalThis.TextEncoder();
|
|
1915
1891
|
Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
|
|
@@ -1927,7 +1903,7 @@ function getUintBE(view) {
|
|
|
1927
1903
|
if (byteLength === 1) return view.getUint8(0);
|
|
1928
1904
|
}
|
|
1929
1905
|
//#endregion
|
|
1930
|
-
//#region node_modules/file-type/
|
|
1906
|
+
//#region node_modules/file-type/source/tokens.js
|
|
1931
1907
|
function stringToBytes(string, encoding) {
|
|
1932
1908
|
if (encoding === "utf-16le") {
|
|
1933
1909
|
const bytes = [];
|
|
@@ -1955,7 +1931,7 @@ Checks whether the TAR checksum is valid.
|
|
|
1955
1931
|
@returns {boolean} `true` if the TAR checksum is valid, otherwise `false`.
|
|
1956
1932
|
*/
|
|
1957
1933
|
function tarHeaderChecksumMatches(arrayBuffer, offset = 0) {
|
|
1958
|
-
const readSum = Number.parseInt(new StringType(6).get(arrayBuffer, 148).replace(
|
|
1934
|
+
const readSum = Number.parseInt(new StringType(6).get(arrayBuffer, 148).replace(new RegExp("\\0.*$", "v"), "").trim(), 8);
|
|
1959
1935
|
if (Number.isNaN(readSum)) return false;
|
|
1960
1936
|
let sum = 256;
|
|
1961
1937
|
for (let index = offset; index < offset + 148; index++) sum += arrayBuffer[index];
|
|
@@ -1967,11 +1943,11 @@ ID3 UINT32 sync-safe tokenizer token.
|
|
|
1967
1943
|
28 bits (representing up to 256MB) integer, the msb is 0 to avoid "false syncsignals".
|
|
1968
1944
|
*/
|
|
1969
1945
|
const uint32SyncSafeToken = {
|
|
1970
|
-
get: (buffer, offset) => buffer[offset + 3] & 127 | buffer[offset + 2] << 7 | buffer[offset + 1] << 14 | buffer[offset] << 21,
|
|
1946
|
+
get: (buffer, offset) => buffer[offset + 3] & 127 | (buffer[offset + 2] & 127) << 7 | (buffer[offset + 1] & 127) << 14 | (buffer[offset] & 127) << 21,
|
|
1971
1947
|
len: 4
|
|
1972
1948
|
};
|
|
1973
1949
|
//#endregion
|
|
1974
|
-
//#region node_modules/file-type/supported.js
|
|
1950
|
+
//#region node_modules/file-type/source/supported.js
|
|
1975
1951
|
const extensions = [
|
|
1976
1952
|
"jpg",
|
|
1977
1953
|
"png",
|
|
@@ -2152,7 +2128,10 @@ const extensions = [
|
|
|
2152
2128
|
"ppsx",
|
|
2153
2129
|
"tar.gz",
|
|
2154
2130
|
"reg",
|
|
2155
|
-
"dat"
|
|
2131
|
+
"dat",
|
|
2132
|
+
"key",
|
|
2133
|
+
"numbers",
|
|
2134
|
+
"pages"
|
|
2156
2135
|
];
|
|
2157
2136
|
const mimeTypes = [
|
|
2158
2137
|
"image/jpeg",
|
|
@@ -2235,7 +2214,7 @@ const mimeTypes = [
|
|
|
2235
2214
|
"application/x-unix-archive",
|
|
2236
2215
|
"application/x-rpm",
|
|
2237
2216
|
"application/x-compress",
|
|
2238
|
-
"application/
|
|
2217
|
+
"application/lzip",
|
|
2239
2218
|
"application/x-cfb",
|
|
2240
2219
|
"application/x-mie",
|
|
2241
2220
|
"application/mxf",
|
|
@@ -2264,8 +2243,8 @@ const mimeTypes = [
|
|
|
2264
2243
|
"model/gltf-binary",
|
|
2265
2244
|
"application/vnd.tcpdump.pcap",
|
|
2266
2245
|
"audio/x-dsf",
|
|
2267
|
-
"application/x
|
|
2268
|
-
"application/x
|
|
2246
|
+
"application/x-ms-shortcut",
|
|
2247
|
+
"application/x-ft-apple.alias",
|
|
2269
2248
|
"audio/x-voc",
|
|
2270
2249
|
"audio/vnd.dolby.dd-raw",
|
|
2271
2250
|
"audio/x-m4a",
|
|
@@ -2305,10 +2284,10 @@ const mimeTypes = [
|
|
|
2305
2284
|
"application/x-ace-compressed",
|
|
2306
2285
|
"application/avro",
|
|
2307
2286
|
"application/vnd.iccprofile",
|
|
2308
|
-
"application/x
|
|
2287
|
+
"application/x-ft-fbx",
|
|
2309
2288
|
"application/vnd.visio",
|
|
2310
2289
|
"application/vnd.android.package-archive",
|
|
2311
|
-
"application/
|
|
2290
|
+
"application/x-ft-draco",
|
|
2312
2291
|
"application/x-lz4",
|
|
2313
2292
|
"application/vnd.openxmlformats-officedocument.presentationml.template",
|
|
2314
2293
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.template",
|
|
@@ -2329,48 +2308,14 @@ const mimeTypes = [
|
|
|
2329
2308
|
"application/x-spss-sav",
|
|
2330
2309
|
"application/x-ms-regedit",
|
|
2331
2310
|
"application/x-ft-windows-registry-hive",
|
|
2332
|
-
"application/x-jmp-data"
|
|
2311
|
+
"application/x-jmp-data",
|
|
2312
|
+
"application/vnd.apple.keynote",
|
|
2313
|
+
"application/vnd.apple.numbers",
|
|
2314
|
+
"application/vnd.apple.pages"
|
|
2333
2315
|
];
|
|
2334
2316
|
//#endregion
|
|
2335
|
-
//#region node_modules/file-type/
|
|
2336
|
-
|
|
2337
|
-
Primary entry point, Node.js specific entry point is index.js
|
|
2338
|
-
*/
|
|
2339
|
-
const reasonableDetectionSizeInBytes = 4100;
|
|
2340
|
-
const maximumMpegOffsetTolerance = reasonableDetectionSizeInBytes - 2;
|
|
2341
|
-
const maximumZipEntrySizeInBytes = 1024 * 1024;
|
|
2342
|
-
const maximumZipEntryCount = 1024;
|
|
2343
|
-
const maximumZipBufferedReadSizeInBytes = 2 ** 31 - 1;
|
|
2344
|
-
const maximumUntrustedSkipSizeInBytes = 16 * 1024 * 1024;
|
|
2345
|
-
const maximumZipTextEntrySizeInBytes = maximumZipEntrySizeInBytes;
|
|
2346
|
-
const maximumNestedGzipDetectionSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
2347
|
-
const maximumNestedGzipProbeDepth = 1;
|
|
2348
|
-
const maximumId3HeaderSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
2349
|
-
const maximumEbmlDocumentTypeSizeInBytes = 64;
|
|
2350
|
-
const maximumEbmlElementPayloadSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
2351
|
-
const maximumEbmlElementCount = 256;
|
|
2352
|
-
const maximumPngChunkCount = 512;
|
|
2353
|
-
const maximumAsfHeaderObjectCount = 512;
|
|
2354
|
-
const maximumTiffTagCount = 512;
|
|
2355
|
-
const maximumDetectionReentryCount = 256;
|
|
2356
|
-
const maximumPngChunkSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
2357
|
-
const maximumTiffIfdOffsetInBytes = maximumUntrustedSkipSizeInBytes;
|
|
2358
|
-
const recoverableZipErrorMessages = new Set([
|
|
2359
|
-
"Unexpected signature",
|
|
2360
|
-
"Encrypted ZIP",
|
|
2361
|
-
"Expected Central-File-Header signature"
|
|
2362
|
-
]);
|
|
2363
|
-
const recoverableZipErrorMessagePrefixes = [
|
|
2364
|
-
"ZIP entry count exceeds ",
|
|
2365
|
-
"Unsupported ZIP compression method:",
|
|
2366
|
-
"ZIP entry compressed data exceeds ",
|
|
2367
|
-
"ZIP entry decompressed data exceeds "
|
|
2368
|
-
];
|
|
2369
|
-
const recoverableZipErrorCodes = new Set([
|
|
2370
|
-
"Z_BUF_ERROR",
|
|
2371
|
-
"Z_DATA_ERROR",
|
|
2372
|
-
"ERR_INVALID_STATE"
|
|
2373
|
-
]);
|
|
2317
|
+
//#region node_modules/file-type/source/parser.js
|
|
2318
|
+
const maximumUntrustedSkipSizeInBytes = 16777216;
|
|
2374
2319
|
var ParserHardLimitError = class extends Error {};
|
|
2375
2320
|
function getSafeBound(value, maximum, reason) {
|
|
2376
2321
|
if (!Number.isFinite(value) || value < 0 || value > maximum) throw new ParserHardLimitError(`${reason} has invalid size ${value} (maximum ${maximum} bytes)`);
|
|
@@ -2387,154 +2332,133 @@ async function safeReadBuffer(tokenizer, buffer, options, { maximumLength = buff
|
|
|
2387
2332
|
length: safeLength
|
|
2388
2333
|
});
|
|
2389
2334
|
}
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
}
|
|
2395
|
-
const
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
const { done, value } = await reader.read();
|
|
2400
|
-
if (done) break;
|
|
2401
|
-
totalLength += value.length;
|
|
2402
|
-
if (totalLength > maximumLength) {
|
|
2403
|
-
await reader.cancel();
|
|
2404
|
-
throw new Error(`ZIP entry decompressed data exceeds ${maximumLength} bytes`);
|
|
2405
|
-
}
|
|
2406
|
-
chunks.push(value);
|
|
2407
|
-
}
|
|
2408
|
-
} finally {
|
|
2409
|
-
reader.releaseLock();
|
|
2410
|
-
}
|
|
2411
|
-
const uncompressedData = new Uint8Array(totalLength);
|
|
2412
|
-
let offset = 0;
|
|
2413
|
-
for (const chunk of chunks) {
|
|
2414
|
-
uncompressedData.set(chunk, offset);
|
|
2415
|
-
offset += chunk.length;
|
|
2416
|
-
}
|
|
2417
|
-
return uncompressedData;
|
|
2418
|
-
}
|
|
2419
|
-
const zipDataDescriptorSignature = 134695760;
|
|
2420
|
-
const zipDataDescriptorLengthInBytes = 16;
|
|
2421
|
-
const zipDataDescriptorOverlapLengthInBytes = zipDataDescriptorLengthInBytes - 1;
|
|
2422
|
-
function findZipDataDescriptorOffset(buffer, bytesConsumed) {
|
|
2423
|
-
if (buffer.length < zipDataDescriptorLengthInBytes) return -1;
|
|
2424
|
-
const lastPossibleDescriptorOffset = buffer.length - zipDataDescriptorLengthInBytes;
|
|
2425
|
-
for (let index = 0; index <= lastPossibleDescriptorOffset; index++) if (UINT32_LE.get(buffer, index) === zipDataDescriptorSignature && UINT32_LE.get(buffer, index + 8) === bytesConsumed + index) return index;
|
|
2426
|
-
return -1;
|
|
2427
|
-
}
|
|
2428
|
-
function mergeByteChunks(chunks, totalLength) {
|
|
2429
|
-
const merged = new Uint8Array(totalLength);
|
|
2430
|
-
let offset = 0;
|
|
2431
|
-
for (const chunk of chunks) {
|
|
2432
|
-
merged.set(chunk, offset);
|
|
2433
|
-
offset += chunk.length;
|
|
2434
|
-
}
|
|
2435
|
-
return merged;
|
|
2335
|
+
function checkBytes(buffer, headers, options) {
|
|
2336
|
+
options = {
|
|
2337
|
+
offset: 0,
|
|
2338
|
+
...options
|
|
2339
|
+
};
|
|
2340
|
+
for (const [index, header] of headers.entries()) if (options.mask) {
|
|
2341
|
+
if (header !== (options.mask[index] & buffer[index + options.offset])) return false;
|
|
2342
|
+
} else if (header !== buffer[index + options.offset]) return false;
|
|
2343
|
+
return true;
|
|
2436
2344
|
}
|
|
2437
|
-
|
|
2438
|
-
const
|
|
2439
|
-
|
|
2440
|
-
const chunks = [];
|
|
2441
|
-
let bytesConsumed = 0;
|
|
2442
|
-
for (;;) {
|
|
2443
|
-
const length = await zipHandler.tokenizer.peekBuffer(syncBuffer, { mayBeLess: true });
|
|
2444
|
-
const dataDescriptorOffset = findZipDataDescriptorOffset(syncBuffer.subarray(0, length), bytesConsumed);
|
|
2445
|
-
const retainedLength = dataDescriptorOffset >= 0 ? 0 : length === syncBufferLength ? Math.min(zipDataDescriptorOverlapLengthInBytes, length - 1) : 0;
|
|
2446
|
-
const chunkLength = dataDescriptorOffset >= 0 ? dataDescriptorOffset : length - retainedLength;
|
|
2447
|
-
if (chunkLength === 0) break;
|
|
2448
|
-
bytesConsumed += chunkLength;
|
|
2449
|
-
if (bytesConsumed > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
|
|
2450
|
-
if (shouldBuffer) {
|
|
2451
|
-
const data = new Uint8Array(chunkLength);
|
|
2452
|
-
await zipHandler.tokenizer.readBuffer(data);
|
|
2453
|
-
chunks.push(data);
|
|
2454
|
-
} else await zipHandler.tokenizer.ignore(chunkLength);
|
|
2455
|
-
if (dataDescriptorOffset >= 0) break;
|
|
2456
|
-
}
|
|
2457
|
-
if (!shouldBuffer) return;
|
|
2458
|
-
return mergeByteChunks(chunks, bytesConsumed);
|
|
2345
|
+
function hasUnknownFileSize(tokenizer) {
|
|
2346
|
+
const fileSize = tokenizer.fileInfo.size;
|
|
2347
|
+
return !Number.isFinite(fileSize) || fileSize === Number.MAX_SAFE_INTEGER;
|
|
2459
2348
|
}
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
if (!shouldBuffer) {
|
|
2463
|
-
await zipHandler.tokenizer.ignore(zipHeader.compressedSize);
|
|
2464
|
-
return;
|
|
2465
|
-
}
|
|
2466
|
-
const maximumLength = getMaximumZipBufferedReadLength(zipHandler.tokenizer);
|
|
2467
|
-
if (!Number.isFinite(zipHeader.compressedSize) || zipHeader.compressedSize < 0 || zipHeader.compressedSize > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
|
|
2468
|
-
const fileData = new Uint8Array(zipHeader.compressedSize);
|
|
2469
|
-
await zipHandler.tokenizer.readBuffer(fileData);
|
|
2470
|
-
return fileData;
|
|
2349
|
+
function hasExceededUnknownSizeScanBudget(tokenizer, startOffset, maximumBytes) {
|
|
2350
|
+
return hasUnknownFileSize(tokenizer) && tokenizer.position - startOffset > maximumBytes;
|
|
2471
2351
|
}
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
let
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
controller.close();
|
|
2511
|
-
await cancelSource();
|
|
2512
|
-
return;
|
|
2513
|
-
}
|
|
2514
|
-
const { done, value } = await reader.read();
|
|
2515
|
-
if (done || !value) {
|
|
2516
|
-
sourceDone = true;
|
|
2517
|
-
controller.close();
|
|
2518
|
-
return;
|
|
2519
|
-
}
|
|
2520
|
-
const remainingBytes = maximumBytes - emittedBytes;
|
|
2521
|
-
if (value.length > remainingBytes) {
|
|
2522
|
-
controller.enqueue(value.subarray(0, remainingBytes));
|
|
2523
|
-
emittedBytes += remainingBytes;
|
|
2524
|
-
controller.close();
|
|
2525
|
-
await cancelSource();
|
|
2526
|
-
return;
|
|
2352
|
+
//#endregion
|
|
2353
|
+
//#region node_modules/file-type/source/detectors/zip.js
|
|
2354
|
+
const maximumZipEntrySizeInBytes = 1048576;
|
|
2355
|
+
const maximumZipEntryCount = 1024;
|
|
2356
|
+
const maximumZipBufferedReadSizeInBytes = 2 ** 31 - 1;
|
|
2357
|
+
const maximumZipTextEntrySizeInBytes = maximumZipEntrySizeInBytes;
|
|
2358
|
+
const recoverableZipErrorMessages = /* @__PURE__ */ new Set([
|
|
2359
|
+
"Unexpected signature",
|
|
2360
|
+
"Encrypted ZIP",
|
|
2361
|
+
"Expected Central-File-Header signature"
|
|
2362
|
+
]);
|
|
2363
|
+
const recoverableZipErrorMessagePrefixes = [
|
|
2364
|
+
"ZIP entry count exceeds ",
|
|
2365
|
+
"Unsupported ZIP compression method:",
|
|
2366
|
+
"ZIP entry compressed data exceeds ",
|
|
2367
|
+
"ZIP entry decompressed data exceeds ",
|
|
2368
|
+
"Expected data-descriptor-signature at position "
|
|
2369
|
+
];
|
|
2370
|
+
const recoverableZipErrorCodes = /* @__PURE__ */ new Set([
|
|
2371
|
+
"Z_BUF_ERROR",
|
|
2372
|
+
"Z_DATA_ERROR",
|
|
2373
|
+
"ERR_INVALID_STATE"
|
|
2374
|
+
]);
|
|
2375
|
+
async function decompressDeflateRawWithLimit(data, { maximumLength = maximumZipEntrySizeInBytes } = {}) {
|
|
2376
|
+
const reader = new ReadableStream({ start(controller) {
|
|
2377
|
+
controller.enqueue(data);
|
|
2378
|
+
controller.close();
|
|
2379
|
+
} }).pipeThrough(new DecompressionStream("deflate-raw")).getReader();
|
|
2380
|
+
const chunks = [];
|
|
2381
|
+
let totalLength = 0;
|
|
2382
|
+
try {
|
|
2383
|
+
for (;;) {
|
|
2384
|
+
const { done, value } = await reader.read();
|
|
2385
|
+
if (done) break;
|
|
2386
|
+
totalLength += value.length;
|
|
2387
|
+
if (totalLength > maximumLength) {
|
|
2388
|
+
await reader.cancel().catch(() => {});
|
|
2389
|
+
throw new Error(`ZIP entry decompressed data exceeds ${maximumLength} bytes`);
|
|
2527
2390
|
}
|
|
2528
|
-
|
|
2529
|
-
emittedBytes += value.length;
|
|
2530
|
-
},
|
|
2531
|
-
async cancel(reason) {
|
|
2532
|
-
await cancelSource(reason);
|
|
2391
|
+
chunks.push(value);
|
|
2533
2392
|
}
|
|
2534
|
-
})
|
|
2393
|
+
} catch (error) {
|
|
2394
|
+
if (error.code !== "ERR_TRAILING_JUNK_AFTER_STREAM_END") throw error;
|
|
2395
|
+
} finally {
|
|
2396
|
+
reader.releaseLock();
|
|
2397
|
+
}
|
|
2398
|
+
const uncompressedData = new Uint8Array(totalLength);
|
|
2399
|
+
let offset = 0;
|
|
2400
|
+
for (const chunk of chunks) {
|
|
2401
|
+
uncompressedData.set(chunk, offset);
|
|
2402
|
+
offset += chunk.length;
|
|
2403
|
+
}
|
|
2404
|
+
return uncompressedData;
|
|
2535
2405
|
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2406
|
+
function mergeByteChunks(chunks, totalLength) {
|
|
2407
|
+
const merged = new Uint8Array(totalLength);
|
|
2408
|
+
let offset = 0;
|
|
2409
|
+
for (const chunk of chunks) {
|
|
2410
|
+
merged.set(chunk, offset);
|
|
2411
|
+
offset += chunk.length;
|
|
2412
|
+
}
|
|
2413
|
+
return merged;
|
|
2414
|
+
}
|
|
2415
|
+
function getMaximumZipBufferedReadLength(tokenizer) {
|
|
2416
|
+
const fileSize = tokenizer.fileInfo.size;
|
|
2417
|
+
const remainingBytes = Number.isFinite(fileSize) ? Math.max(0, fileSize - tokenizer.position) : Number.MAX_SAFE_INTEGER;
|
|
2418
|
+
return Math.min(remainingBytes, maximumZipBufferedReadSizeInBytes);
|
|
2419
|
+
}
|
|
2420
|
+
function isRecoverableZipError(error) {
|
|
2421
|
+
if (error instanceof EndOfStreamError) return true;
|
|
2422
|
+
if (error instanceof ParserHardLimitError) return true;
|
|
2423
|
+
if (!(error instanceof Error)) return false;
|
|
2424
|
+
if (recoverableZipErrorMessages.has(error.message)) return true;
|
|
2425
|
+
if (recoverableZipErrorCodes.has(error.code)) return true;
|
|
2426
|
+
for (const prefix of recoverableZipErrorMessagePrefixes) if (error.message.startsWith(prefix)) return true;
|
|
2427
|
+
return false;
|
|
2428
|
+
}
|
|
2429
|
+
function canReadZipEntryForDetection(zipHeader, maximumSize = maximumZipEntrySizeInBytes) {
|
|
2430
|
+
const sizes = [zipHeader.compressedSize, zipHeader.uncompressedSize];
|
|
2431
|
+
for (const size of sizes) if (!Number.isFinite(size) || size < 0 || size > maximumSize) return false;
|
|
2432
|
+
return true;
|
|
2433
|
+
}
|
|
2434
|
+
function createIWorkZipDetectionState() {
|
|
2435
|
+
return {
|
|
2436
|
+
hasDocumentEntry: false,
|
|
2437
|
+
hasMasterSlideEntry: false,
|
|
2438
|
+
hasTablesEntry: false,
|
|
2439
|
+
hasCalculationEngineEntry: false
|
|
2440
|
+
};
|
|
2441
|
+
}
|
|
2442
|
+
function updateIWorkZipDetectionStateFromFilename(iWorkState, filename) {
|
|
2443
|
+
if (filename === "Index/Document.iwa") iWorkState.hasDocumentEntry = true;
|
|
2444
|
+
if (filename.startsWith("Index/MasterSlide")) iWorkState.hasMasterSlideEntry = true;
|
|
2445
|
+
if (filename.startsWith("Index/Tables/")) iWorkState.hasTablesEntry = true;
|
|
2446
|
+
if (filename === "Index/CalculationEngine.iwa") iWorkState.hasCalculationEngineEntry = true;
|
|
2447
|
+
}
|
|
2448
|
+
function getIWorkFileTypeFromZipEntries(iWorkState) {
|
|
2449
|
+
if (!iWorkState.hasDocumentEntry) return;
|
|
2450
|
+
if (iWorkState.hasMasterSlideEntry) return {
|
|
2451
|
+
ext: "key",
|
|
2452
|
+
mime: "application/vnd.apple.keynote"
|
|
2453
|
+
};
|
|
2454
|
+
if (iWorkState.hasTablesEntry) return {
|
|
2455
|
+
ext: "numbers",
|
|
2456
|
+
mime: "application/vnd.apple.numbers"
|
|
2457
|
+
};
|
|
2458
|
+
return {
|
|
2459
|
+
ext: "pages",
|
|
2460
|
+
mime: "application/vnd.apple.pages"
|
|
2461
|
+
};
|
|
2538
2462
|
}
|
|
2539
2463
|
function getFileTypeFromMimeType(mimeType) {
|
|
2540
2464
|
mimeType = mimeType.toLowerCase();
|
|
@@ -2639,19 +2563,495 @@ function getFileTypeFromMimeType(mimeType) {
|
|
|
2639
2563
|
ext: "3mf",
|
|
2640
2564
|
mime: "model/3mf"
|
|
2641
2565
|
};
|
|
2642
|
-
default:
|
|
2643
2566
|
}
|
|
2644
|
-
}
|
|
2645
|
-
function
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2567
|
+
}
|
|
2568
|
+
function createOpenXmlZipDetectionState() {
|
|
2569
|
+
return {
|
|
2570
|
+
hasContentTypesEntry: false,
|
|
2571
|
+
hasParsedContentTypesEntry: false,
|
|
2572
|
+
isParsingContentTypes: false,
|
|
2573
|
+
hasUnparseableContentTypes: false,
|
|
2574
|
+
hasWordDirectory: false,
|
|
2575
|
+
hasPresentationDirectory: false,
|
|
2576
|
+
hasSpreadsheetDirectory: false,
|
|
2577
|
+
hasThreeDimensionalModelEntry: false
|
|
2578
|
+
};
|
|
2579
|
+
}
|
|
2580
|
+
function updateOpenXmlZipDetectionStateFromFilename(openXmlState, filename) {
|
|
2581
|
+
if (filename.startsWith("word/")) openXmlState.hasWordDirectory = true;
|
|
2582
|
+
if (filename.startsWith("ppt/")) openXmlState.hasPresentationDirectory = true;
|
|
2583
|
+
if (filename.startsWith("xl/")) openXmlState.hasSpreadsheetDirectory = true;
|
|
2584
|
+
if (filename.startsWith("3D/") && filename.endsWith(".model")) openXmlState.hasThreeDimensionalModelEntry = true;
|
|
2585
|
+
}
|
|
2586
|
+
function getOpenXmlFileTypeFromDirectoryNames(openXmlState) {
|
|
2587
|
+
if (openXmlState.hasWordDirectory) return {
|
|
2588
|
+
ext: "docx",
|
|
2589
|
+
mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
2590
|
+
};
|
|
2591
|
+
if (openXmlState.hasPresentationDirectory) return {
|
|
2592
|
+
ext: "pptx",
|
|
2593
|
+
mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
2594
|
+
};
|
|
2595
|
+
if (openXmlState.hasSpreadsheetDirectory) return {
|
|
2596
|
+
ext: "xlsx",
|
|
2597
|
+
mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
2598
|
+
};
|
|
2599
|
+
if (openXmlState.hasThreeDimensionalModelEntry) return {
|
|
2600
|
+
ext: "3mf",
|
|
2601
|
+
mime: "model/3mf"
|
|
2602
|
+
};
|
|
2603
|
+
}
|
|
2604
|
+
function getOpenXmlFileTypeFromZipEntries(openXmlState) {
|
|
2605
|
+
if (!openXmlState.hasContentTypesEntry || openXmlState.hasUnparseableContentTypes || openXmlState.isParsingContentTypes || openXmlState.hasParsedContentTypesEntry) return;
|
|
2606
|
+
return getOpenXmlFileTypeFromDirectoryNames(openXmlState);
|
|
2607
|
+
}
|
|
2608
|
+
function getOpenXmlMimeTypeFromContentTypesXml(xmlContent) {
|
|
2609
|
+
const endPosition = xmlContent.indexOf(".main+xml\"");
|
|
2610
|
+
if (endPosition === -1) {
|
|
2611
|
+
const mimeType = "application/vnd.ms-package.3dmanufacturing-3dmodel+xml";
|
|
2612
|
+
if (xmlContent.includes(`ContentType="${mimeType}"`)) return mimeType;
|
|
2613
|
+
return;
|
|
2614
|
+
}
|
|
2615
|
+
const truncatedContent = xmlContent.slice(0, endPosition);
|
|
2616
|
+
const firstQuotePosition = truncatedContent.lastIndexOf("\"");
|
|
2617
|
+
return truncatedContent.slice(firstQuotePosition + 1);
|
|
2618
|
+
}
|
|
2619
|
+
const zipDataDescriptorSignature = 134695760;
|
|
2620
|
+
const zipDataDescriptorLengthInBytes = 16;
|
|
2621
|
+
const zipDataDescriptorOverlapLengthInBytes = 15;
|
|
2622
|
+
function findZipDataDescriptorOffset(buffer, bytesConsumed) {
|
|
2623
|
+
if (buffer.length < zipDataDescriptorLengthInBytes) return -1;
|
|
2624
|
+
const lastPossibleDescriptorOffset = buffer.length - zipDataDescriptorLengthInBytes;
|
|
2625
|
+
for (let index = 0; index <= lastPossibleDescriptorOffset; index++) if (UINT32_LE.get(buffer, index) === zipDataDescriptorSignature && UINT32_LE.get(buffer, index + 8) === bytesConsumed + index) return index;
|
|
2626
|
+
return -1;
|
|
2627
|
+
}
|
|
2628
|
+
async function readZipDataDescriptorEntryWithLimit(zipHandler, { shouldBuffer, maximumLength = maximumZipEntrySizeInBytes } = {}) {
|
|
2629
|
+
const { syncBuffer } = zipHandler;
|
|
2630
|
+
const { length: syncBufferLength } = syncBuffer;
|
|
2631
|
+
const chunks = [];
|
|
2632
|
+
let bytesConsumed = 0;
|
|
2633
|
+
for (;;) {
|
|
2634
|
+
const length = await zipHandler.tokenizer.peekBuffer(syncBuffer, { mayBeLess: true });
|
|
2635
|
+
const dataDescriptorOffset = findZipDataDescriptorOffset(syncBuffer.subarray(0, length), bytesConsumed);
|
|
2636
|
+
const retainedLength = dataDescriptorOffset >= 0 ? 0 : length === syncBufferLength ? Math.min(zipDataDescriptorOverlapLengthInBytes, length - 1) : 0;
|
|
2637
|
+
const chunkLength = dataDescriptorOffset >= 0 ? dataDescriptorOffset : length - retainedLength;
|
|
2638
|
+
if (chunkLength === 0) break;
|
|
2639
|
+
bytesConsumed += chunkLength;
|
|
2640
|
+
if (bytesConsumed > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
|
|
2641
|
+
if (shouldBuffer) {
|
|
2642
|
+
const data = new Uint8Array(chunkLength);
|
|
2643
|
+
await zipHandler.tokenizer.readBuffer(data);
|
|
2644
|
+
chunks.push(data);
|
|
2645
|
+
} else await zipHandler.tokenizer.ignore(chunkLength);
|
|
2646
|
+
if (dataDescriptorOffset >= 0) break;
|
|
2647
|
+
}
|
|
2648
|
+
if (!hasUnknownFileSize(zipHandler.tokenizer)) zipHandler.knownSizeDescriptorScannedBytes += bytesConsumed;
|
|
2649
|
+
if (!shouldBuffer) return;
|
|
2650
|
+
return mergeByteChunks(chunks, bytesConsumed);
|
|
2651
|
+
}
|
|
2652
|
+
function getRemainingZipScanBudget(zipHandler, startOffset) {
|
|
2653
|
+
if (hasUnknownFileSize(zipHandler.tokenizer)) return Math.max(0, maximumUntrustedSkipSizeInBytes - (zipHandler.tokenizer.position - startOffset));
|
|
2654
|
+
return Math.max(0, maximumZipEntrySizeInBytes - zipHandler.knownSizeDescriptorScannedBytes);
|
|
2655
|
+
}
|
|
2656
|
+
async function readZipEntryData(zipHandler, zipHeader, { shouldBuffer, maximumDescriptorLength = maximumZipEntrySizeInBytes } = {}) {
|
|
2657
|
+
if (zipHeader.dataDescriptor && zipHeader.compressedSize === 0) return readZipDataDescriptorEntryWithLimit(zipHandler, {
|
|
2658
|
+
shouldBuffer,
|
|
2659
|
+
maximumLength: maximumDescriptorLength
|
|
2660
|
+
});
|
|
2661
|
+
if (!shouldBuffer) {
|
|
2662
|
+
await safeIgnore(zipHandler.tokenizer, zipHeader.compressedSize, {
|
|
2663
|
+
maximumLength: hasUnknownFileSize(zipHandler.tokenizer) ? maximumZipEntrySizeInBytes : zipHandler.tokenizer.fileInfo.size,
|
|
2664
|
+
reason: "ZIP entry compressed data"
|
|
2665
|
+
});
|
|
2666
|
+
return;
|
|
2667
|
+
}
|
|
2668
|
+
const maximumLength = getMaximumZipBufferedReadLength(zipHandler.tokenizer);
|
|
2669
|
+
if (!Number.isFinite(zipHeader.compressedSize) || zipHeader.compressedSize < 0 || zipHeader.compressedSize > maximumLength) throw new Error(`ZIP entry compressed data exceeds ${maximumLength} bytes`);
|
|
2670
|
+
const fileData = new Uint8Array(zipHeader.compressedSize);
|
|
2671
|
+
await zipHandler.tokenizer.readBuffer(fileData);
|
|
2672
|
+
return fileData;
|
|
2673
|
+
}
|
|
2674
|
+
ZipHandler.prototype.inflate = async function(zipHeader, fileData, callback) {
|
|
2675
|
+
if (zipHeader.compressedMethod === 0) return callback(fileData);
|
|
2676
|
+
if (zipHeader.compressedMethod !== 8) throw new Error(`Unsupported ZIP compression method: ${zipHeader.compressedMethod}`);
|
|
2677
|
+
return callback(await decompressDeflateRawWithLimit(fileData, { maximumLength: maximumZipEntrySizeInBytes }));
|
|
2678
|
+
};
|
|
2679
|
+
ZipHandler.prototype.unzip = async function(fileCallback) {
|
|
2680
|
+
let stop = false;
|
|
2681
|
+
let zipEntryCount = 0;
|
|
2682
|
+
const zipScanStart = this.tokenizer.position;
|
|
2683
|
+
this.knownSizeDescriptorScannedBytes = 0;
|
|
2684
|
+
do {
|
|
2685
|
+
if (hasExceededUnknownSizeScanBudget(this.tokenizer, zipScanStart, 16777216)) throw new ParserHardLimitError(`ZIP stream probing exceeds ${maximumUntrustedSkipSizeInBytes} bytes`);
|
|
2686
|
+
const zipHeader = await this.readLocalFileHeader();
|
|
2687
|
+
if (!zipHeader) break;
|
|
2688
|
+
zipEntryCount++;
|
|
2689
|
+
if (zipEntryCount > maximumZipEntryCount) throw new Error(`ZIP entry count exceeds ${maximumZipEntryCount}`);
|
|
2690
|
+
const next = fileCallback(zipHeader);
|
|
2691
|
+
stop = Boolean(next.stop);
|
|
2692
|
+
await this.tokenizer.ignore(zipHeader.extraFieldLength);
|
|
2693
|
+
const fileData = await readZipEntryData(this, zipHeader, {
|
|
2694
|
+
shouldBuffer: Boolean(next.handler),
|
|
2695
|
+
maximumDescriptorLength: Math.min(maximumZipEntrySizeInBytes, getRemainingZipScanBudget(this, zipScanStart))
|
|
2696
|
+
});
|
|
2697
|
+
if (next.handler) await this.inflate(zipHeader, fileData, next.handler);
|
|
2698
|
+
if (zipHeader.dataDescriptor) {
|
|
2699
|
+
const dataDescriptor = new Uint8Array(zipDataDescriptorLengthInBytes);
|
|
2700
|
+
await this.tokenizer.readBuffer(dataDescriptor);
|
|
2701
|
+
if (UINT32_LE.get(dataDescriptor, 0) !== zipDataDescriptorSignature) throw new Error(`Expected data-descriptor-signature at position ${this.tokenizer.position - dataDescriptor.length}`);
|
|
2702
|
+
}
|
|
2703
|
+
if (hasExceededUnknownSizeScanBudget(this.tokenizer, zipScanStart, 16777216)) throw new ParserHardLimitError(`ZIP stream probing exceeds ${maximumUntrustedSkipSizeInBytes} bytes`);
|
|
2704
|
+
} while (!stop);
|
|
2705
|
+
};
|
|
2706
|
+
async function detectZip(tokenizer) {
|
|
2707
|
+
let fileType;
|
|
2708
|
+
const openXmlState = createOpenXmlZipDetectionState();
|
|
2709
|
+
const iWorkState = createIWorkZipDetectionState();
|
|
2710
|
+
try {
|
|
2711
|
+
await new ZipHandler(tokenizer).unzip((zipHeader) => {
|
|
2712
|
+
updateOpenXmlZipDetectionStateFromFilename(openXmlState, zipHeader.filename);
|
|
2713
|
+
updateIWorkZipDetectionStateFromFilename(iWorkState, zipHeader.filename);
|
|
2714
|
+
if (iWorkState.hasDocumentEntry && (iWorkState.hasMasterSlideEntry || iWorkState.hasTablesEntry)) {
|
|
2715
|
+
fileType = getIWorkFileTypeFromZipEntries(iWorkState);
|
|
2716
|
+
return { stop: true };
|
|
2717
|
+
}
|
|
2718
|
+
const isOpenXmlContentTypesEntry = zipHeader.filename === "[Content_Types].xml";
|
|
2719
|
+
const openXmlFileTypeFromEntries = getOpenXmlFileTypeFromZipEntries(openXmlState);
|
|
2720
|
+
if (!isOpenXmlContentTypesEntry && openXmlFileTypeFromEntries) {
|
|
2721
|
+
fileType = openXmlFileTypeFromEntries;
|
|
2722
|
+
return { stop: true };
|
|
2723
|
+
}
|
|
2724
|
+
switch (zipHeader.filename) {
|
|
2725
|
+
case "META-INF/mozilla.rsa":
|
|
2726
|
+
fileType = {
|
|
2727
|
+
ext: "xpi",
|
|
2728
|
+
mime: "application/x-xpinstall"
|
|
2729
|
+
};
|
|
2730
|
+
return { stop: true };
|
|
2731
|
+
case "META-INF/MANIFEST.MF":
|
|
2732
|
+
fileType = {
|
|
2733
|
+
ext: "jar",
|
|
2734
|
+
mime: "application/java-archive"
|
|
2735
|
+
};
|
|
2736
|
+
return { stop: true };
|
|
2737
|
+
case "mimetype":
|
|
2738
|
+
if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) return {};
|
|
2739
|
+
return {
|
|
2740
|
+
async handler(fileData) {
|
|
2741
|
+
fileType = getFileTypeFromMimeType(new TextDecoder("utf-8").decode(fileData).trim());
|
|
2742
|
+
},
|
|
2743
|
+
stop: true
|
|
2744
|
+
};
|
|
2745
|
+
case "[Content_Types].xml":
|
|
2746
|
+
openXmlState.hasContentTypesEntry = true;
|
|
2747
|
+
if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) {
|
|
2748
|
+
openXmlState.hasUnparseableContentTypes = true;
|
|
2749
|
+
return {};
|
|
2750
|
+
}
|
|
2751
|
+
openXmlState.isParsingContentTypes = true;
|
|
2752
|
+
return {
|
|
2753
|
+
async handler(fileData) {
|
|
2754
|
+
const mimeType = getOpenXmlMimeTypeFromContentTypesXml(new TextDecoder("utf-8").decode(fileData));
|
|
2755
|
+
if (mimeType) fileType = getFileTypeFromMimeType(mimeType);
|
|
2756
|
+
openXmlState.hasParsedContentTypesEntry = true;
|
|
2757
|
+
openXmlState.isParsingContentTypes = false;
|
|
2758
|
+
},
|
|
2759
|
+
stop: true
|
|
2760
|
+
};
|
|
2761
|
+
default:
|
|
2762
|
+
if (new RegExp("classes\\d*\\.dex", "v").test(zipHeader.filename)) {
|
|
2763
|
+
fileType = {
|
|
2764
|
+
ext: "apk",
|
|
2765
|
+
mime: "application/vnd.android.package-archive"
|
|
2766
|
+
};
|
|
2767
|
+
return { stop: true };
|
|
2768
|
+
}
|
|
2769
|
+
return {};
|
|
2770
|
+
}
|
|
2771
|
+
});
|
|
2772
|
+
} catch (error) {
|
|
2773
|
+
if (!isRecoverableZipError(error)) throw error;
|
|
2774
|
+
if (openXmlState.isParsingContentTypes) {
|
|
2775
|
+
openXmlState.isParsingContentTypes = false;
|
|
2776
|
+
openXmlState.hasUnparseableContentTypes = true;
|
|
2777
|
+
}
|
|
2778
|
+
if (!fileType && error instanceof EndOfStreamError && !openXmlState.hasContentTypesEntry) fileType = getOpenXmlFileTypeFromDirectoryNames(openXmlState);
|
|
2779
|
+
}
|
|
2780
|
+
const iWorkFileType = hasUnknownFileSize(tokenizer) && iWorkState.hasDocumentEntry && !iWorkState.hasMasterSlideEntry && !iWorkState.hasTablesEntry && !iWorkState.hasCalculationEngineEntry ? void 0 : getIWorkFileTypeFromZipEntries(iWorkState);
|
|
2781
|
+
return fileType ?? getOpenXmlFileTypeFromZipEntries(openXmlState) ?? iWorkFileType ?? {
|
|
2782
|
+
ext: "zip",
|
|
2783
|
+
mime: "application/zip"
|
|
2784
|
+
};
|
|
2785
|
+
}
|
|
2786
|
+
//#endregion
|
|
2787
|
+
//#region node_modules/file-type/source/detectors/ebml.js
|
|
2788
|
+
const maximumEbmlDocumentTypeSizeInBytes = 64;
|
|
2789
|
+
const maximumEbmlElementPayloadSizeInBytes = 1048576;
|
|
2790
|
+
const maximumEbmlElementCount = 256;
|
|
2791
|
+
async function detectEbml(tokenizer) {
|
|
2792
|
+
async function readField() {
|
|
2793
|
+
const msb = await tokenizer.peekNumber(UINT8);
|
|
2794
|
+
let mask = 128;
|
|
2795
|
+
let ic = 0;
|
|
2796
|
+
while ((msb & mask) === 0 && mask !== 0) {
|
|
2797
|
+
++ic;
|
|
2798
|
+
mask >>= 1;
|
|
2799
|
+
}
|
|
2800
|
+
const id = new Uint8Array(ic + 1);
|
|
2801
|
+
await safeReadBuffer(tokenizer, id, void 0, {
|
|
2802
|
+
maximumLength: id.length,
|
|
2803
|
+
reason: "EBML field"
|
|
2804
|
+
});
|
|
2805
|
+
return id;
|
|
2806
|
+
}
|
|
2807
|
+
async function readElement() {
|
|
2808
|
+
const idField = await readField();
|
|
2809
|
+
const lengthField = await readField();
|
|
2810
|
+
lengthField[0] ^= 128 >> lengthField.length - 1;
|
|
2811
|
+
const nrLength = Math.min(6, lengthField.length);
|
|
2812
|
+
const idView = new DataView(idField.buffer);
|
|
2813
|
+
const lengthView = new DataView(lengthField.buffer, lengthField.length - nrLength, nrLength);
|
|
2814
|
+
return {
|
|
2815
|
+
id: getUintBE(idView),
|
|
2816
|
+
len: getUintBE(lengthView)
|
|
2817
|
+
};
|
|
2818
|
+
}
|
|
2819
|
+
async function readChildren(children) {
|
|
2820
|
+
let ebmlElementCount = 0;
|
|
2821
|
+
while (children > 0) {
|
|
2822
|
+
ebmlElementCount++;
|
|
2823
|
+
if (ebmlElementCount > maximumEbmlElementCount) return;
|
|
2824
|
+
if (hasExceededUnknownSizeScanBudget(tokenizer, ebmlScanStart, 16777216)) return;
|
|
2825
|
+
const previousPosition = tokenizer.position;
|
|
2826
|
+
const element = await readElement();
|
|
2827
|
+
if (element.id === 17026) {
|
|
2828
|
+
if (element.len > maximumEbmlDocumentTypeSizeInBytes) return;
|
|
2829
|
+
const documentTypeLength = getSafeBound(element.len, maximumEbmlDocumentTypeSizeInBytes, "EBML DocType");
|
|
2830
|
+
return (await tokenizer.readToken(new StringType(documentTypeLength))).replaceAll(new RegExp("\\0.*$", "gv"), "");
|
|
2831
|
+
}
|
|
2832
|
+
if (hasUnknownFileSize(tokenizer) && (!Number.isFinite(element.len) || element.len < 0 || element.len > maximumEbmlElementPayloadSizeInBytes)) return;
|
|
2833
|
+
await safeIgnore(tokenizer, element.len, {
|
|
2834
|
+
maximumLength: hasUnknownFileSize(tokenizer) ? maximumEbmlElementPayloadSizeInBytes : tokenizer.fileInfo.size,
|
|
2835
|
+
reason: "EBML payload"
|
|
2836
|
+
});
|
|
2837
|
+
--children;
|
|
2838
|
+
if (tokenizer.position <= previousPosition) return;
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
const rootElement = await readElement();
|
|
2842
|
+
const ebmlScanStart = tokenizer.position;
|
|
2843
|
+
switch (await readChildren(rootElement.len)) {
|
|
2844
|
+
case "webm": return {
|
|
2845
|
+
ext: "webm",
|
|
2846
|
+
mime: "video/webm"
|
|
2847
|
+
};
|
|
2848
|
+
case "matroska": return {
|
|
2849
|
+
ext: "mkv",
|
|
2850
|
+
mime: "video/matroska"
|
|
2851
|
+
};
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
//#endregion
|
|
2855
|
+
//#region node_modules/file-type/source/detectors/png.js
|
|
2856
|
+
const maximumPngChunkCount = 512;
|
|
2857
|
+
const maximumPngStreamScanBudgetInBytes = 16777216;
|
|
2858
|
+
const maximumPngChunkSizeInBytes = 1048576;
|
|
2859
|
+
function isPngAncillaryChunk(type) {
|
|
2860
|
+
return (type.codePointAt(0) & 32) !== 0;
|
|
2861
|
+
}
|
|
2862
|
+
async function detectPng(tokenizer) {
|
|
2863
|
+
const pngFileType = {
|
|
2864
|
+
ext: "png",
|
|
2865
|
+
mime: "image/png"
|
|
2866
|
+
};
|
|
2867
|
+
const apngFileType = {
|
|
2868
|
+
ext: "apng",
|
|
2869
|
+
mime: "image/apng"
|
|
2870
|
+
};
|
|
2871
|
+
await tokenizer.ignore(8);
|
|
2872
|
+
async function readChunkHeader() {
|
|
2873
|
+
return {
|
|
2874
|
+
length: await tokenizer.readToken(INT32_BE),
|
|
2875
|
+
type: await tokenizer.readToken(new StringType(4, "latin1"))
|
|
2876
|
+
};
|
|
2877
|
+
}
|
|
2878
|
+
const isUnknownPngStream = hasUnknownFileSize(tokenizer);
|
|
2879
|
+
const pngScanStart = tokenizer.position;
|
|
2880
|
+
let pngChunkCount = 0;
|
|
2881
|
+
let hasSeenImageHeader = false;
|
|
2882
|
+
do {
|
|
2883
|
+
pngChunkCount++;
|
|
2884
|
+
if (pngChunkCount > maximumPngChunkCount) break;
|
|
2885
|
+
if (hasExceededUnknownSizeScanBudget(tokenizer, pngScanStart, maximumPngStreamScanBudgetInBytes)) break;
|
|
2886
|
+
const previousPosition = tokenizer.position;
|
|
2887
|
+
const chunk = await readChunkHeader();
|
|
2888
|
+
if (chunk.length < 0) return;
|
|
2889
|
+
if (chunk.type === "IHDR") {
|
|
2890
|
+
if (chunk.length !== 13) return;
|
|
2891
|
+
hasSeenImageHeader = true;
|
|
2892
|
+
}
|
|
2893
|
+
switch (chunk.type) {
|
|
2894
|
+
case "IDAT": return pngFileType;
|
|
2895
|
+
case "acTL": return apngFileType;
|
|
2896
|
+
default:
|
|
2897
|
+
if (!hasSeenImageHeader && chunk.type !== "CgBI") return;
|
|
2898
|
+
if (isUnknownPngStream && chunk.length > maximumPngChunkSizeInBytes) return hasSeenImageHeader && isPngAncillaryChunk(chunk.type) ? pngFileType : void 0;
|
|
2899
|
+
try {
|
|
2900
|
+
await safeIgnore(tokenizer, chunk.length + 4, {
|
|
2901
|
+
maximumLength: isUnknownPngStream ? 1048580 : tokenizer.fileInfo.size,
|
|
2902
|
+
reason: "PNG chunk payload"
|
|
2903
|
+
});
|
|
2904
|
+
} catch (error) {
|
|
2905
|
+
if (!isUnknownPngStream && (error instanceof ParserHardLimitError || error instanceof EndOfStreamError)) return pngFileType;
|
|
2906
|
+
throw error;
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
if (tokenizer.position <= previousPosition) break;
|
|
2910
|
+
} while (tokenizer.position + 8 < tokenizer.fileInfo.size);
|
|
2911
|
+
return pngFileType;
|
|
2912
|
+
}
|
|
2913
|
+
//#endregion
|
|
2914
|
+
//#region node_modules/file-type/source/detectors/asf.js
|
|
2915
|
+
const maximumAsfHeaderObjectCount = 512;
|
|
2916
|
+
const maximumAsfHeaderPayloadSizeInBytes = 1048576;
|
|
2917
|
+
async function detectAsf(tokenizer) {
|
|
2918
|
+
let isMalformedAsf = false;
|
|
2919
|
+
try {
|
|
2920
|
+
async function readHeader() {
|
|
2921
|
+
const guid = /* @__PURE__ */ new Uint8Array(16);
|
|
2922
|
+
await safeReadBuffer(tokenizer, guid, void 0, {
|
|
2923
|
+
maximumLength: guid.length,
|
|
2924
|
+
reason: "ASF header GUID"
|
|
2925
|
+
});
|
|
2926
|
+
return {
|
|
2927
|
+
id: guid,
|
|
2928
|
+
size: Number(await tokenizer.readToken(UINT64_LE))
|
|
2929
|
+
};
|
|
2930
|
+
}
|
|
2931
|
+
await safeIgnore(tokenizer, 30, {
|
|
2932
|
+
maximumLength: 30,
|
|
2933
|
+
reason: "ASF header prelude"
|
|
2934
|
+
});
|
|
2935
|
+
const isUnknownFileSize = hasUnknownFileSize(tokenizer);
|
|
2936
|
+
const asfHeaderScanStart = tokenizer.position;
|
|
2937
|
+
let asfHeaderObjectCount = 0;
|
|
2938
|
+
while (tokenizer.position + 24 < tokenizer.fileInfo.size) {
|
|
2939
|
+
asfHeaderObjectCount++;
|
|
2940
|
+
if (asfHeaderObjectCount > maximumAsfHeaderObjectCount) break;
|
|
2941
|
+
if (hasExceededUnknownSizeScanBudget(tokenizer, asfHeaderScanStart, 16777216)) break;
|
|
2942
|
+
const previousPosition = tokenizer.position;
|
|
2943
|
+
const header = await readHeader();
|
|
2944
|
+
let payload = header.size - 24;
|
|
2945
|
+
if (!Number.isFinite(payload) || payload < 0) {
|
|
2946
|
+
isMalformedAsf = true;
|
|
2947
|
+
break;
|
|
2948
|
+
}
|
|
2949
|
+
if (checkBytes(header.id, [
|
|
2950
|
+
145,
|
|
2951
|
+
7,
|
|
2952
|
+
220,
|
|
2953
|
+
183,
|
|
2954
|
+
183,
|
|
2955
|
+
169,
|
|
2956
|
+
207,
|
|
2957
|
+
17,
|
|
2958
|
+
142,
|
|
2959
|
+
230,
|
|
2960
|
+
0,
|
|
2961
|
+
192,
|
|
2962
|
+
12,
|
|
2963
|
+
32,
|
|
2964
|
+
83,
|
|
2965
|
+
101
|
|
2966
|
+
])) {
|
|
2967
|
+
const typeId = /* @__PURE__ */ new Uint8Array(16);
|
|
2968
|
+
payload -= await safeReadBuffer(tokenizer, typeId, void 0, {
|
|
2969
|
+
maximumLength: typeId.length,
|
|
2970
|
+
reason: "ASF stream type GUID"
|
|
2971
|
+
});
|
|
2972
|
+
if (checkBytes(typeId, [
|
|
2973
|
+
64,
|
|
2974
|
+
158,
|
|
2975
|
+
105,
|
|
2976
|
+
248,
|
|
2977
|
+
77,
|
|
2978
|
+
91,
|
|
2979
|
+
207,
|
|
2980
|
+
17,
|
|
2981
|
+
168,
|
|
2982
|
+
253,
|
|
2983
|
+
0,
|
|
2984
|
+
128,
|
|
2985
|
+
95,
|
|
2986
|
+
92,
|
|
2987
|
+
68,
|
|
2988
|
+
43
|
|
2989
|
+
])) return {
|
|
2990
|
+
ext: "asf",
|
|
2991
|
+
mime: "audio/x-ms-asf"
|
|
2992
|
+
};
|
|
2993
|
+
if (checkBytes(typeId, [
|
|
2994
|
+
192,
|
|
2995
|
+
239,
|
|
2996
|
+
25,
|
|
2997
|
+
188,
|
|
2998
|
+
77,
|
|
2999
|
+
91,
|
|
3000
|
+
207,
|
|
3001
|
+
17,
|
|
3002
|
+
168,
|
|
3003
|
+
253,
|
|
3004
|
+
0,
|
|
3005
|
+
128,
|
|
3006
|
+
95,
|
|
3007
|
+
92,
|
|
3008
|
+
68,
|
|
3009
|
+
43
|
|
3010
|
+
])) return {
|
|
3011
|
+
ext: "asf",
|
|
3012
|
+
mime: "video/x-ms-asf"
|
|
3013
|
+
};
|
|
3014
|
+
break;
|
|
3015
|
+
}
|
|
3016
|
+
if (isUnknownFileSize && payload > maximumAsfHeaderPayloadSizeInBytes) {
|
|
3017
|
+
isMalformedAsf = true;
|
|
3018
|
+
break;
|
|
3019
|
+
}
|
|
3020
|
+
await safeIgnore(tokenizer, payload, {
|
|
3021
|
+
maximumLength: isUnknownFileSize ? maximumAsfHeaderPayloadSizeInBytes : tokenizer.fileInfo.size,
|
|
3022
|
+
reason: "ASF header payload"
|
|
3023
|
+
});
|
|
3024
|
+
if (tokenizer.position <= previousPosition) {
|
|
3025
|
+
isMalformedAsf = true;
|
|
3026
|
+
break;
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
} catch (error) {
|
|
3030
|
+
if (error instanceof EndOfStreamError || error instanceof ParserHardLimitError) {
|
|
3031
|
+
if (hasUnknownFileSize(tokenizer)) isMalformedAsf = true;
|
|
3032
|
+
} else throw error;
|
|
3033
|
+
}
|
|
3034
|
+
if (isMalformedAsf) return;
|
|
3035
|
+
return {
|
|
3036
|
+
ext: "asf",
|
|
3037
|
+
mime: "application/vnd.ms-asf"
|
|
2649
3038
|
};
|
|
2650
|
-
for (const [index, header] of headers.entries()) if (options.mask) {
|
|
2651
|
-
if (header !== (options.mask[index] & buffer[index + options.offset])) return false;
|
|
2652
|
-
} else if (header !== buffer[index + options.offset]) return false;
|
|
2653
|
-
return true;
|
|
2654
3039
|
}
|
|
3040
|
+
//#endregion
|
|
3041
|
+
//#region node_modules/file-type/source/index.js
|
|
3042
|
+
/**
|
|
3043
|
+
Primary entry point, Node.js specific entry point is index.js
|
|
3044
|
+
*/
|
|
3045
|
+
const reasonableDetectionSizeInBytes = 4100;
|
|
3046
|
+
const maximumMpegOffsetTolerance = 4096;
|
|
3047
|
+
const maximumNestedGzipDetectionSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
3048
|
+
const maximumNestedGzipProbeDepth = 1;
|
|
3049
|
+
const unknownSizeGzipProbeTimeoutInMilliseconds = 100;
|
|
3050
|
+
const maximumId3HeaderSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
3051
|
+
const maximumTiffTagCount = 512;
|
|
3052
|
+
const maximumDetectionReentryCount = 256;
|
|
3053
|
+
const maximumTiffStreamIfdOffsetInBytes = 1048576;
|
|
3054
|
+
const maximumTiffIfdOffsetInBytes = maximumUntrustedSkipSizeInBytes;
|
|
2655
3055
|
function normalizeSampleSize(sampleSize) {
|
|
2656
3056
|
if (!Number.isFinite(sampleSize)) return reasonableDetectionSizeInBytes;
|
|
2657
3057
|
return Math.max(1, Math.trunc(sampleSize));
|
|
@@ -2664,81 +3064,65 @@ function getKnownFileSizeOrMaximum(fileSize) {
|
|
|
2664
3064
|
if (!Number.isFinite(fileSize)) return Number.MAX_SAFE_INTEGER;
|
|
2665
3065
|
return Math.max(0, fileSize);
|
|
2666
3066
|
}
|
|
2667
|
-
function
|
|
2668
|
-
|
|
2669
|
-
return !Number.isFinite(fileSize) || fileSize === Number.MAX_SAFE_INTEGER;
|
|
2670
|
-
}
|
|
2671
|
-
function hasExceededUnknownSizeScanBudget(tokenizer, startOffset, maximumBytes) {
|
|
2672
|
-
return hasUnknownFileSize(tokenizer) && tokenizer.position - startOffset > maximumBytes;
|
|
2673
|
-
}
|
|
2674
|
-
function getMaximumZipBufferedReadLength(tokenizer) {
|
|
2675
|
-
const fileSize = tokenizer.fileInfo.size;
|
|
2676
|
-
const remainingBytes = Number.isFinite(fileSize) ? Math.max(0, fileSize - tokenizer.position) : Number.MAX_SAFE_INTEGER;
|
|
2677
|
-
return Math.min(remainingBytes, maximumZipBufferedReadSizeInBytes);
|
|
2678
|
-
}
|
|
2679
|
-
function isRecoverableZipError(error) {
|
|
2680
|
-
if (error instanceof EndOfStreamError) return true;
|
|
2681
|
-
if (error instanceof ParserHardLimitError) return true;
|
|
2682
|
-
if (!(error instanceof Error)) return false;
|
|
2683
|
-
if (recoverableZipErrorMessages.has(error.message)) return true;
|
|
2684
|
-
if (recoverableZipErrorCodes.has(error.code)) return true;
|
|
2685
|
-
for (const prefix of recoverableZipErrorMessagePrefixes) if (error.message.startsWith(prefix)) return true;
|
|
2686
|
-
return false;
|
|
2687
|
-
}
|
|
2688
|
-
function canReadZipEntryForDetection(zipHeader, maximumSize = maximumZipEntrySizeInBytes) {
|
|
2689
|
-
const sizes = [zipHeader.compressedSize, zipHeader.uncompressedSize];
|
|
2690
|
-
for (const size of sizes) if (!Number.isFinite(size) || size < 0 || size > maximumSize) return false;
|
|
2691
|
-
return true;
|
|
3067
|
+
function importAtRuntime(specifier) {
|
|
3068
|
+
return import(specifier);
|
|
2692
3069
|
}
|
|
2693
|
-
function
|
|
2694
|
-
return
|
|
2695
|
-
hasContentTypesEntry: false,
|
|
2696
|
-
hasParsedContentTypesEntry: false,
|
|
2697
|
-
isParsingContentTypes: false,
|
|
2698
|
-
hasUnparseableContentTypes: false,
|
|
2699
|
-
hasWordDirectory: false,
|
|
2700
|
-
hasPresentationDirectory: false,
|
|
2701
|
-
hasSpreadsheetDirectory: false,
|
|
2702
|
-
hasThreeDimensionalModelEntry: false
|
|
2703
|
-
};
|
|
3070
|
+
function toDefaultStream(stream) {
|
|
3071
|
+
return stream.pipeThrough(new TransformStream());
|
|
2704
3072
|
}
|
|
2705
|
-
function
|
|
2706
|
-
if (
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
3073
|
+
function readWithSignal(reader, signal) {
|
|
3074
|
+
if (signal === void 0) return reader.read();
|
|
3075
|
+
signal.throwIfAborted();
|
|
3076
|
+
return Promise.race([reader.read(), new Promise((_resolve, reject) => {
|
|
3077
|
+
signal.addEventListener("abort", () => {
|
|
3078
|
+
reject(signal.reason);
|
|
3079
|
+
reader.cancel(signal.reason).catch(() => {});
|
|
3080
|
+
}, { once: true });
|
|
3081
|
+
})]);
|
|
2710
3082
|
}
|
|
2711
|
-
function
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
};
|
|
2721
|
-
if (openXmlState.hasSpreadsheetDirectory) return {
|
|
2722
|
-
ext: "xlsx",
|
|
2723
|
-
mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
2724
|
-
};
|
|
2725
|
-
if (openXmlState.hasThreeDimensionalModelEntry) return {
|
|
2726
|
-
ext: "3mf",
|
|
2727
|
-
mime: "model/3mf"
|
|
3083
|
+
function createByteLimitedReadableStream(stream, maximumBytes) {
|
|
3084
|
+
const reader = stream.getReader();
|
|
3085
|
+
let emittedBytes = 0;
|
|
3086
|
+
let sourceDone = false;
|
|
3087
|
+
let sourceCanceled = false;
|
|
3088
|
+
const cancelSource = async (reason) => {
|
|
3089
|
+
if (sourceDone || sourceCanceled) return;
|
|
3090
|
+
sourceCanceled = true;
|
|
3091
|
+
await reader.cancel(reason);
|
|
2728
3092
|
};
|
|
3093
|
+
return new ReadableStream({
|
|
3094
|
+
async pull(controller) {
|
|
3095
|
+
if (emittedBytes >= maximumBytes) {
|
|
3096
|
+
controller.close();
|
|
3097
|
+
await cancelSource();
|
|
3098
|
+
return;
|
|
3099
|
+
}
|
|
3100
|
+
const { done, value } = await reader.read();
|
|
3101
|
+
if (done || !value) {
|
|
3102
|
+
sourceDone = true;
|
|
3103
|
+
controller.close();
|
|
3104
|
+
return;
|
|
3105
|
+
}
|
|
3106
|
+
const remainingBytes = maximumBytes - emittedBytes;
|
|
3107
|
+
if (value.length > remainingBytes) {
|
|
3108
|
+
controller.enqueue(value.subarray(0, remainingBytes));
|
|
3109
|
+
emittedBytes += remainingBytes;
|
|
3110
|
+
controller.close();
|
|
3111
|
+
await cancelSource();
|
|
3112
|
+
return;
|
|
3113
|
+
}
|
|
3114
|
+
controller.enqueue(value);
|
|
3115
|
+
emittedBytes += value.length;
|
|
3116
|
+
},
|
|
3117
|
+
async cancel(reason) {
|
|
3118
|
+
await cancelSource(reason);
|
|
3119
|
+
}
|
|
3120
|
+
});
|
|
2729
3121
|
}
|
|
2730
|
-
function
|
|
2731
|
-
|
|
2732
|
-
if (endPosition === -1) {
|
|
2733
|
-
const mimeType = "application/vnd.ms-package.3dmanufacturing-3dmodel+xml";
|
|
2734
|
-
if (xmlContent.includes(`ContentType="${mimeType}"`)) return mimeType;
|
|
2735
|
-
return;
|
|
2736
|
-
}
|
|
2737
|
-
const truncatedContent = xmlContent.slice(0, endPosition);
|
|
2738
|
-
const firstQuotePosition = truncatedContent.lastIndexOf("\"");
|
|
2739
|
-
return truncatedContent.slice(firstQuotePosition + 1);
|
|
3122
|
+
async function fileTypeFromBlob(blob, options) {
|
|
3123
|
+
return new FileTypeParser(options).fromBlob(blob);
|
|
2740
3124
|
}
|
|
2741
|
-
var FileTypeParser = class {
|
|
3125
|
+
var FileTypeParser = class FileTypeParser {
|
|
2742
3126
|
constructor(options) {
|
|
2743
3127
|
const normalizedMpegOffsetTolerance = normalizeMpegOffsetTolerance(options?.mpegOffsetTolerance);
|
|
2744
3128
|
this.options = {
|
|
@@ -2762,7 +3146,10 @@ var FileTypeParser = class {
|
|
|
2762
3146
|
getTokenizerOptions() {
|
|
2763
3147
|
return { ...this.tokenizerOptions };
|
|
2764
3148
|
}
|
|
2765
|
-
|
|
3149
|
+
createTokenizerFromWebStream(stream) {
|
|
3150
|
+
return fromWebStream(toDefaultStream(stream), this.getTokenizerOptions());
|
|
3151
|
+
}
|
|
3152
|
+
async parseTokenizer(tokenizer, detectionReentryCount = 0) {
|
|
2766
3153
|
this.detectionReentryCount = detectionReentryCount;
|
|
2767
3154
|
const initialPosition = tokenizer.position;
|
|
2768
3155
|
for (const detector of this.detectors) {
|
|
@@ -2778,6 +3165,13 @@ var FileTypeParser = class {
|
|
|
2778
3165
|
if (initialPosition !== tokenizer.position) return;
|
|
2779
3166
|
}
|
|
2780
3167
|
}
|
|
3168
|
+
async fromTokenizer(tokenizer) {
|
|
3169
|
+
try {
|
|
3170
|
+
return await this.parseTokenizer(tokenizer);
|
|
3171
|
+
} finally {
|
|
3172
|
+
await tokenizer.close();
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
2781
3175
|
async fromBuffer(input) {
|
|
2782
3176
|
if (!(input instanceof Uint8Array || input instanceof ArrayBuffer)) throw new TypeError(`Expected the \`input\` argument to be of type \`Uint8Array\` or \`ArrayBuffer\`, got \`${typeof input}\``);
|
|
2783
3177
|
const buffer = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
@@ -2785,42 +3179,78 @@ var FileTypeParser = class {
|
|
|
2785
3179
|
return this.fromTokenizer(fromBuffer(buffer, this.getTokenizerOptions()));
|
|
2786
3180
|
}
|
|
2787
3181
|
async fromBlob(blob) {
|
|
3182
|
+
this.options.signal?.throwIfAborted();
|
|
2788
3183
|
const tokenizer = fromBlob(blob, this.getTokenizerOptions());
|
|
2789
|
-
|
|
2790
|
-
return await this.fromTokenizer(tokenizer);
|
|
2791
|
-
} finally {
|
|
2792
|
-
await tokenizer.close();
|
|
2793
|
-
}
|
|
3184
|
+
return this.fromTokenizer(tokenizer);
|
|
2794
3185
|
}
|
|
2795
3186
|
async fromStream(stream) {
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
3187
|
+
this.options.signal?.throwIfAborted();
|
|
3188
|
+
const tokenizer = this.createTokenizerFromWebStream(stream);
|
|
3189
|
+
return this.fromTokenizer(tokenizer);
|
|
3190
|
+
}
|
|
3191
|
+
async fromFile(path) {
|
|
3192
|
+
this.options.signal?.throwIfAborted();
|
|
3193
|
+
const [{ default: fsPromises }, { FileTokenizer }] = await Promise.all([importAtRuntime("node:fs/promises"), importAtRuntime("strtok3")]);
|
|
3194
|
+
const fileHandle = await fsPromises.open(path, fsPromises.constants.O_RDONLY | fsPromises.constants.O_NONBLOCK);
|
|
3195
|
+
const fileStat = await fileHandle.stat();
|
|
3196
|
+
if (!fileStat.isFile()) {
|
|
3197
|
+
await fileHandle.close();
|
|
3198
|
+
return;
|
|
2801
3199
|
}
|
|
3200
|
+
const tokenizer = new FileTokenizer(fileHandle, {
|
|
3201
|
+
...this.getTokenizerOptions(),
|
|
3202
|
+
fileInfo: {
|
|
3203
|
+
path,
|
|
3204
|
+
size: fileStat.size
|
|
3205
|
+
}
|
|
3206
|
+
});
|
|
3207
|
+
return this.fromTokenizer(tokenizer);
|
|
2802
3208
|
}
|
|
2803
3209
|
async toDetectionStream(stream, options) {
|
|
3210
|
+
this.options.signal?.throwIfAborted();
|
|
2804
3211
|
const sampleSize = normalizeSampleSize(options?.sampleSize ?? 4100);
|
|
2805
3212
|
let detectedFileType;
|
|
2806
|
-
let
|
|
2807
|
-
const reader = stream.getReader(
|
|
3213
|
+
let streamEnded = false;
|
|
3214
|
+
const reader = stream.getReader();
|
|
3215
|
+
const chunks = [];
|
|
3216
|
+
let totalSize = 0;
|
|
2808
3217
|
try {
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
3218
|
+
while (totalSize < sampleSize) {
|
|
3219
|
+
const { value, done } = await readWithSignal(reader, this.options.signal);
|
|
3220
|
+
if (done || !value) {
|
|
3221
|
+
streamEnded = true;
|
|
3222
|
+
break;
|
|
3223
|
+
}
|
|
3224
|
+
chunks.push(value);
|
|
3225
|
+
totalSize += value.length;
|
|
3226
|
+
}
|
|
3227
|
+
if (!streamEnded && totalSize === sampleSize) {
|
|
3228
|
+
const { value, done } = await readWithSignal(reader, this.options.signal);
|
|
3229
|
+
if (done || !value) streamEnded = true;
|
|
3230
|
+
else {
|
|
3231
|
+
chunks.push(value);
|
|
3232
|
+
totalSize += value.length;
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
} finally {
|
|
3236
|
+
reader.releaseLock();
|
|
3237
|
+
}
|
|
3238
|
+
if (totalSize > 0) {
|
|
3239
|
+
const sample = chunks.length === 1 ? chunks[0] : concatUint8Arrays(chunks);
|
|
3240
|
+
try {
|
|
3241
|
+
detectedFileType = await this.fromBuffer(sample.subarray(0, sampleSize));
|
|
2813
3242
|
} catch (error) {
|
|
2814
3243
|
if (!(error instanceof EndOfStreamError)) throw error;
|
|
2815
3244
|
detectedFileType = void 0;
|
|
2816
3245
|
}
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
3246
|
+
if (!streamEnded && detectedFileType?.ext === "pages") detectedFileType = {
|
|
3247
|
+
ext: "zip",
|
|
3248
|
+
mime: "application/zip"
|
|
3249
|
+
};
|
|
2820
3250
|
}
|
|
2821
3251
|
const transformStream = new TransformStream({
|
|
2822
|
-
|
|
2823
|
-
controller.enqueue(
|
|
3252
|
+
start(controller) {
|
|
3253
|
+
for (const chunk of chunks) controller.enqueue(chunk);
|
|
2824
3254
|
},
|
|
2825
3255
|
transform(chunk, controller) {
|
|
2826
3256
|
controller.enqueue(chunk);
|
|
@@ -2830,8 +3260,48 @@ var FileTypeParser = class {
|
|
|
2830
3260
|
newStream.fileType = detectedFileType;
|
|
2831
3261
|
return newStream;
|
|
2832
3262
|
}
|
|
3263
|
+
async detectGzip(tokenizer) {
|
|
3264
|
+
if (this.gzipProbeDepth >= maximumNestedGzipProbeDepth) return {
|
|
3265
|
+
ext: "gz",
|
|
3266
|
+
mime: "application/gzip"
|
|
3267
|
+
};
|
|
3268
|
+
const limitedInflatedStream = createByteLimitedReadableStream(new GzipHandler(tokenizer).inflate(), maximumNestedGzipDetectionSizeInBytes);
|
|
3269
|
+
const hasUnknownSize = hasUnknownFileSize(tokenizer);
|
|
3270
|
+
let timeout;
|
|
3271
|
+
let probeSignal;
|
|
3272
|
+
let probeParser;
|
|
3273
|
+
let compressedFileType;
|
|
3274
|
+
if (hasUnknownSize) {
|
|
3275
|
+
const timeoutController = new AbortController();
|
|
3276
|
+
timeout = setTimeout(() => {
|
|
3277
|
+
timeoutController.abort(new DOMException(`Operation timed out after ${unknownSizeGzipProbeTimeoutInMilliseconds} ms`, "TimeoutError"));
|
|
3278
|
+
}, unknownSizeGzipProbeTimeoutInMilliseconds);
|
|
3279
|
+
probeSignal = this.options.signal === void 0 ? timeoutController.signal : AbortSignal.any([this.options.signal, timeoutController.signal]);
|
|
3280
|
+
probeParser = new FileTypeParser({
|
|
3281
|
+
...this.options,
|
|
3282
|
+
signal: probeSignal
|
|
3283
|
+
});
|
|
3284
|
+
probeParser.gzipProbeDepth = this.gzipProbeDepth + 1;
|
|
3285
|
+
} else this.gzipProbeDepth++;
|
|
3286
|
+
try {
|
|
3287
|
+
compressedFileType = await (probeParser ?? this).fromStream(limitedInflatedStream);
|
|
3288
|
+
} catch (error) {
|
|
3289
|
+
if (error?.name === "AbortError" && probeSignal?.reason?.name !== "TimeoutError") throw error;
|
|
3290
|
+
} finally {
|
|
3291
|
+
clearTimeout(timeout);
|
|
3292
|
+
if (!hasUnknownSize) this.gzipProbeDepth--;
|
|
3293
|
+
}
|
|
3294
|
+
if (compressedFileType?.ext === "tar") return {
|
|
3295
|
+
ext: "tar.gz",
|
|
3296
|
+
mime: "application/gzip"
|
|
3297
|
+
};
|
|
3298
|
+
return {
|
|
3299
|
+
ext: "gz",
|
|
3300
|
+
mime: "application/gzip"
|
|
3301
|
+
};
|
|
3302
|
+
}
|
|
2833
3303
|
check(header, options) {
|
|
2834
|
-
return
|
|
3304
|
+
return checkBytes(this.buffer, header, options);
|
|
2835
3305
|
}
|
|
2836
3306
|
checkString(header, options) {
|
|
2837
3307
|
return this.check(stringToBytes(header, options?.encoding), options);
|
|
@@ -2840,6 +3310,17 @@ var FileTypeParser = class {
|
|
|
2840
3310
|
this.buffer = new Uint8Array(reasonableDetectionSizeInBytes);
|
|
2841
3311
|
if (tokenizer.fileInfo.size === void 0) tokenizer.fileInfo.size = Number.MAX_SAFE_INTEGER;
|
|
2842
3312
|
this.tokenizer = tokenizer;
|
|
3313
|
+
if (hasUnknownFileSize(tokenizer)) {
|
|
3314
|
+
await tokenizer.peekBuffer(this.buffer, {
|
|
3315
|
+
length: 3,
|
|
3316
|
+
mayBeLess: true
|
|
3317
|
+
});
|
|
3318
|
+
if (this.check([
|
|
3319
|
+
31,
|
|
3320
|
+
139,
|
|
3321
|
+
8
|
|
3322
|
+
])) return this.detectGzip(tokenizer);
|
|
3323
|
+
}
|
|
2843
3324
|
await tokenizer.peekBuffer(this.buffer, {
|
|
2844
3325
|
length: 32,
|
|
2845
3326
|
mayBeLess: true
|
|
@@ -2916,30 +3397,7 @@ var FileTypeParser = class {
|
|
|
2916
3397
|
31,
|
|
2917
3398
|
139,
|
|
2918
3399
|
8
|
|
2919
|
-
]))
|
|
2920
|
-
if (this.gzipProbeDepth >= maximumNestedGzipProbeDepth) return {
|
|
2921
|
-
ext: "gz",
|
|
2922
|
-
mime: "application/gzip"
|
|
2923
|
-
};
|
|
2924
|
-
const limitedInflatedStream = createByteLimitedReadableStream(new GzipHandler(tokenizer).inflate(), maximumNestedGzipDetectionSizeInBytes);
|
|
2925
|
-
let compressedFileType;
|
|
2926
|
-
try {
|
|
2927
|
-
this.gzipProbeDepth++;
|
|
2928
|
-
compressedFileType = await this.fromStream(limitedInflatedStream);
|
|
2929
|
-
} catch (error) {
|
|
2930
|
-
if (error?.name === "AbortError") throw error;
|
|
2931
|
-
} finally {
|
|
2932
|
-
this.gzipProbeDepth--;
|
|
2933
|
-
}
|
|
2934
|
-
if (compressedFileType?.ext === "tar") return {
|
|
2935
|
-
ext: "tar.gz",
|
|
2936
|
-
mime: "application/gzip"
|
|
2937
|
-
};
|
|
2938
|
-
return {
|
|
2939
|
-
ext: "gz",
|
|
2940
|
-
mime: "application/gzip"
|
|
2941
|
-
};
|
|
2942
|
-
}
|
|
3400
|
+
])) return this.detectGzip(tokenizer);
|
|
2943
3401
|
if (this.check([
|
|
2944
3402
|
66,
|
|
2945
3403
|
90,
|
|
@@ -2955,7 +3413,7 @@ var FileTypeParser = class {
|
|
|
2955
3413
|
});
|
|
2956
3414
|
const id3HeaderLength = await tokenizer.readToken(uint32SyncSafeToken);
|
|
2957
3415
|
const isUnknownFileSize = hasUnknownFileSize(tokenizer);
|
|
2958
|
-
if (!Number.isFinite(id3HeaderLength) || id3HeaderLength < 0 || isUnknownFileSize && id3HeaderLength > maximumId3HeaderSizeInBytes) return;
|
|
3416
|
+
if (!Number.isFinite(id3HeaderLength) || id3HeaderLength < 0 || isUnknownFileSize && (id3HeaderLength > maximumId3HeaderSizeInBytes || tokenizer.position + id3HeaderLength > maximumId3HeaderSizeInBytes)) return;
|
|
2959
3417
|
if (tokenizer.position + id3HeaderLength > tokenizer.fileInfo.size) {
|
|
2960
3418
|
if (isUnknownFileSize) return;
|
|
2961
3419
|
return {
|
|
@@ -2974,7 +3432,7 @@ var FileTypeParser = class {
|
|
|
2974
3432
|
}
|
|
2975
3433
|
if (this.detectionReentryCount >= maximumDetectionReentryCount) return;
|
|
2976
3434
|
this.detectionReentryCount++;
|
|
2977
|
-
return this.
|
|
3435
|
+
return this.parseTokenizer(tokenizer, this.detectionReentryCount);
|
|
2978
3436
|
}
|
|
2979
3437
|
if (this.checkString("MP+")) return {
|
|
2980
3438
|
ext: "mpc",
|
|
@@ -3032,83 +3490,12 @@ var FileTypeParser = class {
|
|
|
3032
3490
|
75,
|
|
3033
3491
|
3,
|
|
3034
3492
|
4
|
|
3035
|
-
]))
|
|
3036
|
-
let fileType;
|
|
3037
|
-
const openXmlState = createOpenXmlZipDetectionState();
|
|
3038
|
-
try {
|
|
3039
|
-
await new ZipHandler(tokenizer).unzip((zipHeader) => {
|
|
3040
|
-
updateOpenXmlZipDetectionStateFromFilename(openXmlState, zipHeader.filename);
|
|
3041
|
-
const isOpenXmlContentTypesEntry = zipHeader.filename === "[Content_Types].xml";
|
|
3042
|
-
const openXmlFileTypeFromEntries = getOpenXmlFileTypeFromZipEntries(openXmlState);
|
|
3043
|
-
if (!isOpenXmlContentTypesEntry && openXmlFileTypeFromEntries) {
|
|
3044
|
-
fileType = openXmlFileTypeFromEntries;
|
|
3045
|
-
return { stop: true };
|
|
3046
|
-
}
|
|
3047
|
-
switch (zipHeader.filename) {
|
|
3048
|
-
case "META-INF/mozilla.rsa":
|
|
3049
|
-
fileType = {
|
|
3050
|
-
ext: "xpi",
|
|
3051
|
-
mime: "application/x-xpinstall"
|
|
3052
|
-
};
|
|
3053
|
-
return { stop: true };
|
|
3054
|
-
case "META-INF/MANIFEST.MF":
|
|
3055
|
-
fileType = {
|
|
3056
|
-
ext: "jar",
|
|
3057
|
-
mime: "application/java-archive"
|
|
3058
|
-
};
|
|
3059
|
-
return { stop: true };
|
|
3060
|
-
case "mimetype":
|
|
3061
|
-
if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) return {};
|
|
3062
|
-
return {
|
|
3063
|
-
async handler(fileData) {
|
|
3064
|
-
fileType = getFileTypeFromMimeType(new TextDecoder("utf-8").decode(fileData).trim());
|
|
3065
|
-
},
|
|
3066
|
-
stop: true
|
|
3067
|
-
};
|
|
3068
|
-
case "[Content_Types].xml":
|
|
3069
|
-
openXmlState.hasContentTypesEntry = true;
|
|
3070
|
-
if (!canReadZipEntryForDetection(zipHeader, maximumZipTextEntrySizeInBytes)) {
|
|
3071
|
-
openXmlState.hasUnparseableContentTypes = true;
|
|
3072
|
-
return {};
|
|
3073
|
-
}
|
|
3074
|
-
openXmlState.isParsingContentTypes = true;
|
|
3075
|
-
return {
|
|
3076
|
-
async handler(fileData) {
|
|
3077
|
-
const mimeType = getOpenXmlMimeTypeFromContentTypesXml(new TextDecoder("utf-8").decode(fileData));
|
|
3078
|
-
if (mimeType) fileType = getFileTypeFromMimeType(mimeType);
|
|
3079
|
-
openXmlState.hasParsedContentTypesEntry = true;
|
|
3080
|
-
openXmlState.isParsingContentTypes = false;
|
|
3081
|
-
},
|
|
3082
|
-
stop: true
|
|
3083
|
-
};
|
|
3084
|
-
default:
|
|
3085
|
-
if (/classes\d*\.dex/.test(zipHeader.filename)) {
|
|
3086
|
-
fileType = {
|
|
3087
|
-
ext: "apk",
|
|
3088
|
-
mime: "application/vnd.android.package-archive"
|
|
3089
|
-
};
|
|
3090
|
-
return { stop: true };
|
|
3091
|
-
}
|
|
3092
|
-
return {};
|
|
3093
|
-
}
|
|
3094
|
-
});
|
|
3095
|
-
} catch (error) {
|
|
3096
|
-
if (!isRecoverableZipError(error)) throw error;
|
|
3097
|
-
if (openXmlState.isParsingContentTypes) {
|
|
3098
|
-
openXmlState.isParsingContentTypes = false;
|
|
3099
|
-
openXmlState.hasUnparseableContentTypes = true;
|
|
3100
|
-
}
|
|
3101
|
-
}
|
|
3102
|
-
return fileType ?? getOpenXmlFileTypeFromZipEntries(openXmlState) ?? {
|
|
3103
|
-
ext: "zip",
|
|
3104
|
-
mime: "application/zip"
|
|
3105
|
-
};
|
|
3106
|
-
}
|
|
3493
|
+
])) return detectZip(tokenizer);
|
|
3107
3494
|
if (this.checkString("OggS")) {
|
|
3108
3495
|
await tokenizer.ignore(28);
|
|
3109
|
-
const type = new Uint8Array(8);
|
|
3496
|
+
const type = /* @__PURE__ */ new Uint8Array(8);
|
|
3110
3497
|
await tokenizer.readBuffer(type);
|
|
3111
|
-
if (
|
|
3498
|
+
if (checkBytes(type, [
|
|
3112
3499
|
79,
|
|
3113
3500
|
112,
|
|
3114
3501
|
117,
|
|
@@ -3121,7 +3508,7 @@ var FileTypeParser = class {
|
|
|
3121
3508
|
ext: "opus",
|
|
3122
3509
|
mime: "audio/ogg; codecs=opus"
|
|
3123
3510
|
};
|
|
3124
|
-
if (
|
|
3511
|
+
if (checkBytes(type, [
|
|
3125
3512
|
128,
|
|
3126
3513
|
116,
|
|
3127
3514
|
104,
|
|
@@ -3133,7 +3520,7 @@ var FileTypeParser = class {
|
|
|
3133
3520
|
ext: "ogv",
|
|
3134
3521
|
mime: "video/ogg"
|
|
3135
3522
|
};
|
|
3136
|
-
if (
|
|
3523
|
+
if (checkBytes(type, [
|
|
3137
3524
|
1,
|
|
3138
3525
|
118,
|
|
3139
3526
|
105,
|
|
@@ -3145,7 +3532,7 @@ var FileTypeParser = class {
|
|
|
3145
3532
|
ext: "ogm",
|
|
3146
3533
|
mime: "video/ogg"
|
|
3147
3534
|
};
|
|
3148
|
-
if (
|
|
3535
|
+
if (checkBytes(type, [
|
|
3149
3536
|
127,
|
|
3150
3537
|
70,
|
|
3151
3538
|
76,
|
|
@@ -3155,7 +3542,7 @@ var FileTypeParser = class {
|
|
|
3155
3542
|
ext: "oga",
|
|
3156
3543
|
mime: "audio/ogg"
|
|
3157
3544
|
};
|
|
3158
|
-
if (
|
|
3545
|
+
if (checkBytes(type, [
|
|
3159
3546
|
83,
|
|
3160
3547
|
112,
|
|
3161
3548
|
101,
|
|
@@ -3167,7 +3554,7 @@ var FileTypeParser = class {
|
|
|
3167
3554
|
ext: "spx",
|
|
3168
3555
|
mime: "audio/ogg"
|
|
3169
3556
|
};
|
|
3170
|
-
if (
|
|
3557
|
+
if (checkBytes(type, [
|
|
3171
3558
|
1,
|
|
3172
3559
|
118,
|
|
3173
3560
|
111,
|
|
@@ -3230,7 +3617,7 @@ var FileTypeParser = class {
|
|
|
3230
3617
|
};
|
|
3231
3618
|
if (this.checkString("LZIP")) return {
|
|
3232
3619
|
ext: "lz",
|
|
3233
|
-
mime: "application/
|
|
3620
|
+
mime: "application/lzip"
|
|
3234
3621
|
};
|
|
3235
3622
|
if (this.checkString("fLaC")) return {
|
|
3236
3623
|
ext: "flac",
|
|
@@ -3279,67 +3666,7 @@ var FileTypeParser = class {
|
|
|
3279
3666
|
69,
|
|
3280
3667
|
223,
|
|
3281
3668
|
163
|
|
3282
|
-
]))
|
|
3283
|
-
async function readField() {
|
|
3284
|
-
const msb = await tokenizer.peekNumber(UINT8);
|
|
3285
|
-
let mask = 128;
|
|
3286
|
-
let ic = 0;
|
|
3287
|
-
while ((msb & mask) === 0 && mask !== 0) {
|
|
3288
|
-
++ic;
|
|
3289
|
-
mask >>= 1;
|
|
3290
|
-
}
|
|
3291
|
-
const id = new Uint8Array(ic + 1);
|
|
3292
|
-
await safeReadBuffer(tokenizer, id, void 0, {
|
|
3293
|
-
maximumLength: id.length,
|
|
3294
|
-
reason: "EBML field"
|
|
3295
|
-
});
|
|
3296
|
-
return id;
|
|
3297
|
-
}
|
|
3298
|
-
async function readElement() {
|
|
3299
|
-
const idField = await readField();
|
|
3300
|
-
const lengthField = await readField();
|
|
3301
|
-
lengthField[0] ^= 128 >> lengthField.length - 1;
|
|
3302
|
-
const nrLength = Math.min(6, lengthField.length);
|
|
3303
|
-
const idView = new DataView(idField.buffer);
|
|
3304
|
-
const lengthView = new DataView(lengthField.buffer, lengthField.length - nrLength, nrLength);
|
|
3305
|
-
return {
|
|
3306
|
-
id: getUintBE(idView),
|
|
3307
|
-
len: getUintBE(lengthView)
|
|
3308
|
-
};
|
|
3309
|
-
}
|
|
3310
|
-
async function readChildren(children) {
|
|
3311
|
-
let ebmlElementCount = 0;
|
|
3312
|
-
while (children > 0) {
|
|
3313
|
-
ebmlElementCount++;
|
|
3314
|
-
if (ebmlElementCount > maximumEbmlElementCount) return;
|
|
3315
|
-
const previousPosition = tokenizer.position;
|
|
3316
|
-
const element = await readElement();
|
|
3317
|
-
if (element.id === 17026) {
|
|
3318
|
-
if (element.len > maximumEbmlDocumentTypeSizeInBytes) return;
|
|
3319
|
-
const documentTypeLength = getSafeBound(element.len, maximumEbmlDocumentTypeSizeInBytes, "EBML DocType");
|
|
3320
|
-
return (await tokenizer.readToken(new StringType(documentTypeLength))).replaceAll(/\00.*$/g, "");
|
|
3321
|
-
}
|
|
3322
|
-
if (hasUnknownFileSize(tokenizer) && (!Number.isFinite(element.len) || element.len < 0 || element.len > maximumEbmlElementPayloadSizeInBytes)) return;
|
|
3323
|
-
await safeIgnore(tokenizer, element.len, {
|
|
3324
|
-
maximumLength: hasUnknownFileSize(tokenizer) ? maximumEbmlElementPayloadSizeInBytes : tokenizer.fileInfo.size,
|
|
3325
|
-
reason: "EBML payload"
|
|
3326
|
-
});
|
|
3327
|
-
--children;
|
|
3328
|
-
if (tokenizer.position <= previousPosition) return;
|
|
3329
|
-
}
|
|
3330
|
-
}
|
|
3331
|
-
switch (await readChildren((await readElement()).len)) {
|
|
3332
|
-
case "webm": return {
|
|
3333
|
-
ext: "webm",
|
|
3334
|
-
mime: "video/webm"
|
|
3335
|
-
};
|
|
3336
|
-
case "matroska": return {
|
|
3337
|
-
ext: "mkv",
|
|
3338
|
-
mime: "video/matroska"
|
|
3339
|
-
};
|
|
3340
|
-
default: return;
|
|
3341
|
-
}
|
|
3342
|
-
}
|
|
3669
|
+
])) return detectEbml(tokenizer);
|
|
3343
3670
|
if (this.checkString("SQLi")) return {
|
|
3344
3671
|
ext: "sqlite",
|
|
3345
3672
|
mime: "application/x-sqlite3"
|
|
@@ -3469,7 +3796,7 @@ var FileTypeParser = class {
|
|
|
3469
3796
|
ext: "amr",
|
|
3470
3797
|
mime: "audio/amr"
|
|
3471
3798
|
};
|
|
3472
|
-
if (this.checkString(
|
|
3799
|
+
if (this.checkString(String.raw`{\rtf`)) return {
|
|
3473
3800
|
ext: "rtf",
|
|
3474
3801
|
mime: "application/rtf"
|
|
3475
3802
|
};
|
|
@@ -3538,7 +3865,7 @@ var FileTypeParser = class {
|
|
|
3538
3865
|
};
|
|
3539
3866
|
if (this.checkString("DRACO")) return {
|
|
3540
3867
|
ext: "drc",
|
|
3541
|
-
mime: "application/
|
|
3868
|
+
mime: "application/x-ft-draco"
|
|
3542
3869
|
};
|
|
3543
3870
|
if (this.check([
|
|
3544
3871
|
253,
|
|
@@ -3583,7 +3910,7 @@ var FileTypeParser = class {
|
|
|
3583
3910
|
};
|
|
3584
3911
|
if (this.checkString("AC")) {
|
|
3585
3912
|
const version = new StringType(4, "latin1").get(this.buffer, 2);
|
|
3586
|
-
if (
|
|
3913
|
+
if (new RegExp("^\\d+$", "v").test(version) && version >= 1e3 && version <= 1050) return {
|
|
3587
3914
|
ext: "dwg",
|
|
3588
3915
|
mime: "image/vnd.dwg"
|
|
3589
3916
|
};
|
|
@@ -3626,51 +3953,7 @@ var FileTypeParser = class {
|
|
|
3626
3953
|
10,
|
|
3627
3954
|
26,
|
|
3628
3955
|
10
|
|
3629
|
-
]))
|
|
3630
|
-
const pngFileType = {
|
|
3631
|
-
ext: "png",
|
|
3632
|
-
mime: "image/png"
|
|
3633
|
-
};
|
|
3634
|
-
const apngFileType = {
|
|
3635
|
-
ext: "apng",
|
|
3636
|
-
mime: "image/apng"
|
|
3637
|
-
};
|
|
3638
|
-
await tokenizer.ignore(8);
|
|
3639
|
-
async function readChunkHeader() {
|
|
3640
|
-
return {
|
|
3641
|
-
length: await tokenizer.readToken(INT32_BE),
|
|
3642
|
-
type: await tokenizer.readToken(new StringType(4, "latin1"))
|
|
3643
|
-
};
|
|
3644
|
-
}
|
|
3645
|
-
const isUnknownPngStream = hasUnknownFileSize(tokenizer);
|
|
3646
|
-
const pngScanStart = tokenizer.position;
|
|
3647
|
-
let pngChunkCount = 0;
|
|
3648
|
-
do {
|
|
3649
|
-
pngChunkCount++;
|
|
3650
|
-
if (pngChunkCount > maximumPngChunkCount) break;
|
|
3651
|
-
if (hasExceededUnknownSizeScanBudget(tokenizer, pngScanStart, maximumPngChunkSizeInBytes)) break;
|
|
3652
|
-
const previousPosition = tokenizer.position;
|
|
3653
|
-
const chunk = await readChunkHeader();
|
|
3654
|
-
if (chunk.length < 0) return;
|
|
3655
|
-
switch (chunk.type) {
|
|
3656
|
-
case "IDAT": return pngFileType;
|
|
3657
|
-
case "acTL": return apngFileType;
|
|
3658
|
-
default:
|
|
3659
|
-
if (isUnknownPngStream && chunk.length > maximumPngChunkSizeInBytes) return;
|
|
3660
|
-
try {
|
|
3661
|
-
await safeIgnore(tokenizer, chunk.length + 4, {
|
|
3662
|
-
maximumLength: isUnknownPngStream ? 16777220 : tokenizer.fileInfo.size,
|
|
3663
|
-
reason: "PNG chunk payload"
|
|
3664
|
-
});
|
|
3665
|
-
} catch (error) {
|
|
3666
|
-
if (!isUnknownPngStream && (error instanceof ParserHardLimitError || error instanceof EndOfStreamError)) return pngFileType;
|
|
3667
|
-
throw error;
|
|
3668
|
-
}
|
|
3669
|
-
}
|
|
3670
|
-
if (tokenizer.position <= previousPosition) break;
|
|
3671
|
-
} while (tokenizer.position + 8 < tokenizer.fileInfo.size);
|
|
3672
|
-
return pngFileType;
|
|
3673
|
-
}
|
|
3956
|
+
])) return detectPng(tokenizer);
|
|
3674
3957
|
if (this.check([
|
|
3675
3958
|
65,
|
|
3676
3959
|
82,
|
|
@@ -3893,125 +4176,7 @@ var FileTypeParser = class {
|
|
|
3893
4176
|
17,
|
|
3894
4177
|
166,
|
|
3895
4178
|
217
|
|
3896
|
-
]))
|
|
3897
|
-
let isMalformedAsf = false;
|
|
3898
|
-
try {
|
|
3899
|
-
async function readHeader() {
|
|
3900
|
-
const guid = new Uint8Array(16);
|
|
3901
|
-
await safeReadBuffer(tokenizer, guid, void 0, {
|
|
3902
|
-
maximumLength: guid.length,
|
|
3903
|
-
reason: "ASF header GUID"
|
|
3904
|
-
});
|
|
3905
|
-
return {
|
|
3906
|
-
id: guid,
|
|
3907
|
-
size: Number(await tokenizer.readToken(UINT64_LE))
|
|
3908
|
-
};
|
|
3909
|
-
}
|
|
3910
|
-
await safeIgnore(tokenizer, 30, {
|
|
3911
|
-
maximumLength: 30,
|
|
3912
|
-
reason: "ASF header prelude"
|
|
3913
|
-
});
|
|
3914
|
-
const isUnknownFileSize = hasUnknownFileSize(tokenizer);
|
|
3915
|
-
const asfHeaderScanStart = tokenizer.position;
|
|
3916
|
-
let asfHeaderObjectCount = 0;
|
|
3917
|
-
while (tokenizer.position + 24 < tokenizer.fileInfo.size) {
|
|
3918
|
-
asfHeaderObjectCount++;
|
|
3919
|
-
if (asfHeaderObjectCount > maximumAsfHeaderObjectCount) break;
|
|
3920
|
-
if (hasExceededUnknownSizeScanBudget(tokenizer, asfHeaderScanStart, maximumUntrustedSkipSizeInBytes)) break;
|
|
3921
|
-
const previousPosition = tokenizer.position;
|
|
3922
|
-
const header = await readHeader();
|
|
3923
|
-
let payload = header.size - 24;
|
|
3924
|
-
if (!Number.isFinite(payload) || payload < 0) {
|
|
3925
|
-
isMalformedAsf = true;
|
|
3926
|
-
break;
|
|
3927
|
-
}
|
|
3928
|
-
if (_check(header.id, [
|
|
3929
|
-
145,
|
|
3930
|
-
7,
|
|
3931
|
-
220,
|
|
3932
|
-
183,
|
|
3933
|
-
183,
|
|
3934
|
-
169,
|
|
3935
|
-
207,
|
|
3936
|
-
17,
|
|
3937
|
-
142,
|
|
3938
|
-
230,
|
|
3939
|
-
0,
|
|
3940
|
-
192,
|
|
3941
|
-
12,
|
|
3942
|
-
32,
|
|
3943
|
-
83,
|
|
3944
|
-
101
|
|
3945
|
-
])) {
|
|
3946
|
-
const typeId = new Uint8Array(16);
|
|
3947
|
-
payload -= await safeReadBuffer(tokenizer, typeId, void 0, {
|
|
3948
|
-
maximumLength: typeId.length,
|
|
3949
|
-
reason: "ASF stream type GUID"
|
|
3950
|
-
});
|
|
3951
|
-
if (_check(typeId, [
|
|
3952
|
-
64,
|
|
3953
|
-
158,
|
|
3954
|
-
105,
|
|
3955
|
-
248,
|
|
3956
|
-
77,
|
|
3957
|
-
91,
|
|
3958
|
-
207,
|
|
3959
|
-
17,
|
|
3960
|
-
168,
|
|
3961
|
-
253,
|
|
3962
|
-
0,
|
|
3963
|
-
128,
|
|
3964
|
-
95,
|
|
3965
|
-
92,
|
|
3966
|
-
68,
|
|
3967
|
-
43
|
|
3968
|
-
])) return {
|
|
3969
|
-
ext: "asf",
|
|
3970
|
-
mime: "audio/x-ms-asf"
|
|
3971
|
-
};
|
|
3972
|
-
if (_check(typeId, [
|
|
3973
|
-
192,
|
|
3974
|
-
239,
|
|
3975
|
-
25,
|
|
3976
|
-
188,
|
|
3977
|
-
77,
|
|
3978
|
-
91,
|
|
3979
|
-
207,
|
|
3980
|
-
17,
|
|
3981
|
-
168,
|
|
3982
|
-
253,
|
|
3983
|
-
0,
|
|
3984
|
-
128,
|
|
3985
|
-
95,
|
|
3986
|
-
92,
|
|
3987
|
-
68,
|
|
3988
|
-
43
|
|
3989
|
-
])) return {
|
|
3990
|
-
ext: "asf",
|
|
3991
|
-
mime: "video/x-ms-asf"
|
|
3992
|
-
};
|
|
3993
|
-
break;
|
|
3994
|
-
}
|
|
3995
|
-
await safeIgnore(tokenizer, payload, {
|
|
3996
|
-
maximumLength: isUnknownFileSize ? maximumUntrustedSkipSizeInBytes : tokenizer.fileInfo.size,
|
|
3997
|
-
reason: "ASF header payload"
|
|
3998
|
-
});
|
|
3999
|
-
if (tokenizer.position <= previousPosition) {
|
|
4000
|
-
isMalformedAsf = true;
|
|
4001
|
-
break;
|
|
4002
|
-
}
|
|
4003
|
-
}
|
|
4004
|
-
} catch (error) {
|
|
4005
|
-
if (error instanceof EndOfStreamError || error instanceof ParserHardLimitError) {
|
|
4006
|
-
if (hasUnknownFileSize(tokenizer)) isMalformedAsf = true;
|
|
4007
|
-
} else throw error;
|
|
4008
|
-
}
|
|
4009
|
-
if (isMalformedAsf) return;
|
|
4010
|
-
return {
|
|
4011
|
-
ext: "asf",
|
|
4012
|
-
mime: "application/vnd.ms-asf"
|
|
4013
|
-
};
|
|
4014
|
-
}
|
|
4179
|
+
])) return detectAsf(tokenizer);
|
|
4015
4180
|
if (this.check([
|
|
4016
4181
|
171,
|
|
4017
4182
|
75,
|
|
@@ -4277,7 +4442,7 @@ var FileTypeParser = class {
|
|
|
4277
4442
|
70
|
|
4278
4443
|
])) return {
|
|
4279
4444
|
ext: "lnk",
|
|
4280
|
-
mime: "application/x
|
|
4445
|
+
mime: "application/x-ms-shortcut"
|
|
4281
4446
|
};
|
|
4282
4447
|
if (this.check([
|
|
4283
4448
|
98,
|
|
@@ -4298,11 +4463,11 @@ var FileTypeParser = class {
|
|
|
4298
4463
|
0
|
|
4299
4464
|
])) return {
|
|
4300
4465
|
ext: "alias",
|
|
4301
|
-
mime: "application/x
|
|
4466
|
+
mime: "application/x-ft-apple.alias"
|
|
4302
4467
|
};
|
|
4303
4468
|
if (this.checkString("Kaydara FBX Binary \0")) return {
|
|
4304
4469
|
ext: "fbx",
|
|
4305
|
-
mime: "application/x
|
|
4470
|
+
mime: "application/x-ft-fbx"
|
|
4306
4471
|
};
|
|
4307
4472
|
if (this.check([76, 80], { offset: 34 }) && (this.check([
|
|
4308
4473
|
0,
|
|
@@ -4474,10 +4639,10 @@ var FileTypeParser = class {
|
|
|
4474
4639
|
mime: "image/x-icon"
|
|
4475
4640
|
};
|
|
4476
4641
|
await tokenizer.peekBuffer(this.buffer, {
|
|
4477
|
-
length: Math.min(
|
|
4642
|
+
length: Math.min(4 + this.options.mpegOffsetTolerance, fileSize),
|
|
4478
4643
|
mayBeLess: true
|
|
4479
4644
|
});
|
|
4480
|
-
if (this.buffer.length >=
|
|
4645
|
+
if (this.buffer.length >= 4 + this.options.mpegOffsetTolerance) for (let depth = 0; depth <= this.options.mpegOffsetTolerance; ++depth) {
|
|
4481
4646
|
const type = this.scanMpeg(depth);
|
|
4482
4647
|
if (type) return type;
|
|
4483
4648
|
}
|
|
@@ -4494,7 +4659,6 @@ var FileTypeParser = class {
|
|
|
4494
4659
|
ext: "dng",
|
|
4495
4660
|
mime: "image/x-adobe-dng"
|
|
4496
4661
|
};
|
|
4497
|
-
default:
|
|
4498
4662
|
}
|
|
4499
4663
|
}
|
|
4500
4664
|
async readTiffIFD(bigEndian) {
|
|
@@ -4528,6 +4692,7 @@ var FileTypeParser = class {
|
|
|
4528
4692
|
};
|
|
4529
4693
|
}
|
|
4530
4694
|
}
|
|
4695
|
+
if (hasUnknownFileSize(this.tokenizer) && ifdOffset > maximumTiffStreamIfdOffsetInBytes) return tiffFileType;
|
|
4531
4696
|
const maximumTiffOffset = hasUnknownFileSize(this.tokenizer) ? maximumTiffIfdOffsetInBytes : this.tokenizer.fileInfo.size;
|
|
4532
4697
|
try {
|
|
4533
4698
|
await safeIgnore(this.tokenizer, ifdOffset, {
|
|
@@ -4563,19 +4728,23 @@ var FileTypeParser = class {
|
|
|
4563
4728
|
if (this.check([16], {
|
|
4564
4729
|
offset: offset + 1,
|
|
4565
4730
|
mask: [22]
|
|
4566
|
-
})) {
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
}
|
|
4731
|
+
})) return {
|
|
4732
|
+
ext: "aac",
|
|
4733
|
+
mime: "audio/aac"
|
|
4734
|
+
};
|
|
4735
|
+
if (this.check([255, 254], { offset })) return;
|
|
4736
|
+
if (this.check([8], {
|
|
4737
|
+
offset: offset + 1,
|
|
4738
|
+
mask: [24]
|
|
4739
|
+
})) return;
|
|
4740
|
+
if (this.check([240], {
|
|
4741
|
+
offset: offset + 2,
|
|
4742
|
+
mask: [240]
|
|
4743
|
+
})) return;
|
|
4744
|
+
if (this.check([12], {
|
|
4745
|
+
offset: offset + 2,
|
|
4746
|
+
mask: [12]
|
|
4747
|
+
})) return;
|
|
4579
4748
|
if (this.check([2], {
|
|
4580
4749
|
offset: offset + 1,
|
|
4581
4750
|
mask: [6]
|
|
@@ -4605,4 +4774,4 @@ new Set(mimeTypes);
|
|
|
4605
4774
|
//#endregion
|
|
4606
4775
|
export { fileTypeFromBlob };
|
|
4607
4776
|
|
|
4608
|
-
//# sourceMappingURL=
|
|
4777
|
+
//# sourceMappingURL=source-BpNO27ea.mjs.map
|