@@ -129,7 +129,9 @@ export async function fileTypeStream(webStream, options) {
129
129
130
130
export class FileTypeParser {
131
131
constructor ( options ) {
132
- this . detectors = [ ...( options ?. customDetectors ?? [ ] ) , this . parse ] ;
132
+ this . detectors = [ ...( options ?. customDetectors ?? [ ] ) ,
133
+ { id : 'core.safe' , detect : this . detectCore } ,
134
+ { id : 'core.unsafe' , detect : this . detectUnsafe } ] ;
133
135
this . tokenizerOptions = {
134
136
abortSignal : options ?. signal ,
135
137
} ;
@@ -140,7 +142,7 @@ export class FileTypeParser {
140
142
141
143
// Iterate through all file-type detectors
142
144
for ( const detector of this . detectors ) {
143
- const fileType = await detector ( tokenizer ) ;
145
+ const fileType = await detector . detect ( tokenizer ) ;
144
146
if ( fileType ) {
145
147
return fileType ;
146
148
}
@@ -231,7 +233,7 @@ export class FileTypeParser {
231
233
return this . check ( stringToBytes ( header ) , options ) ;
232
234
}
233
235
234
- parse = async tokenizer => {
236
+ detectCore = async tokenizer => {
235
237
this . buffer = new Uint8Array ( reasonableDetectionSizeInBytes ) ;
236
238
237
239
// Keep reading until EOF if the file size is unknown.
@@ -321,7 +323,7 @@ export class FileTypeParser {
321
323
if ( this . check ( [ 0xEF , 0xBB , 0xBF ] ) ) { // UTF-8-BOM
322
324
// Strip off UTF-8-BOM
323
325
this . tokenizer . ignore ( 3 ) ;
324
- return this . parse ( tokenizer ) ;
326
+ return this . detectCore ( tokenizer ) ;
325
327
}
326
328
327
329
if ( this . check ( [ 0x47 , 0x49 , 0x46 ] ) ) {
@@ -1381,39 +1383,6 @@ export class FileTypeParser {
1381
1383
return undefined ; // Some unknown text based format
1382
1384
}
1383
1385
1384
- // -- Unsafe signatures --
1385
-
1386
- if (
1387
- this . check ( [ 0x0 , 0x0 , 0x1 , 0xBA ] )
1388
- || this . check ( [ 0x0 , 0x0 , 0x1 , 0xB3 ] )
1389
- ) {
1390
- return {
1391
- ext : 'mpg' ,
1392
- mime : 'video/mpeg' ,
1393
- } ;
1394
- }
1395
-
1396
- if ( this . check ( [ 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ] ) ) {
1397
- return {
1398
- ext : 'ttf' ,
1399
- mime : 'font/ttf' ,
1400
- } ;
1401
- }
1402
-
1403
- if ( this . check ( [ 0x00 , 0x00 , 0x01 , 0x00 ] ) ) {
1404
- return {
1405
- ext : 'ico' ,
1406
- mime : 'image/x-icon' ,
1407
- } ;
1408
- }
1409
-
1410
- if ( this . check ( [ 0x00 , 0x00 , 0x02 , 0x00 ] ) ) {
1411
- return {
1412
- ext : 'cur' ,
1413
- mime : 'image/x-icon' ,
1414
- } ;
1415
- }
1416
-
1417
1386
if ( this . check ( [ 0xD0 , 0xCF , 0x11 , 0xE0 , 0xA1 , 0xB1 , 0x1A , 0xE1 ] ) ) {
1418
1387
// Detected Microsoft Compound File Binary File (MS-CFB) Format.
1419
1388
return {
@@ -1619,6 +1588,44 @@ export class FileTypeParser {
1619
1588
mime : 'application/pgp-encrypted' ,
1620
1589
} ;
1621
1590
}
1591
+ } ;
1592
+
1593
+ detectUnsafe = async tokenizer => {
1594
+ this . buffer = new Uint8Array ( reasonableDetectionSizeInBytes ) ;
1595
+
1596
+ // Read initial sample size of 8 bytes
1597
+ await tokenizer . peekBuffer ( this . buffer , { length : Math . min ( 8 , tokenizer . fileInfo . size ) , mayBeLess : true } ) ;
1598
+
1599
+ if (
1600
+ this . check ( [ 0x0 , 0x0 , 0x1 , 0xBA ] )
1601
+ || this . check ( [ 0x0 , 0x0 , 0x1 , 0xB3 ] )
1602
+ ) {
1603
+ return {
1604
+ ext : 'mpg' ,
1605
+ mime : 'video/mpeg' ,
1606
+ } ;
1607
+ }
1608
+
1609
+ if ( this . check ( [ 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ] ) ) {
1610
+ return {
1611
+ ext : 'ttf' ,
1612
+ mime : 'font/ttf' ,
1613
+ } ;
1614
+ }
1615
+
1616
+ if ( this . check ( [ 0x00 , 0x00 , 0x01 , 0x00 ] ) ) {
1617
+ return {
1618
+ ext : 'ico' ,
1619
+ mime : 'image/x-icon' ,
1620
+ } ;
1621
+ }
1622
+
1623
+ if ( this . check ( [ 0x00 , 0x00 , 0x02 , 0x00 ] ) ) {
1624
+ return {
1625
+ ext : 'cur' ,
1626
+ mime : 'image/x-icon' ,
1627
+ } ;
1628
+ }
1622
1629
1623
1630
// Check MPEG 1 or 2 Layer 3 header, or 'layer 0' for ADTS (MPEG sync-word 0xFFE)
1624
1631
if ( this . buffer . length >= 2 && this . check ( [ 0xFF , 0xE0 ] , { offset : 0 , mask : [ 0xFF , 0xE0 ] } ) ) {
0 commit comments