Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

filevalidator

Package Overview
Dependencies
Maintainers
0
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

filevalidator - npm Package Compare versions

Comparing version 1.0.1 to 2.0.0

172

filevalidator.js

@@ -1,99 +0,87 @@

define([
'underscore',
],
'use strict';
function(_) {
'use strict';
// https://en.wikipedia.org/wiki/List_of_file_signatures
const fileSignatures = {
'mp3': [
// MPEG-1 Layer 3 file without an ID3 tag or with an ID3v1 tag (which's appended at the end of the file)
[0xFF, 0xFB],
// MP3 file with an ID3v2 container
[0x49, 0x44, 0x33],
// Other MP3 files (FF Fx and FF Ex – they may cause false-positives)
// Headers taken from https://www.garykessler.net/library/file_sigs.html
[0xFF, 0xE0], [0xFF, 0xE1], [0xFF, 0xE2], [0xFF, 0xE3], [0xFF, 0xE4],
[0xFF, 0xE5], [0xFF, 0xE6], [0xFF, 0xE7], [0xFF, 0xE8], [0xFF, 0xE9],
[0xFF, 0xEA], [0xFF, 0xEB], [0xFF, 0xEC], [0xFF, 0xED], [0xFF, 0xEE], [0xFF, 0xEF],
[0xFF, 0xF0], [0xFF, 0xF1], [0xFF, 0xF2], [0xFF, 0xF3], [0xFF, 0xF4],
[0xFF, 0xF5], [0xFF, 0xF6], [0xFF, 0xF7], [0xFF, 0xF8], [0xFF, 0xF9],
[0xFF, 0xFA], [0xFF, 0xFB], [0xFF, 0xFC], [0xFF, 0xFD], [0xFF, 0xFE], [0xFF, 0xFF]
],
'wav': [
// Waveform Audio File Format
// Empty slots can be any byte. Can't look at only first 4 or else .avi files match
[0x52, 0x49, 0x46, 0x46, , , , , 0x57, 0x41, 0x56, 0x45]
],
};
// https://en.wikipedia.org/wiki/List_of_file_signatures
var fileSignatures = {
'mp3': [
// MPEG-1 Layer 3 file without an ID3 tag or with an ID3v1 tag (which's appended at the end of the file)
[0xFF, 0xFB],
// MP3 file with an ID3v2 container
[0x49, 0x44, 0x33],
// Other MP3 files (FF Fx and FF Ex – they may cause false-positives)
// Headers taken from https://www.garykessler.net/library/file_sigs.html
[0xFF, 0xE0], [0xFF, 0xE1], [0xFF, 0xE2], [0xFF, 0xE3], [0xFF, 0xE4],
[0xFF, 0xE5], [0xFF, 0xE6], [0xFF, 0xE7], [0xFF, 0xE8], [0xFF, 0xE9],
[0xFF, 0xEA], [0xFF, 0xEB], [0xFF, 0xEC], [0xFF, 0xED], [0xFF, 0xEE], [0xFF, 0xEF],
[0xFF, 0xF0], [0xFF, 0xF1], [0xFF, 0xF2], [0xFF, 0xF3], [0xFF, 0xF4],
[0xFF, 0xF5], [0xFF, 0xF6], [0xFF, 0xF7], [0xFF, 0xF8], [0xFF, 0xF9],
[0xFF, 0xFA], [0xFF, 0xFB], [0xFF, 0xFC], [0xFF, 0xFD], [0xFF, 0xFE], [0xFF, 0xFF]
],
'wav': [
// Waveform Audio File Format
// Empty slots can be any byte. Can't look at only first 4 or else .avi files match
[0x52, 0x49, 0x46, 0x46, , , , , 0x57, 0x41, 0x56, 0x45]
],
};
/**
* Compare an Uint8Array with an expected file signature.
* Can't do a direct equality check since some signatures (e.gfor wav files) have wildcard slots.
* @param {array} sig - pattern from fileSignatures
* @param {Uint8Array} actual - bytes from file (should already be sliced to match length of sig)
* @returns {boolean} - do they match
*/
const compareSignature = function(sig, actual) {
if (sig.length !== actual.length) return false;
for (var i = 0, l = sig.length; i < l; i++) {
if (sig[i] !== actual[i] && typeof sig[i] !== 'undefined') return false;
}
return true;
};
/**
* Compare an Uint8Array with an expected file signature.
* Can't do a direct equality check since some signatures (e.gfor wav files) have wildcard slots.
* @param {array} sig - pattern from fileSignatures
* @param {Uint8Array} actual - bytes from file (should already be sliced to match length of sig)
* @returns {boolean} - do they match
*/
var compareSignature = function(sig, actual) {
if (sig.length !== actual.length) return false;
for (var i = 0, l = sig.length; i < l; i++) {
if (sig[i] !== actual[i] && typeof sig[i] !== 'undefined') return false;
}
return true;
};
/**
* @param {Uint8Array} uint8
* @param {string} type
* @returns {boolean}
*/
const matchesFileType = function(uint8, type) {
return fileSignatures[type].find(function(sig) {
return compareSignature(sig, uint8.subarray(0, sig.length));
});
};
/**
* @param {Uint8Array} uint8
* @param {string} type
* @returns {boolean}
*/
var matchesFileType = function(uint8, type) {
return _.find(fileSignatures[type], function(sig) {
return compareSignature(sig, uint8.subarray(0, sig.length));
});
};
/**
* Detect, through file signature / mime sniffing detection, if a given File
* matches an expected type or types. The types supported are the keys in
* fileSignatures above.
* @param {File} file
* @param {(string|string[])} types - e.g. 'mp3' or ['mp3', 'wav']
* @param {function} - callback which is passed a boolean
*/
const verifyFileType = function(file, types, cb) {
if (typeof types === 'string') types = [types];
/**
* Detect, through file signature / mime sniffing detection, if a given File
* matches an expected type or types. The types supported are the keys in
* fileSignatures above.
* @param {File} file
* @param {(string|string[])} types - e.g. 'mp3' or ['mp3', 'wav']
* @param {function} - callback which is passed a boolean
*/
var verifyFileType = function(file, types, cb) {
if (_.isString(types)) types = [types];
// Calculate the longest file signature for any of the requested
// types, so we know how many bytes of this file to look at.
const bytesNeeded = types.reduce(function(prevMax, type, idx, arr) {
var sigs = fileSignatures[type];
return Math.max.apply(this, [prevMax].concat(sigs.map(function(sig) {
return sig.length;
})));
}, 0);
// Calculate the longest file signature for any of the requested
// types, so we know how many bytes of this file to look at.
var bytesNeeded = types.reduce(function(prevMax, type, idx, arr) {
var sigs = fileSignatures[type];
return Math.max.apply(this, [prevMax].concat(sigs.map(function(sig) {
return sig.length;
})));
}, 0);
// Load file into ArrayBuffer and see if its first few bytes match
// the signature of any of our requested types. Let callback know.
const reader = new FileReader();
reader.addEventListener('load', function(e) {
// Load only as many bytes from the array buffer as necessary
var arrayBuffer = e.currentTarget.result;
var bytes = new Uint8Array(arrayBuffer, 0, bytesNeeded);
var match = _.find(types, function(type) {
return matchesFileType(bytes, type);
});
cb(match);
});
reader.readAsArrayBuffer(file);
};
// Load file into ArrayBuffer and see if its first few bytes match
// the signature of any of our requested types. Let callback know.
var reader = new FileReader();
reader.onload = function(e) {
// Load only as many bytes from the array buffer as necessary
var arrayBuffer = e.currentTarget.result;
var bytes = new Uint8Array(arrayBuffer, 0, bytesNeeded);
var match = _.find(types, function(type) {
return matchesFileType(bytes, type);
});
cb(match);
};
reader.readAsArrayBuffer(file);
};
// Expose public interface
var FileDetector = {
verifyFileType: verifyFileType
};
return FileDetector;
});
export { verifyFileType };
{
"name": "filevalidator",
"version": "1.0.1",
"version": "2.0.0",
"description": "File signature validation in JavaScript",
"type": "module",
"main": "filevalidator.js",
"author": "Phil Freo <phil@philfreo.com> (http://philfreo.com/)",
"license": "MIT"
}
}

@@ -11,19 +11,13 @@ # filevalidator.js

```js
define([
'filevalidator',
],
import { verifyFileType } from 'filevalidator';
function(filevalidator) {
const fileInput = document.getElementById('file-input');
var fileInput = document.getElementById('file-input');
fileInput.addEventListener('change', function(e) {
var file = e.currentTarget.files[0];
filevalidator.verifyFileType(file, ['mp3', 'wav'], function(valid) {
alert('Valid mp3 or wave file: ' + !!valid);
});
fileInput.addEventListener('change', function(e) {
const file = e.currentTarget.files[0];
verifyFileType(file, ['mp3', 'wav'], function(valid) {
alert('Valid mp3 or wave file: ' + !!valid);
});
});
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc