isbinaryfile
Advanced tools
Comparing version 2.0.4 to 3.0.0
112
index.js
var fs = require('fs'); | ||
var path = require("path"); | ||
var max_bytes = 512; | ||
var MAX_BYTES = 512; | ||
module.exports = function(bytes, size) { | ||
// Read the file with no encoding for raw buffer access. | ||
if (size === undefined) { | ||
module.exports = function(bytes, size, cb) { | ||
// Only two args | ||
if (cb === undefined) { | ||
var file = bytes; | ||
try { | ||
if(!fs.statSync(file).isFile()) return false; | ||
} catch (err) { | ||
// otherwise continue on | ||
} | ||
var descriptor = fs.openSync(file, 'r'); | ||
try { | ||
bytes = new Buffer(max_bytes); | ||
size = fs.readSync(descriptor, bytes, 0, bytes.length, 0); | ||
} finally { | ||
fs.closeSync(descriptor); | ||
} | ||
} | ||
// async version has a function instead of a `size` | ||
else if (typeof size === "function") { | ||
var file = bytes, callback = size; | ||
cb = size; | ||
fs.stat(file, function(err, stat) { | ||
if (err || !stat.isFile()) return callback(null, false); | ||
if (err || !stat.isFile()) return cb(err, false); | ||
fs.open(file, 'r', function(err, descriptor){ | ||
if (err) return callback(err); | ||
var bytes = new Buffer(max_bytes); | ||
fs.open(file, 'r', function(r_err, descriptor){ | ||
if (r_err) return cb(r_err); | ||
bytes = new Buffer(MAX_BYTES); | ||
// Read the file with no encoding for raw buffer access. | ||
fs.read(descriptor, bytes, 0, bytes.length, 0, function(err, size, bytes){ | ||
fs.close(descriptor, function(err2){ | ||
if (err || err2) | ||
return callback(err || err2); | ||
return callback(null, isBinaryCheck(bytes, size)); | ||
fs.close(descriptor, function(c_err){ | ||
if (c_err) return cb(c_err, false); | ||
return cb(null, isBinaryCheck(bytes, size)); | ||
}); | ||
@@ -42,6 +27,6 @@ }); | ||
} | ||
else | ||
return cb(null, isBinaryCheck(bytes, size)); | ||
}; | ||
return isBinaryCheck(bytes, size); | ||
} | ||
function isBinaryCheck(bytes, size) { | ||
@@ -52,9 +37,39 @@ if (size === 0) | ||
var suspicious_bytes = 0; | ||
var total_bytes = Math.min(size, max_bytes); | ||
var total_bytes = Math.min(size, MAX_BYTES); | ||
// UTF-8 BOM | ||
if (size >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { | ||
// UTF-8 BOM. This isn't binary. | ||
return false; | ||
} | ||
// UTF-32 BOM | ||
if (size >= 4 && bytes[0] === 0x00 && bytes[1] === 0x00 && bytes[2] == 0xFE && bytes[3] == 0xFF) { | ||
return false; | ||
} | ||
// UTF-32 LE BOM | ||
if (size >= 4 && bytes[0] == 0xFF && bytes[1] == 0xFE && bytes[2] === 0x00 && bytes[3] === 0x00) { | ||
return false; | ||
} | ||
// GB BOM | ||
if (size >= 4 && bytes[0] == 0x84 && bytes[1] == 0x31 && bytes[2] == 0x95 && bytes[3] == 0x33) { | ||
return false; | ||
} | ||
if (total_bytes >= 4 && bytes[0] == 0x25 && bytes[1] == 0x50 && bytes[2] == 0x44 && bytes[3] == 0x46) { | ||
return true; | ||
} | ||
// UTF-16 BE BOM | ||
if (size >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) { | ||
return false; | ||
} | ||
// UTF-16 LE BOM | ||
if (size >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) { | ||
return false; | ||
} | ||
for (var i = 0; i < total_bytes; i++) { | ||
@@ -69,3 +84,3 @@ if (bytes[i] === 0) { // NULL byte--it's binary! | ||
if (bytes[i] > 127 && bytes[i] < 192) { | ||
continue; | ||
continue; | ||
} | ||
@@ -76,4 +91,4 @@ } | ||
if (bytes[i] > 127 && bytes[i] < 192 && bytes[i + 1] > 127 && bytes[i + 1] < 192) { | ||
i++; | ||
continue; | ||
i++; | ||
continue; | ||
} | ||
@@ -84,3 +99,3 @@ } | ||
if (i > 32 && (suspicious_bytes * 100) / total_bytes > 10) { | ||
return true; | ||
return true; | ||
} | ||
@@ -96,1 +111,24 @@ } | ||
} | ||
module.exports.sync = function(bytes, size) { | ||
// Only one arg | ||
if (size === undefined) { | ||
var file = bytes; | ||
try { | ||
if(!fs.statSync(file).isFile()) return false; | ||
} catch (err) { | ||
// otherwise continue on | ||
} | ||
var descriptor = fs.openSync(file, 'r'); | ||
try { | ||
// Read the file with no encoding for raw buffer access. | ||
bytes = new Buffer(MAX_BYTES); | ||
size = fs.readSync(descriptor, bytes, 0, bytes.length, 0); | ||
} finally { | ||
fs.closeSync(descriptor); | ||
} | ||
return isBinaryCheck(bytes, size); | ||
} | ||
else | ||
return isBinaryCheck(bytes, size); | ||
} |
{ | ||
"name": "isbinaryfile", | ||
"version" : "2.0.4", | ||
"description": "Detects if a file is binary in Node.js. Similar to Perl's -B.", | ||
"main" : "./lib/panino.js", | ||
"engines": { | ||
"node": ">=0.6.0" | ||
}, | ||
"maintainers": [{ | ||
"name": "Garen J. Torikian", | ||
"email": "gjtorikian@gmail.com" | ||
}], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/gjtorikian/isBinaryFile" | ||
}, | ||
"devDependencies" : { "mocha": "" }, | ||
"scripts": { | ||
"test": "mocha tests/test.js" | ||
"name": "isbinaryfile", | ||
"description": "Detects if a file is binary in Node.js. Similar to Perl's -B.", | ||
"version": "3.0.0", | ||
"devDependencies": { | ||
"mocha": "^2.2.4", | ||
"grunt": "~0.4.1", | ||
"grunt-release": "~0.6.0", | ||
"grunt-exec": "0.4.3", | ||
"grunt-cli": "~0.1.13" | ||
}, | ||
"engines": { | ||
"node": ">=0.6.0" | ||
}, | ||
"license": "MIT", | ||
"main": "./index.js", | ||
"maintainers": [ | ||
{ | ||
"name": "Garen J. Torikian", | ||
"email": "gjtorikian@gmail.com" | ||
} | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/gjtorikian/isBinaryFile" | ||
}, | ||
"scripts": { | ||
"test": "mocha" | ||
} | ||
} |
117
README.md
@@ -1,17 +0,12 @@ | ||
isBinaryFile | ||
============ | ||
# isBinaryFile | ||
Detects if a file is binary in Node.js. Similar to [Perl's `-B` switch](http://stackoverflow.com/questions/899206/how-does-perl-know-a-file-is-binary), | ||
in that: | ||
Detects if a file is binary in Node.js. Similar to [Perl's `-B` switch](http://stackoverflow.com/questions/899206/how-does-perl-know-a-file-is-binary), in that: | ||
- it reads the first few thousand bytes of a file | ||
- checks for a `null` byte; if it's found, it's binary | ||
- flags non-ASCII characters. After a certain number of "weird" characters, the file is flagged as binary | ||
* it reads the first few thousand bytes of a file | ||
* checks for a `null` byte; if it's found, it's binary | ||
* flags non-ASCII characters. After a certain number of "weird" characters, the | ||
file is flagged as binary | ||
Much of the logic is pretty much ported from [ag](https://github.com/ggreer/the_silver_searcher). | ||
All the logic is also pretty much ported from | ||
[ag](https://github.com/ggreer/the_silver_searcher). | ||
Note: if the file doesn't exist, is a directory, or is empty, the function returns `false`. | ||
Note: if the file doesn't exist or it is empty, this function returns `false`. | ||
## Installation | ||
@@ -25,7 +20,35 @@ | ||
If you pass in one argument, this module assumes it's just the file path, and | ||
performs the appropriate file read and stat functionality internally, as sync | ||
options: | ||
### isBinaryFile(filepath, callback) | ||
``` javascript | ||
* `filepath`, a `string` indicating the path to the file. | ||
* `callback`, a `function` for the callback. It has two arguments: | ||
- `err`, the typical Node.js error argument | ||
- `result`, a `boolean` of `true` or `false`, depending on if the file is binary | ||
### isBinaryFile(bytes, size, callback) | ||
* `bytes`, an `number` indicating the size of the file. | ||
* `size`, an optional `number` indicating the file size. | ||
* `callback`, a `function` for the callback. It has two arguments: | ||
- `err`, the typical Node.js error argument | ||
- `result`, a `boolean` of `true` or `false`, depending on if the file is binary | ||
### isBinaryFile.sync(filepath) | ||
* `filepath`, a `string` indicating the path to the file. | ||
### isBinaryFile.sync(bytes, size) | ||
* `bytes`, an `number` indicating the size of the file. | ||
* `size`, an `number` indicating the file size. | ||
Returns a `boolean` of `true` or `false`, depending on if the file is binary. | ||
### Examples | ||
```javascript | ||
var isBinaryFile = require("isbinaryfile"); | ||
@@ -37,11 +60,3 @@ | ||
console.log("No.") | ||
``` | ||
Ta da. | ||
However, if you've already read and `stat()`-ed a file (for some other reason), | ||
you can pass in both the file's raw data and the stat's `size` info to save | ||
time: | ||
```javascript | ||
fs.readFile(process.argv[2], function(err, data) { | ||
@@ -55,21 +70,6 @@ fs.lstat(process.argv[2], function(err, stat) { | ||
}); | ||
``` | ||
### Async | ||
Previous to version 2.0.0, this program always ran in sync mode. Now, there's | ||
an async option. Simply pass a function as your second parameter, and `isBinaryFile` | ||
will figure the rest out: | ||
``` javascript | ||
var isBinaryFile = require("isbinaryfile"); | ||
isBinaryFile(process.argv[2], function(err, result) { | ||
if (err) return console.error(err); | ||
if (result) | ||
console.log("It is!") | ||
else | ||
console.log("No.") | ||
} | ||
isBinaryFile.sync(process.argv[2]); // true or false | ||
var stat = fs.lstatSync(process.argv[2]); | ||
isBinaryFile.sync(process.argv[2], stat.size); // true or false | ||
``` | ||
@@ -79,33 +79,2 @@ | ||
Install mocha on your machine: | ||
``` | ||
npm install mocha -g | ||
``` | ||
Then run `npm test`. | ||
# MIT License | ||
Copyright (c) 2013 Garen J. Torikian | ||
Permission is hereby granted, free of charge, to any person | ||
obtaining a copy of this software and associated documentation | ||
files (the "Software"), to deal in the Software without | ||
restriction, including without limitation the rights to use, | ||
copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the | ||
Software is furnished to do so, subject to the following | ||
conditions: | ||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
OTHER DEALINGS IN THE SOFTWARE. | ||
Run `npm install` to install `mocha`, then run `npm test`. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
169943
30
259
5
77
2
1