file-type 14.6.2 → 15.0.1
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/core.d.ts +9 -5
- package/core.js +42 -24
- package/package.json +6 -3
- package/readme.md +9 -5
- package/supported.js +8 -4
- package/util.js +15 -31
package/core.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ declare namespace core {
|
|
|
23
23
|
| 'icns'
|
|
24
24
|
| 'jxr'
|
|
25
25
|
| 'psd'
|
|
26
|
+
| 'indd'
|
|
26
27
|
| 'zip'
|
|
27
28
|
| 'tar'
|
|
28
29
|
| 'rar'
|
|
@@ -72,7 +73,7 @@ declare namespace core {
|
|
|
72
73
|
| 'rpm'
|
|
73
74
|
| 'Z'
|
|
74
75
|
| 'lz'
|
|
75
|
-
| '
|
|
76
|
+
| 'cfb'
|
|
76
77
|
| 'mxf'
|
|
77
78
|
| 'mts'
|
|
78
79
|
| 'wasm'
|
|
@@ -134,7 +135,8 @@ declare namespace core {
|
|
|
134
135
|
| 'avif'
|
|
135
136
|
| 'eps'
|
|
136
137
|
| 'lzh'
|
|
137
|
-
| 'pgp'
|
|
138
|
+
| 'pgp'
|
|
139
|
+
| 'asar';
|
|
138
140
|
|
|
139
141
|
type MimeType =
|
|
140
142
|
| 'image/jpeg'
|
|
@@ -149,6 +151,7 @@ declare namespace core {
|
|
|
149
151
|
| 'image/icns'
|
|
150
152
|
| 'image/vnd.ms-photo'
|
|
151
153
|
| 'image/vnd.adobe.photoshop'
|
|
154
|
+
| 'application/x-indesign'
|
|
152
155
|
| 'application/epub+zip'
|
|
153
156
|
| 'application/x-xpinstall'
|
|
154
157
|
| 'application/vnd.oasis.opendocument.text'
|
|
@@ -211,7 +214,7 @@ declare namespace core {
|
|
|
211
214
|
| 'application/x-rpm'
|
|
212
215
|
| 'application/x-compress'
|
|
213
216
|
| 'application/x-lzip'
|
|
214
|
-
| 'application/x-
|
|
217
|
+
| 'application/x-cfb'
|
|
215
218
|
| 'application/x-mie'
|
|
216
219
|
| 'application/x-apache-arrow'
|
|
217
220
|
| 'application/mxf'
|
|
@@ -260,7 +263,8 @@ declare namespace core {
|
|
|
260
263
|
| 'application/vnd.sketchup.skp'
|
|
261
264
|
| 'image/avif'
|
|
262
265
|
| 'application/x-lzh-compressed'
|
|
263
|
-
| 'application/pgp-encrypted'
|
|
266
|
+
| 'application/pgp-encrypted'
|
|
267
|
+
| 'application/x-asar';
|
|
264
268
|
|
|
265
269
|
interface FileTypeResult {
|
|
266
270
|
/**
|
|
@@ -332,7 +336,7 @@ declare namespace core {
|
|
|
332
336
|
/**
|
|
333
337
|
Supported file extensions.
|
|
334
338
|
*/
|
|
335
|
-
const extensions:
|
|
339
|
+
const extensions: Set<core.FileExtension>;
|
|
336
340
|
|
|
337
341
|
/**
|
|
338
342
|
Supported MIME types.
|
package/core.js
CHANGED
|
@@ -4,8 +4,7 @@ const strtok3 = require('strtok3/lib/core');
|
|
|
4
4
|
const {
|
|
5
5
|
stringToBytes,
|
|
6
6
|
tarHeaderChecksumMatches,
|
|
7
|
-
uint32SyncSafeToken
|
|
8
|
-
uint8ArrayUtf8ByteString
|
|
7
|
+
uint32SyncSafeToken
|
|
9
8
|
} = require('./util');
|
|
10
9
|
const supported = require('./supported');
|
|
11
10
|
|
|
@@ -464,7 +463,7 @@ async function _fromTokenizer(tokenizer) {
|
|
|
464
463
|
) {
|
|
465
464
|
// They all can have MIME `video/mp4` except `application/mp4` special-case which is hard to detect.
|
|
466
465
|
// For some cases, we're specific, everything else falls to `video/mp4` with `mp4` extension.
|
|
467
|
-
const brandMajor =
|
|
466
|
+
const brandMajor = buffer.toString('binary', 8, 12).replace('\0', ' ').trim();
|
|
468
467
|
switch (brandMajor) {
|
|
469
468
|
case 'avif':
|
|
470
469
|
return {ext: 'avif', mime: 'image/avif'};
|
|
@@ -968,6 +967,10 @@ async function _fromTokenizer(tokenizer) {
|
|
|
968
967
|
|
|
969
968
|
do {
|
|
970
969
|
const chunk = await readChunkHeader();
|
|
970
|
+
if (chunk.length < 0) {
|
|
971
|
+
return; // Invalid chunk length
|
|
972
|
+
}
|
|
973
|
+
|
|
971
974
|
switch (chunk.type) {
|
|
972
975
|
case 'IDAT':
|
|
973
976
|
return {
|
|
@@ -982,7 +985,7 @@ async function _fromTokenizer(tokenizer) {
|
|
|
982
985
|
default:
|
|
983
986
|
await tokenizer.ignore(chunk.length + 4); // Ignore chunk-data + CRC
|
|
984
987
|
}
|
|
985
|
-
} while (tokenizer.position < tokenizer.fileInfo.size);
|
|
988
|
+
} while (tokenizer.position + 8 < tokenizer.fileInfo.size);
|
|
986
989
|
|
|
987
990
|
return {
|
|
988
991
|
ext: 'png',
|
|
@@ -1170,6 +1173,14 @@ async function _fromTokenizer(tokenizer) {
|
|
|
1170
1173
|
};
|
|
1171
1174
|
}
|
|
1172
1175
|
|
|
1176
|
+
if (check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) {
|
|
1177
|
+
// Detected Microsoft Compound File Binary File (MS-CFB) Format.
|
|
1178
|
+
return {
|
|
1179
|
+
ext: 'cfb',
|
|
1180
|
+
mime: 'application/x-cfb'
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1173
1184
|
// Increase sample size from 12 to 256.
|
|
1174
1185
|
await tokenizer.peekBuffer(buffer, {length: Math.min(256, tokenizer.fileInfo.size), mayBeLess: true});
|
|
1175
1186
|
|
|
@@ -1195,21 +1206,22 @@ async function _fromTokenizer(tokenizer) {
|
|
|
1195
1206
|
};
|
|
1196
1207
|
}
|
|
1197
1208
|
|
|
1198
|
-
if (
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1209
|
+
if (check([0x04, 0x00, 0x00, 0x00]) && buffer.length >= 16) { // Rough & quick check Pickle/ASAR
|
|
1210
|
+
const jsonSize = buffer.readUInt32LE(12);
|
|
1211
|
+
if (jsonSize > 12 && jsonSize < 240 && buffer.length >= jsonSize + 16) {
|
|
1212
|
+
try {
|
|
1213
|
+
const header = buffer.slice(16, jsonSize + 16).toString();
|
|
1214
|
+
const json = JSON.parse(header);
|
|
1215
|
+
// Check if Pickle is ASAR
|
|
1216
|
+
if (json.files) { // Final check, assuring Pickle/ASAR format
|
|
1217
|
+
return {
|
|
1218
|
+
ext: 'asar',
|
|
1219
|
+
mime: 'application/x-asar'
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
} catch (_) {
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1213
1225
|
}
|
|
1214
1226
|
|
|
1215
1227
|
if (check([0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02])) {
|
|
@@ -1275,13 +1287,18 @@ async function _fromTokenizer(tokenizer) {
|
|
|
1275
1287
|
};
|
|
1276
1288
|
}
|
|
1277
1289
|
|
|
1290
|
+
if (check([0x06, 0x06, 0xED, 0xF5, 0xD8, 0x1D, 0x46, 0xE5, 0xBD, 0x31, 0xEF, 0xE7, 0xFE, 0x74, 0xB7, 0x1D])) {
|
|
1291
|
+
return {
|
|
1292
|
+
ext: 'indd',
|
|
1293
|
+
mime: 'application/x-indesign'
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1278
1297
|
// Increase sample size from 256 to 512
|
|
1279
1298
|
await tokenizer.peekBuffer(buffer, {length: Math.min(512, tokenizer.fileInfo.size), mayBeLess: true});
|
|
1280
1299
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
tarHeaderChecksumMatches(buffer)
|
|
1284
|
-
) {
|
|
1300
|
+
// Requires a buffer size of 512 bytes
|
|
1301
|
+
if (tarHeaderChecksumMatches(buffer)) {
|
|
1285
1302
|
return {
|
|
1286
1303
|
ext: 'tar',
|
|
1287
1304
|
mime: 'application/x-tar'
|
|
@@ -1360,7 +1377,8 @@ const stream = readableStream => new Promise((resolve, reject) => {
|
|
|
1360
1377
|
const pass = new stream.PassThrough();
|
|
1361
1378
|
let outputStream;
|
|
1362
1379
|
if (stream.pipeline) {
|
|
1363
|
-
outputStream = stream.pipeline(readableStream, pass, () => {
|
|
1380
|
+
outputStream = stream.pipeline(readableStream, pass, () => {
|
|
1381
|
+
});
|
|
1364
1382
|
} else {
|
|
1365
1383
|
outputStream = readableStream.pipe(pass);
|
|
1366
1384
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "file-type",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "15.0.1",
|
|
4
4
|
"description": "Detect the file type of a Buffer/Uint8Array/ArrayBuffer",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/file-type",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"mime",
|
|
32
32
|
"file",
|
|
33
33
|
"type",
|
|
34
|
+
"magic",
|
|
34
35
|
"archive",
|
|
35
36
|
"image",
|
|
36
37
|
"img",
|
|
@@ -66,6 +67,7 @@
|
|
|
66
67
|
"icns",
|
|
67
68
|
"jxr",
|
|
68
69
|
"psd",
|
|
70
|
+
"indd",
|
|
69
71
|
"zip",
|
|
70
72
|
"tar",
|
|
71
73
|
"rar",
|
|
@@ -110,7 +112,7 @@
|
|
|
110
112
|
"rpm",
|
|
111
113
|
"Z",
|
|
112
114
|
"lz",
|
|
113
|
-
"
|
|
115
|
+
"cfb",
|
|
114
116
|
"mxf",
|
|
115
117
|
"mts",
|
|
116
118
|
"wasm",
|
|
@@ -177,7 +179,8 @@
|
|
|
177
179
|
"avif",
|
|
178
180
|
"eps",
|
|
179
181
|
"lzh",
|
|
180
|
-
"pgp"
|
|
182
|
+
"pgp",
|
|
183
|
+
"asar"
|
|
181
184
|
],
|
|
182
185
|
"devDependencies": {
|
|
183
186
|
"@types/node": "^13.1.4",
|
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# file-type [](https://travis-ci.
|
|
1
|
+
# file-type [](https://travis-ci.com/github/sindresorhus/file-type)
|
|
2
2
|
|
|
3
3
|
> Detect the file type of a Buffer/Uint8Array/ArrayBuffer
|
|
4
4
|
|
|
@@ -289,6 +289,7 @@ Returns a set of supported MIME types.
|
|
|
289
289
|
- [`icns`](https://en.wikipedia.org/wiki/Apple_Icon_Image_format)
|
|
290
290
|
- [`jxr`](https://en.wikipedia.org/wiki/JPEG_XR)
|
|
291
291
|
- [`psd`](https://en.wikipedia.org/wiki/Adobe_Photoshop#File_format)
|
|
292
|
+
- [`indd`](https://en.wikipedia.org/wiki/Adobe_InDesign#File_format)
|
|
292
293
|
- [`zip`](https://en.wikipedia.org/wiki/Zip_(file_format))
|
|
293
294
|
- [`tar`](https://en.wikipedia.org/wiki/Tar_(computing)#File_format)
|
|
294
295
|
- [`rar`](https://en.wikipedia.org/wiki/RAR_(file_format))
|
|
@@ -342,7 +343,7 @@ Returns a set of supported MIME types.
|
|
|
342
343
|
- [`rpm`](https://fileinfo.com/extension/rpm)
|
|
343
344
|
- [`Z`](https://fileinfo.com/extension/z)
|
|
344
345
|
- [`lz`](https://en.wikipedia.org/wiki/Lzip)
|
|
345
|
-
- [`
|
|
346
|
+
- [`cfb`](https://en.wikipedia.org/wiki/Compound_File_Binary_Format)
|
|
346
347
|
- [`mxf`](https://en.wikipedia.org/wiki/Material_Exchange_Format)
|
|
347
348
|
- [`mts`](https://en.wikipedia.org/wiki/.m2ts)
|
|
348
349
|
- [`wasm`](https://en.wikipedia.org/wiki/WebAssembly)
|
|
@@ -401,13 +402,16 @@ Returns a set of supported MIME types.
|
|
|
401
402
|
- [`eps`](https://en.wikipedia.org/wiki/Encapsulated_PostScript) - Encapsulated PostScript
|
|
402
403
|
- [`lzh`](https://en.wikipedia.org/wiki/LHA_(file_format)) - LZH archive
|
|
403
404
|
- [`pgp`](https://en.wikipedia.org/wiki/Pretty_Good_Privacy) - Pretty Good Privacy
|
|
405
|
+
- [`asar`](https://github.com/electron/asar#format) - Archive format primarily used to enclose Electron applications
|
|
404
406
|
|
|
405
407
|
*Pull requests are welcome for additional commonly used file types.*
|
|
406
408
|
|
|
407
409
|
The following file types will not be accepted:
|
|
408
|
-
-
|
|
409
|
-
- `.
|
|
410
|
-
- `.
|
|
410
|
+
- [MS-CFB: Microsoft Compound File Binary File Format based formats](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb/53989ce4-7b05-4f8d-829b-d08d6148375b), too old and difficult to parse:
|
|
411
|
+
- `.doc` - Microsoft Word 97-2003 Document
|
|
412
|
+
- `.xls` - Microsoft Excel 97-2003 Document
|
|
413
|
+
- `.ppt` - Microsoft PowerPoint97-2003 Document
|
|
414
|
+
- `.msi` - Microsoft Windows Installer
|
|
411
415
|
- `.csv` - [Reason.](https://github.com/sindresorhus/file-type/issues/264#issuecomment-568439196)
|
|
412
416
|
- `.svg` - Detecting it requires a full-blown parser. Check out [`is-svg`](https://github.com/sindresorhus/is-svg) for something that mostly works.
|
|
413
417
|
|
package/supported.js
CHANGED
|
@@ -21,6 +21,7 @@ module.exports = {
|
|
|
21
21
|
'icns',
|
|
22
22
|
'jxr',
|
|
23
23
|
'psd',
|
|
24
|
+
'indd',
|
|
24
25
|
'zip',
|
|
25
26
|
'tar',
|
|
26
27
|
'rar',
|
|
@@ -71,7 +72,7 @@ module.exports = {
|
|
|
71
72
|
'rpm',
|
|
72
73
|
'Z',
|
|
73
74
|
'lz',
|
|
74
|
-
'
|
|
75
|
+
'cfb',
|
|
75
76
|
'mxf',
|
|
76
77
|
'mts',
|
|
77
78
|
'blend',
|
|
@@ -132,7 +133,8 @@ module.exports = {
|
|
|
132
133
|
'avif',
|
|
133
134
|
'eps',
|
|
134
135
|
'lzh',
|
|
135
|
-
'pgp'
|
|
136
|
+
'pgp',
|
|
137
|
+
'asar'
|
|
136
138
|
],
|
|
137
139
|
mimeTypes: [
|
|
138
140
|
'image/jpeg',
|
|
@@ -146,6 +148,7 @@ module.exports = {
|
|
|
146
148
|
'image/bmp',
|
|
147
149
|
'image/vnd.ms-photo',
|
|
148
150
|
'image/vnd.adobe.photoshop',
|
|
151
|
+
'application/x-indesign',
|
|
149
152
|
'application/epub+zip',
|
|
150
153
|
'application/x-xpinstall',
|
|
151
154
|
'application/vnd.oasis.opendocument.text',
|
|
@@ -209,7 +212,7 @@ module.exports = {
|
|
|
209
212
|
'application/x-rpm',
|
|
210
213
|
'application/x-compress',
|
|
211
214
|
'application/x-lzip',
|
|
212
|
-
'application/x-
|
|
215
|
+
'application/x-cfb',
|
|
213
216
|
'application/x-mie',
|
|
214
217
|
'application/mxf',
|
|
215
218
|
'video/mp2t',
|
|
@@ -258,6 +261,7 @@ module.exports = {
|
|
|
258
261
|
'application/vnd.sketchup.skp',
|
|
259
262
|
'image/avif',
|
|
260
263
|
'application/x-lzh-compressed',
|
|
261
|
-
'application/pgp-encrypted'
|
|
264
|
+
'application/pgp-encrypted',
|
|
265
|
+
'application/x-asar'
|
|
262
266
|
]
|
|
263
267
|
};
|
package/util.js
CHANGED
|
@@ -2,48 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
exports.stringToBytes = string => [...string].map(character => character.charCodeAt(0));
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
5
|
+
/**
|
|
6
|
+
Checks whether the TAR checksum is valid.
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
@param {Buffer} buffer - The TAR header `[offset ... offset + 512]`.
|
|
9
|
+
@param {number} offset - TAR header offset.
|
|
10
|
+
@returns {boolean} `true` if the TAR checksum is valid, otherwise `false`.
|
|
11
|
+
*/
|
|
12
|
+
exports.tarHeaderChecksumMatches = (buffer, offset = 0) => {
|
|
13
|
+
const readSum = parseInt(buffer.toString('utf8', 148, 154).replace(/\0.*$/, '').trim(), 8); // Read sum in header
|
|
14
|
+
if (isNaN(readSum)) {
|
|
11
15
|
return false;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let sum = 256; // Intitalize sum, with 256 as sum of 8 spaces in checksum field
|
|
17
|
-
let signedBitSum = 0; // Initialize signed bit sum
|
|
18
|
+
let sum = 8 * 0x20; // Initialize signed bit sum
|
|
18
19
|
|
|
19
|
-
for (let i =
|
|
20
|
-
|
|
21
|
-
sum += byte;
|
|
22
|
-
signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum
|
|
20
|
+
for (let i = offset; i < offset + 148; i++) {
|
|
21
|
+
sum += buffer[i];
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
for (let i = 156; i < 512; i++) {
|
|
28
|
-
const byte = buffer[i];
|
|
29
|
-
sum += byte;
|
|
30
|
-
signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum
|
|
24
|
+
for (let i = offset + 156; i < offset + 512; i++) {
|
|
25
|
+
sum += buffer[i];
|
|
31
26
|
}
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// Some implementations compute checksum incorrectly using signed bytes
|
|
36
|
-
return (
|
|
37
|
-
// Checksum in header equals the sum we calculated
|
|
38
|
-
readSum === sum ||
|
|
39
|
-
|
|
40
|
-
// Checksum in header equals sum we calculated plus signed-to-unsigned delta
|
|
41
|
-
readSum === (sum - (signedBitSum << 1))
|
|
42
|
-
);
|
|
28
|
+
return readSum === sum;
|
|
43
29
|
};
|
|
44
30
|
|
|
45
|
-
exports.uint8ArrayUtf8ByteString = uint8ArrayUtf8ByteString;
|
|
46
|
-
|
|
47
31
|
/**
|
|
48
32
|
ID3 UINT32 sync-safe tokenizer token.
|
|
49
33
|
28 bits (representing up to 256MB) integer, the msb is 0 to avoid "false syncsignals".
|