@@ -6,6 +6,7 @@ const openAsync = promisify(fs.open);
66const closeAsync = promisify ( fs . close ) ;
77
88const MAX_BYTES : number = 512 ;
9+ const UTF8_BOUNDARY_RESERVE : number = 3 ;
910
1011// A very basic non-exception raising reader. Read bytes and
1112// at the end use hasError() to check whether this worked.
@@ -120,12 +121,12 @@ export async function isBinaryFile(file: string | Buffer, size?: number): Promis
120121
121122 const fileDescriptor = await openAsync ( file , 'r' ) ;
122123
123- const allocBuffer = Buffer . alloc ( MAX_BYTES ) ;
124+ const allocBuffer = Buffer . alloc ( MAX_BYTES + UTF8_BOUNDARY_RESERVE ) ;
124125
125126 // Read the file with no encoding for raw buffer access.
126127 // NB: something is severely wrong with promisify, had to construct my own Promise
127128 return new Promise ( ( fulfill , reject ) => {
128- fs . read ( fileDescriptor , allocBuffer , 0 , MAX_BYTES , 0 , ( err , bytesRead , _ ) => {
129+ fs . read ( fileDescriptor , allocBuffer , 0 , MAX_BYTES + UTF8_BOUNDARY_RESERVE , 0 , ( err , bytesRead , _ ) => {
129130 closeAsync ( fileDescriptor ) ;
130131 if ( err ) {
131132 reject ( err ) ;
@@ -154,9 +155,9 @@ export function isBinaryFileSync(file: string | Buffer, size?: number): boolean
154155
155156 const fileDescriptor = fs . openSync ( file , 'r' ) ;
156157
157- const allocBuffer = Buffer . alloc ( MAX_BYTES ) ;
158+ const allocBuffer = Buffer . alloc ( MAX_BYTES + UTF8_BOUNDARY_RESERVE ) ;
158159
159- const bytesRead = fs . readSync ( fileDescriptor , allocBuffer , 0 , MAX_BYTES , 0 ) ;
160+ const bytesRead = fs . readSync ( fileDescriptor , allocBuffer , 0 , MAX_BYTES + UTF8_BOUNDARY_RESERVE , 0 ) ;
160161 fs . closeSync ( fileDescriptor ) ;
161162
162163 return isBinaryCheck ( allocBuffer , bytesRead ) ;
@@ -175,7 +176,8 @@ function isBinaryCheck(fileBuffer: Buffer, bytesRead: number): boolean {
175176 }
176177
177178 let suspiciousBytes = 0 ;
178- const totalBytes = Math . min ( bytesRead , MAX_BYTES ) ;
179+ const totalBytes = Math . min ( bytesRead , MAX_BYTES + UTF8_BOUNDARY_RESERVE ) ;
180+ const scanBytes = Math . min ( totalBytes , MAX_BYTES ) ;
179181
180182 // UTF-8 BOM
181183 if ( bytesRead >= 3 && fileBuffer [ 0 ] === 0xef && fileBuffer [ 1 ] === 0xbb && fileBuffer [ 2 ] === 0xbf ) {
@@ -230,7 +232,7 @@ function isBinaryCheck(fileBuffer: Buffer, bytesRead: number): boolean {
230232 return false ;
231233 }
232234
233- for ( let i = 0 ; i < totalBytes ; i ++ ) {
235+ for ( let i = 0 ; i < scanBytes ; i ++ ) {
234236 if ( fileBuffer [ i ] === 0 ) {
235237 // NULL byte--it's binary!
236238 return true ;
@@ -264,17 +266,17 @@ function isBinaryCheck(fileBuffer: Buffer, bytesRead: number): boolean {
264266
265267 suspiciousBytes ++ ;
266268 // Read at least 32 fileBuffer before making a decision
267- if ( i >= 32 && ( suspiciousBytes * 100 ) / totalBytes > 10 ) {
269+ if ( i >= 32 && ( suspiciousBytes * 100 ) / ( scanBytes ) > 10 ) {
268270 return true ;
269271 }
270272 }
271273 }
272274
273- if ( ( suspiciousBytes * 100 ) / totalBytes > 10 ) {
275+ if ( ( suspiciousBytes * 100 ) / ( scanBytes ) > 10 ) {
274276 return true ;
275277 }
276278
277- if ( suspiciousBytes > 1 && isBinaryProto ( fileBuffer , totalBytes ) ) {
279+ if ( suspiciousBytes > 1 && isBinaryProto ( fileBuffer , scanBytes ) ) {
278280 return true ;
279281 }
280282
0 commit comments