mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-09 15:55:01 -04:00
fixed some lint errors
This commit is contained in:
parent
78ba4d4fd3
commit
a980462d71
5 changed files with 84 additions and 68 deletions
|
@ -11,7 +11,7 @@ import {decodeQuotedPrintable} from "../lib/QuotedPrintable";
|
||||||
import {MIME_FORMAT} from "../lib/ChrEnc";
|
import {MIME_FORMAT} from "../lib/ChrEnc";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
|
|
||||||
|
// FIXME: files are a bit off on size.
|
||||||
/**
|
/**
|
||||||
* NOTE: Liberties taken include:
|
* NOTE: Liberties taken include:
|
||||||
* No checks are made to verify quoted words are valid encodings e.g. underscore vs escape
|
* No checks are made to verify quoted words are valid encodings e.g. underscore vs escape
|
||||||
|
@ -37,21 +37,22 @@ class Mime {
|
||||||
* @returns {File[]}
|
* @returns {File[]}
|
||||||
*/
|
*/
|
||||||
decodeMime(decodeWords) {
|
decodeMime(decodeWords) {
|
||||||
// TODO: content-type can be omitted and would mean us-ascii charset and text/plain.
|
|
||||||
if (!this.input) {
|
if (!this.input) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
let emlObj = Mime._splitParseHead(this.input);
|
const emlObj = Mime._splitParseHead(this.input);
|
||||||
if (!emlObj.body) { throw new OperationError("No body was found");}
|
if (!emlObj.body) {
|
||||||
|
throw new OperationError("No body was found");
|
||||||
|
}
|
||||||
if (decodeWords) {
|
if (decodeWords) {
|
||||||
emlObj.rawHeader = Mime.replaceEncodedWord(emlObj.rawHeader);
|
emlObj.rawHeader = Mime.replaceEncodedWord(emlObj.rawHeader);
|
||||||
}
|
}
|
||||||
let retval = [new File([emlObj.rawHeader], "Header", {type: "text/plain"})];
|
const retval = [new File([emlObj.rawHeader], "Header", {type: "text/plain"})];
|
||||||
this._walkMime(emlObj).forEach(function(fileObj){
|
this._walkMime(emlObj).forEach(function(fileObj){
|
||||||
let name = fileObj.name;
|
let name = fileObj.name;
|
||||||
if (fileObj.name === null) {
|
if (fileObj.name === null) {
|
||||||
if ("subject" in emlObj.header) {
|
if (emlObj.header.hasOwnProperty("subject")) {
|
||||||
name = emlObj.header["subject"][0];
|
name = emlObj.header.subject[0];
|
||||||
} else {
|
} else {
|
||||||
name = "Undefined";
|
name = "Undefined";
|
||||||
}
|
}
|
||||||
|
@ -62,6 +63,12 @@ class Mime {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple function to add a common file extention based on mime type string.
|
||||||
|
*
|
||||||
|
* @param {string} mimetype
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
static getFileExt(mimetype) {
|
static getFileExt(mimetype) {
|
||||||
switch (mimetype) {
|
switch (mimetype) {
|
||||||
case "text/plain":
|
case "text/plain":
|
||||||
|
@ -75,24 +82,23 @@ class Mime {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walks a MIME document and returns an array of Mime data and header objects.
|
* Walks a MIME document and returns an array of Mime data.
|
||||||
*
|
*
|
||||||
* @param {string} input
|
* @param {object} parentObj
|
||||||
* @param {object} header
|
|
||||||
* @returns {object[]}
|
* @returns {object[]}
|
||||||
*/
|
*/
|
||||||
_walkMime(parentObj) {
|
_walkMime(parentObj) {
|
||||||
let new_line_length = this.rn ? 2 : 1;
|
const newLineLength = this.rn ? 2 : 1;
|
||||||
let contType = null,
|
let contType = "text/plain",
|
||||||
fileName = null,
|
fileName = null,
|
||||||
charEnc = null,
|
charEnc = "us-ascii",
|
||||||
contDispoObj = null,
|
contDispoObj = null,
|
||||||
contTypeObj = null;
|
contTypeObj = null;
|
||||||
if (parentObj.header.hasOwnProperty("content-type")) {
|
if (parentObj.header.hasOwnProperty("content-type")) {
|
||||||
contTypeObj = Mime._decodeComplexField(parentObj.header["content-type"][0]);
|
contTypeObj = Mime._decodeComplexField(parentObj.header["content-type"][0]);
|
||||||
}
|
}
|
||||||
if (parentObj.header.hasOwnProperty("content-disposition")) {
|
if (parentObj.header.hasOwnProperty("content-disposition")) {
|
||||||
contDispoObj = Mime._decodeComplexField(parentObj.header["content-disposition"][0])
|
contDispoObj = Mime._decodeComplexField(parentObj.header["content-disposition"][0]);
|
||||||
if (contDispoObj != null && contDispoObj.hasOwnProperty("filename")) {
|
if (contDispoObj != null && contDispoObj.hasOwnProperty("filename")) {
|
||||||
fileName = contDispoObj.filename;
|
fileName = contDispoObj.filename;
|
||||||
}
|
}
|
||||||
|
@ -107,29 +113,23 @@ class Mime {
|
||||||
if (fileName == null && contTypeObj.hasOwnProperty("name")) {
|
if (fileName == null && contTypeObj.hasOwnProperty("name")) {
|
||||||
fileName = contTypeObj.name;
|
fileName = contTypeObj.name;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
contType = "text/plain";
|
|
||||||
charEnc = "us-ascii";
|
|
||||||
}
|
}
|
||||||
if (contType.startsWith("multipart/")) {
|
if (contType.startsWith("multipart/")) {
|
||||||
let output_sections = [];
|
const sections = [];
|
||||||
if (!contTypeObj.hasOwnProperty("boundary")) {
|
if (!contTypeObj.hasOwnProperty("boundary")) {
|
||||||
throw new OperationError("Invalid mulitpart section no boundary");
|
throw new OperationError("Invalid mulitpart section no boundary");
|
||||||
}
|
}
|
||||||
let mime_parts = this._splitMultipart(parentObj.body, contTypeObj.boundary, new_line_length);
|
const mimeParts = this._splitMultipart(parentObj.body, contTypeObj.boundary, newLineLength);
|
||||||
mime_parts.forEach(function(mime_part){
|
mimeParts.forEach(function(mimePart){
|
||||||
let mimeObj = Mime._splitParseHead(mime_part);
|
const mimeObj = Mime._splitParseHead(mimePart);
|
||||||
if (!mimeObj.body) {
|
if (mimeObj) {
|
||||||
return [];
|
this._walkMime(mimeObj).forEach(part => sections.push(part));
|
||||||
}
|
}
|
||||||
this._walkMime(mimeObj).forEach(function(part){
|
|
||||||
output_sections.push(part);
|
|
||||||
}, this);
|
|
||||||
}, this);
|
}, this);
|
||||||
return output_sections;
|
return sections;
|
||||||
}
|
}
|
||||||
if (parentObj.header.hasOwnProperty("content-transfer-encoding")) {
|
if (parentObj.header.hasOwnProperty("content-transfer-encoding")) {
|
||||||
let contEncObj = Mime._decodeComplexField(parentObj.header["content-transfer-encoding"][0]);
|
const contEncObj = Mime._decodeComplexField(parentObj.header["content-transfer-encoding"][0]);
|
||||||
if (contEncObj != null && contEncObj.hasOwnProperty("value")) {
|
if (contEncObj != null && contEncObj.hasOwnProperty("value")) {
|
||||||
parentObj.body = Mime._decodeMimeData(parentObj.body, charEnc, contEncObj.value[0]);
|
parentObj.body = Mime._decodeMimeData(parentObj.body, charEnc, contEncObj.value[0]);
|
||||||
}
|
}
|
||||||
|
@ -165,21 +165,22 @@ class Mime {
|
||||||
*/
|
*/
|
||||||
static _splitParseHead(input) {
|
static _splitParseHead(input) {
|
||||||
const emlRegex = /(?:\r?\n){2}/g;
|
const emlRegex = /(?:\r?\n){2}/g;
|
||||||
let matchobj = emlRegex.exec(input);
|
const matchObj = emlRegex.exec(input);
|
||||||
if (matchobj) {
|
if (matchObj) {
|
||||||
let splitEmail = [input.substring(0,matchobj.index), input.substring(emlRegex.lastIndex)];
|
const splitEmail = [input.substring(0, matchObj.index), input.substring(emlRegex.lastIndex)];
|
||||||
const sectionRegex = /([A-Za-z-]+):\s+([\x00-\xff]+?)(?=$|\r?\n\S)/g;
|
const sectionRegex = /([A-Za-z-]+):\s+([\x00-\xff]+?)(?=$|\r?\n\S)/g;
|
||||||
let headerObj = {}, section;
|
const headerObj = {};
|
||||||
|
let section;
|
||||||
while ((section = sectionRegex.exec(splitEmail[0]))) {
|
while ((section = sectionRegex.exec(splitEmail[0]))) {
|
||||||
let fieldName = section[1].toLowerCase();
|
const fieldName = section[1].toLowerCase();
|
||||||
let fieldValue = Mime.replaceEncodedWord(section[2].replace(/\n|\r/g, " "));
|
const fieldValue = Mime.replaceEncodedWord(section[2].replace(/\n|\r/g, " "));
|
||||||
if (fieldName in headerObj) {
|
if (fieldName in headerObj) {
|
||||||
headerObj[fieldName].push(fieldValue);
|
headerObj[fieldName].push(fieldValue);
|
||||||
} else {
|
} else {
|
||||||
headerObj[fieldName] = [fieldValue];
|
headerObj[fieldName] = [fieldValue];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {rawHeader:splitEmail[0], body: splitEmail[1], header: headerObj};
|
return {rawHeader: splitEmail[0], body: splitEmail[1], header: headerObj};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -215,30 +216,29 @@ class Mime {
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
static _decodeComplexField(field) {
|
static _decodeComplexField(field) {
|
||||||
let fieldSplit = field.split(/;\s+/g);
|
const fieldSplit = field.split(/;\s+/g);
|
||||||
let retVal = {};
|
const retVal = {};
|
||||||
fieldSplit.forEach(function(item){
|
fieldSplit.forEach(function(item){
|
||||||
let eq = item.indexOf("=");
|
const eq = item.indexOf("=");
|
||||||
if (eq >= 0) {
|
if (eq >= 0) {
|
||||||
if (item.length > eq) {
|
if (item.length > eq) {
|
||||||
let kv = [item.substring(0, eq), item.substring(eq + 1).trim()];
|
const kv = [item.substring(0, eq), item.substring(eq + 1).trim()];
|
||||||
if ((kv[1].startsWith("\'") && kv[1].endsWith("\'"))
|
if ((kv[1].startsWith("'") && kv[1].endsWith("'")) || (kv[1].startsWith("\"") && kv[1].endsWith("\""))) {
|
||||||
|| (kv[1].startsWith("\"") && kv[1].endsWith("\""))) {
|
|
||||||
kv[1] = (/(['"])(.+)\1/.exec(kv[1]))[2];
|
kv[1] = (/(['"])(.+)\1/.exec(kv[1]))[2];
|
||||||
}
|
}
|
||||||
retVal[kv[0].toLowerCase()] = kv[1];
|
this[kv[0].toLowerCase()] = kv[1];
|
||||||
} else {
|
} else {
|
||||||
throw OperationError("Not a valid header entry");
|
throw OperationError("Not a valid header entry");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
item = item.trim().toLowerCase();
|
item = item.trim().toLowerCase();
|
||||||
if (retVal.hasOwnProperty("value")) {
|
if (this.hasOwnProperty("value")) {
|
||||||
retVal.value.push(item);
|
this.value.push(item);
|
||||||
} else {
|
} else {
|
||||||
retVal.value = [item];
|
this.value = [item];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, retVal);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,25 +248,27 @@ class Mime {
|
||||||
*
|
*
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {string} boundary
|
* @param {string} boundary
|
||||||
* @param {string} new_line_length
|
* @param {string} newLineLength
|
||||||
* @return {string[]}
|
* @return {string[]}
|
||||||
*/
|
*/
|
||||||
_splitMultipart(input, boundary, new_line_length) {
|
_splitMultipart(input, boundary, newLineLength) {
|
||||||
let output = [];
|
const output = [];
|
||||||
const boundary_str = "--".concat(boundary, this.rn ? "\r\n" : "\n");
|
const boundaryStr = "--".concat(boundary, this.rn ? "\r\n" : "\n");
|
||||||
let last = input.indexOf("--".concat(boundary, "--")) - new_line_length;
|
const last = input.indexOf("--".concat(boundary, "--")) - newLineLength;
|
||||||
let start = 0;
|
for (;;) {
|
||||||
while(true) {
|
let start = input.indexOf(boundaryStr, start);
|
||||||
let start = input.indexOf(boundary_str, start);
|
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
start = start + boundary_str.length;
|
start += boundaryStr.length;
|
||||||
let end = input.indexOf(boundary_str, start) - new_line_length;
|
const end = input.indexOf(boundaryStr, start) - newLineLength;
|
||||||
if (end <= start) {
|
if (end <= start) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
output.push(input.substring(start, end));
|
output.push(input.substring(start, end));
|
||||||
|
if (end === last) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import OperationError from "../errors/OperationError";
|
|
||||||
import Mime from "../lib/Mime";
|
import Mime from "../lib/Mime";
|
||||||
import Utils from "../Utils";
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation for Finding and replacing Mime encoded words.
|
||||||
|
*/
|
||||||
class DecodeMimeEncodedWords extends Operation {
|
class DecodeMimeEncodedWords extends Operation {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,8 +20,7 @@ class DecodeMimeEncodedWords extends Operation {
|
||||||
this.name = "Decode Mime Encoded Words";
|
this.name = "Decode Mime Encoded Words";
|
||||||
this.module = "Default";
|
this.module = "Default";
|
||||||
this.description = ["Parser an IMF formatted messages following RFC5322.",
|
this.description = ["Parser an IMF formatted messages following RFC5322.",
|
||||||
"<br><br>",
|
"<br><br>", "Parses an IMF formated message. These often have the file extention ".eml"e; and contain the email headers and body. The output will be a file list of the headers and mime parts.",
|
||||||
"Parses an IMF formated message. These often have the file extention ".eml"e; and contain the email headers and body. The output will be a file list of the headers and mime parts.",
|
|
||||||
].join("\n");
|
].join("\n");
|
||||||
this.infoURL = "https://tools.ietf.org/html/rfc2047";
|
this.infoURL = "https://tools.ietf.org/html/rfc2047";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
|
@ -28,6 +28,13 @@ class DecodeMimeEncodedWords extends Operation {
|
||||||
this.args = [];
|
this.args = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
return Mime.replaceEncodedWord(input);
|
return Mime.replaceEncodedWord(input);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import {decodeQuotedPrintable} from "../lib/QuotedPrintable"
|
import {decodeQuotedPrintable} from "../lib/QuotedPrintable";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From Quoted Printable operation
|
* From Quoted Printable operation
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import OperationError from "../errors/OperationError";
|
|
||||||
import Mime from "../lib/Mime";
|
import Mime from "../lib/Mime";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
class ParseIMF extends Operation {
|
class ParseIMF extends Operation {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,8 +21,8 @@ class ParseIMF extends Operation {
|
||||||
this.name = "Parse Internet Message Format";
|
this.name = "Parse Internet Message Format";
|
||||||
this.module = "Default";
|
this.module = "Default";
|
||||||
this.description = ["Parse an IMF formatted messages following RFC5322.",
|
this.description = ["Parse an IMF formatted messages following RFC5322.",
|
||||||
"<br><br>",
|
"<br><br>",
|
||||||
"Parses an IMF formated message. These often have the file extention ".eml"e; and contain the email headers and body. The output will be a file list of the root header and decoded mime parts.",
|
"Parses an IMF formated message. These often have the file extention ".eml"e; and contain the email headers and body. The output will be a file list of the root header and decoded mime parts.",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
this.infoURL = "https://tools.ietf.org/html/rfc5322";
|
this.infoURL = "https://tools.ietf.org/html/rfc5322";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
|
@ -35,9 +37,16 @@ class ParseIMF extends Operation {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
let mimeObj = new Mime(input);
|
//let mimeObj = new Mime(input);
|
||||||
return mimeObj.decodeMime(args[0]);
|
return new Mime(input).decodeMime(args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue