isbinaryfile
Advanced tools
Comparing version 4.0.8 to 4.0.9
@@ -19,2 +19,81 @@ "use strict"; | ||
const MAX_BYTES = 512; | ||
// A very basic non-exception raising reader. Read bytes and | ||
// at the end use hasError() to check whether this worked. | ||
class Reader { | ||
constructor(fileBuffer, size) { | ||
this.fileBuffer = fileBuffer; | ||
this.size = size; | ||
this.offset = 0; | ||
this.error = false; | ||
} | ||
hasError() { | ||
return this.error; | ||
} | ||
nextByte() { | ||
if (this.offset === this.size || this.hasError()) { | ||
this.error = true; | ||
return 0xff; | ||
} | ||
return this.fileBuffer[this.offset++]; | ||
} | ||
next(len) { | ||
const n = new Array(); | ||
for (let i = 0; i < len; i++) { | ||
n[i] = this.nextByte(); | ||
} | ||
return n; | ||
} | ||
} | ||
// Read a Google Protobuf var(iable)int from the buffer. | ||
function readProtoVarInt(reader) { | ||
let idx = 0; | ||
let varInt = 0; | ||
while (!reader.hasError()) { | ||
const b = reader.nextByte(); | ||
varInt = varInt | ((b & 0x7f) << (7 * idx)); | ||
if ((b & 0x80) === 0) { | ||
break; | ||
} | ||
idx++; | ||
} | ||
return varInt; | ||
} | ||
// Attempt to taste a full Google Protobuf message. | ||
function readProtoMessage(reader) { | ||
const varInt = readProtoVarInt(reader); | ||
const wireType = varInt & 0x7; | ||
switch (wireType) { | ||
case 0: | ||
readProtoVarInt(reader); | ||
return true; | ||
case 1: | ||
reader.next(8); | ||
return true; | ||
case 2: | ||
const len = readProtoVarInt(reader); | ||
reader.next(len); | ||
return true; | ||
case 5: | ||
reader.next(4); | ||
return true; | ||
} | ||
return false; | ||
} | ||
// Check whether this seems to be a valid protobuf file. | ||
function isBinaryProto(fileBuffer, totalBytes) { | ||
const reader = new Reader(fileBuffer, totalBytes); | ||
let numMessages = 0; | ||
while (true) { | ||
// Definitely not a valid protobuf | ||
if (!readProtoMessage(reader) && !reader.hasError()) { | ||
return false; | ||
} | ||
// Short read? | ||
if (reader.hasError()) { | ||
break; | ||
} | ||
numMessages++; | ||
} | ||
return numMessages > 0; | ||
} | ||
function isBinaryFile(file, size) { | ||
@@ -137,3 +216,3 @@ return __awaiter(this, void 0, void 0, function* () { | ||
// Read at least 32 fileBuffer before making a decision | ||
if (i > 32 && (suspiciousBytes * 100) / totalBytes > 10) { | ||
if (i >= 32 && (suspiciousBytes * 100) / totalBytes > 10) { | ||
return true; | ||
@@ -146,2 +225,5 @@ } | ||
} | ||
if (suspiciousBytes > 1 && isBinaryProto(fileBuffer, totalBytes)) { | ||
return true; | ||
} | ||
return false; | ||
@@ -148,0 +230,0 @@ } |
{ | ||
"name": "isbinaryfile", | ||
"description": "Detects if a file is binary in Node.js. Similar to Perl's -B.", | ||
"version": "4.0.8", | ||
"version": "4.0.9", | ||
"keywords": [ | ||
@@ -20,9 +20,8 @@ "text", | ||
], | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@types/jest": "^23.3.14", | ||
"@types/node": "^10.17.59", | ||
"jest": "^25.5.4", | ||
"jest": "^26.5.5", | ||
"prettier": "^1.19.1", | ||
"release-it": "^14.6.1", | ||
"release-it": "^14.13.1", | ||
"ts-jest": "^26.5.5", | ||
@@ -34,3 +33,3 @@ "tslint": "^5.20.1", | ||
"engines": { | ||
"node": ">= 8.0.0" | ||
"node": ">= 14.0.0" | ||
}, | ||
@@ -56,3 +55,3 @@ "files": [ | ||
"build": "tsc", | ||
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", | ||
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\" && tslint --fix -c tslint.json 'src/**/*.ts'", | ||
"lint": "tslint -p tsconfig.json", | ||
@@ -59,0 +58,0 @@ "prepare": "npm run build", |
12505
238