Skip to content

Instantly share code, notes, and snippets.

@azu
Last active April 18, 2021 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save azu/eff893efcd12fa51bc691e50796f1eba to your computer and use it in GitHub Desktop.
Save azu/eff893efcd12fa51bc691e50796f1eba to your computer and use it in GitHub Desktop.
Validate image's binary mimetype on Node.js
const fs = require('fs');
const path = require('path');
const assert = require("assert");
const imageType = require('image-type');
const readChunk = require('read-chunk');
const isSvg = require('is-svg');
/**
* Validate image binary
* if it is ok, return undefined,
* if it is not ok, return an error object
* https://github.com/sindresorhus/image-type
* @param {Buffer} buffer
* @param {string[]} mimeTypes
* @returns {Error|undefined}
*/
function validateBinaryMIMEType(buffer, mimeTypes) {
assert.ok(Array.isArray(mimeTypes) && mimeTypes.every(mimeType => mimeType.includes("/")),
`Should be set an array of mimeType. e.g.) ['image/jpeg']`);
const result = imageType(buffer);
if (!result) {
return new Error("This buffer is not image");
}
const isAllowed = mimeTypes.includes(result.mime);
if (!isAllowed) {
return new Error(`This buffer is disallowed image: ${result.mime}`);
}
}
/**
* validae content of file path
* Careful: do check SVG also
* @param {string} filePath
* @param {string[]} mimeTypes
* @returns {Error|undefined}
* @example
*
* ```
* const validationResult = validateMIMEType("test.png", ['image/jpeg', 'image/gif', 'image/png', 'image/svg+xml']);
* if(validationResult) {
* console.error(validationResult)
* }
* ```
*/
function validateMIMEType(filePath, mimeTypes) {
// SVG is not binary, check at first
// https://github.com/sindresorhus/is-svg
const allowSVG = mimeTypes.includes("image/svg+xml");
const fileExt = path.extname(filePath);
if (allowSVG && fileExt === ".svg") {
const content = fs.readFileSync(filePath, "utf-8");
if (!isSvg(content)) {
return new Error(`This file is not svg`);
}
return;
}
// pick header of a binary
const buffer = readChunk.sync(filePath, 0, 12);
return validateBinaryMIMEType(buffer, mimeTypes);
}
module.exports.validateMIMEType = validateMIMEType;
module.exports.validateBinaryMIMEType = validateBinaryMIMEType;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment