CyberChef/src/core/operations/JS.js

165 lines
3.6 KiB
JavaScript
Raw Normal View History

2017-07-24 15:49:16 +02:00
import * as esprima from "esprima";
import escodegen from "escodegen";
import esmangle from "esmangle";
2016-11-28 11:42:58 +01:00
/**
* JavaScript operations.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*
* @namespace
*/
const JS = {
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/**
* @constant
* @default
*/
PARSE_LOC: false,
/**
* @constant
* @default
*/
PARSE_RANGE: false,
/**
* @constant
* @default
*/
PARSE_TOKENS: false,
/**
* @constant
* @default
*/
PARSE_COMMENT: false,
/**
* @constant
* @default
*/
PARSE_TOLERANT: false,
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/**
* JavaScript Parser operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
runParse: function (input, args) {
2017-04-13 19:08:50 +02:00
let parseLoc = args[0],
parseRange = args[1],
parseTokens = args[2],
parseComment = args[3],
parseTolerant = args[4],
2016-11-28 11:42:58 +01:00
result = {},
options = {
loc: parseLoc,
range: parseRange,
tokens: parseTokens,
comment: parseComment,
tolerant: parseTolerant
2016-11-28 11:42:58 +01:00
};
2017-02-09 16:09:33 +01:00
2017-07-24 15:49:16 +02:00
result = esprima.parseScript(input, options);
2016-11-28 11:42:58 +01:00
return JSON.stringify(result, null, 2);
},
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/**
* @constant
* @default
*/
BEAUTIFY_INDENT: "\\t",
/**
* @constant
* @default
*/
BEAUTIFY_QUOTES: ["Auto", "Single", "Double"],
/**
* @constant
* @default
*/
BEAUTIFY_SEMICOLONS: true,
/**
* @constant
* @default
*/
BEAUTIFY_COMMENT: true,
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/**
* JavaScript Beautify operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
runBeautify: function(input, args) {
2017-04-13 19:08:50 +02:00
let beautifyIndent = args[0] || JS.BEAUTIFY_INDENT,
2016-11-28 11:42:58 +01:00
quotes = args[1].toLowerCase(),
beautifySemicolons = args[2],
beautifyComment = args[3],
2016-11-28 11:42:58 +01:00
result = "",
AST;
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
try {
2017-07-24 15:49:16 +02:00
AST = esprima.parseScript(input, {
2016-11-28 11:42:58 +01:00
range: true,
tokens: true,
comment: true
});
2017-02-09 16:09:33 +01:00
2017-04-13 19:08:50 +02:00
const options = {
2016-11-28 11:42:58 +01:00
format: {
indent: {
style: beautifyIndent
2016-11-28 11:42:58 +01:00
},
quotes: quotes,
semicolons: beautifySemicolons,
2016-11-28 11:42:58 +01:00
},
comment: beautifyComment
2016-11-28 11:42:58 +01:00
};
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
if (options.comment)
AST = escodegen.attachComments(AST, AST.comments, AST.tokens);
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
result = escodegen.generate(AST, options);
2017-02-09 16:09:33 +01:00
} catch (e) {
2016-11-28 11:42:58 +01:00
// Leave original error so the user can see the detail
throw "Unable to parse JavaScript.<br>" + e.message;
}
return result;
},
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/**
* JavaScript Minify operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
runMinify: function(input, args) {
2017-04-13 19:08:50 +02:00
let result = "",
2017-07-24 15:49:16 +02:00
AST = esprima.parseScript(input),
optimisedAST = esmangle.optimize(AST, null),
mangledAST = esmangle.mangle(optimisedAST);
2017-02-09 16:09:33 +01:00
result = escodegen.generate(mangledAST, {
2016-11-28 11:42:58 +01:00
format: {
renumber: true,
hexadecimal: true,
escapeless: true,
compact: true,
semicolons: false,
parentheses: false
}
});
return result;
},
};
export default JS;