ESM: Added remaining Base64 ops and created a Base64 library. Added the prefer-const eslint rule.

This commit is contained in:
n1474335 2018-04-02 17:10:51 +01:00
parent 9b4fc3d3aa
commit 041cd9fb8e
30 changed files with 986 additions and 825 deletions

View File

@ -1 +1,2 @@
src/core/vendor/** src/core/vendor/**
src/core/operations/legacy/**

View File

@ -1,6 +1,6 @@
{ {
"parserOptions": { "parserOptions": {
"ecmaVersion": 8, "ecmaVersion": 9,
"ecmaFeatures": { "ecmaFeatures": {
"impliedStrict": true "impliedStrict": true
}, },
@ -84,7 +84,8 @@
"no-whitespace-before-property": "error", "no-whitespace-before-property": "error",
"operator-linebreak": ["error", "after"], "operator-linebreak": ["error", "after"],
"space-in-parens": "error", "space-in-parens": "error",
"no-var": "error" "no-var": "error",
"prefer-const": "error"
}, },
"globals": { "globals": {
"$": false, "$": false,

View File

@ -117,7 +117,7 @@ module.exports = function (grunt) {
* Generates an entry list for all the modules. * Generates an entry list for all the modules.
*/ */
function listEntryModules() { function listEntryModules() {
let entryModules = {}; const entryModules = {};
glob.sync("./src/core/config/modules/*.mjs").forEach(file => { glob.sync("./src/core/config/modules/*.mjs").forEach(file => {
const basename = path.basename(file); const basename = path.basename(file);

View File

@ -121,9 +121,9 @@ class Chef {
silentBake(recipeConfig) { silentBake(recipeConfig) {
log.debug("Running silent bake"); log.debug("Running silent bake");
let startTime = new Date().getTime(), const startTime = new Date().getTime(),
recipe = new Recipe(recipeConfig), recipe = new Recipe(recipeConfig),
dish = new Dish("", Dish.STRING); dish = new Dish("", Dish.STRING);
try { try {
recipe.execute(dish); recipe.execute(dish);

View File

@ -132,7 +132,7 @@ function silentBake(data) {
*/ */
function loadRequiredModules(recipeConfig) { function loadRequiredModules(recipeConfig) {
recipeConfig.forEach(op => { recipeConfig.forEach(op => {
let module = self.OperationConfig[op.op].module; const module = self.OperationConfig[op.op].module;
if (!OpModules.hasOwnProperty(module)) { if (!OpModules.hasOwnProperty(module)) {
log.info("Loading module " + module); log.info("Loading module " + module);

View File

@ -23,7 +23,7 @@ const FlowControl = {
* @returns {Object} The updated state of the recipe. * @returns {Object} The updated state of the recipe.
*/ */
runFork: async function(state) { runFork: async function(state) {
let opList = state.opList, const opList = state.opList,
inputType = opList[state.progress].inputType, inputType = opList[state.progress].inputType,
outputType = opList[state.progress].outputType, outputType = opList[state.progress].outputType,
input = state.dish.get(inputType), input = state.dish.get(inputType),
@ -31,8 +31,8 @@ const FlowControl = {
splitDelim = ings[0], splitDelim = ings[0],
mergeDelim = ings[1], mergeDelim = ings[1],
ignoreErrors = ings[2], ignoreErrors = ings[2],
subOpList = [], subOpList = [];
inputs = [], let inputs = [],
i; i;
if (input) if (input)
@ -48,8 +48,8 @@ const FlowControl = {
} }
} }
let recipe = new Recipe(), const recipe = new Recipe();
output = "", let output = "",
progress = 0; progress = 0;
state.forkOffset += state.progress + 1; state.forkOffset += state.progress + 1;
@ -223,7 +223,7 @@ const FlowControl = {
} }
if (regexStr !== "") { if (regexStr !== "") {
let strMatch = dish.get(Dish.STRING).search(regexStr) > -1; const strMatch = dish.get(Dish.STRING).search(regexStr) > -1;
if (!invert && strMatch || invert && !strMatch) { if (!invert && strMatch || invert && !strMatch) {
state.progress = jmpIndex; state.progress = jmpIndex;
state.numJumps++; state.numJumps++;
@ -274,9 +274,9 @@ const FlowControl = {
*/ */
_getLabelIndex: function(name, state) { _getLabelIndex: function(name, state) {
for (let o = 0; o < state.opList.length; o++) { for (let o = 0; o < state.opList.length; o++) {
let operation = state.opList[o]; const operation = state.opList[o];
if (operation.name === "Label"){ if (operation.name === "Label"){
let ings = operation.ingValues; const ings = operation.ingValues;
if (name === ings[0]) { if (name === ings[0]) {
return o; return o;
} }

View File

@ -226,7 +226,7 @@ class Recipe {
const highlights = []; const highlights = [];
for (let i = 0; i < this.opList.length; i++) { for (let i = 0; i < this.opList.length; i++) {
let op = this.opList[i]; const op = this.opList[i];
if (op.disabled) continue; if (op.disabled) continue;
// If any breakpoints are set, do not attempt to highlight // If any breakpoints are set, do not attempt to highlight

View File

@ -6,6 +6,7 @@
import utf8 from "utf8"; import utf8 from "utf8";
import moment from "moment-timezone"; import moment from "moment-timezone";
import {fromBase64} from "./lib/Base64";
/** /**
@ -270,7 +271,7 @@ class Utils {
if (i < alphStr.length - 2 && if (i < alphStr.length - 2 &&
alphStr[i+1] === "-" && alphStr[i+1] === "-" &&
alphStr[i] !== "\\") { alphStr[i] !== "\\") {
let start = Utils.ord(alphStr[i]), const start = Utils.ord(alphStr[i]),
end = Utils.ord(alphStr[i+2]); end = Utils.ord(alphStr[i+2]);
for (let j = start; j <= end; j++) { for (let j = start; j <= end; j++) {
@ -313,7 +314,7 @@ class Utils {
case "hex": case "hex":
return Utils.fromHex(str); return Utils.fromHex(str);
case "base64": case "base64":
return Utils.fromBase64(str, null, "byteArray"); return fromBase64(str, null, "byteArray");
case "utf8": case "utf8":
return Utils.strToUtf8ByteArray(str); return Utils.strToUtf8ByteArray(str);
case "latin1": case "latin1":
@ -346,7 +347,7 @@ class Utils {
case "hex": case "hex":
return Utils.byteArrayToChars(Utils.fromHex(str)); return Utils.byteArrayToChars(Utils.fromHex(str));
case "base64": case "base64":
return Utils.byteArrayToChars(Utils.fromBase64(str, null, "byteArray")); return Utils.byteArrayToChars(fromBase64(str, null, "byteArray"));
case "utf8": case "utf8":
return utf8.encode(str); return utf8.encode(str);
case "latin1": case "latin1":
@ -518,118 +519,6 @@ class Utils {
} }
/**
* Base64's the input byte array using the given alphabet, returning a string.
*
* @param {byteArray|Uint8Array|string} data
* @param {string} [alphabet="A-Za-z0-9+/="]
* @returns {string}
*
* @example
* // returns "SGVsbG8="
* Utils.toBase64([72, 101, 108, 108, 111]);
*
* // returns "SGVsbG8="
* Utils.toBase64("Hello");
*/
static toBase64(data, alphabet="A-Za-z0-9+/=") {
if (!data) return "";
if (typeof data == "string") {
data = Utils.strToByteArray(data);
}
alphabet = Utils.expandAlphRange(alphabet).join("");
let output = "",
chr1, chr2, chr3,
enc1, enc2, enc3, enc4,
i = 0;
while (i < data.length) {
chr1 = data[i++];
chr2 = data[i++];
chr3 = data[i++];
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) +
alphabet.charAt(enc3) + alphabet.charAt(enc4);
}
return output;
}
/**
* UnBase64's the input string using the given alphabet, returning a byte array.
*
* @param {byteArray} data
* @param {string} [alphabet="A-Za-z0-9+/="]
* @param {string} [returnType="string"] - Either "string" or "byteArray"
* @param {boolean} [removeNonAlphChars=true]
* @returns {byteArray}
*
* @example
* // returns "Hello"
* Utils.fromBase64("SGVsbG8=");
*
* // returns [72, 101, 108, 108, 111]
* Utils.fromBase64("SGVsbG8=", null, "byteArray");
*/
static fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true) {
if (!data) {
return returnType === "string" ? "" : [];
}
alphabet = Utils.expandAlphRange(alphabet).join("");
let output = [],
chr1, chr2, chr3,
enc1, enc2, enc3, enc4,
i = 0;
if (removeNonAlphChars) {
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
data = data.replace(re, "");
}
while (i < data.length) {
enc1 = alphabet.indexOf(data.charAt(i++));
enc2 = alphabet.indexOf(data.charAt(i++) || "=");
enc3 = alphabet.indexOf(data.charAt(i++) || "=");
enc4 = alphabet.indexOf(data.charAt(i++) || "=");
enc2 = enc2 === -1 ? 64 : enc2;
enc3 = enc3 === -1 ? 64 : enc3;
enc4 = enc4 === -1 ? 64 : enc4;
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output.push(chr1);
if (enc3 !== 64) {
output.push(chr2);
}
if (enc4 !== 64) {
output.push(chr3);
}
}
return returnType === "string" ? Utils.byteArrayToUtf8(output) : output;
}
/** /**
* Convert a byte array into a hex string. * Convert a byte array into a hex string.
* *
@ -734,8 +623,8 @@ class Utils {
ignoreNext = false, ignoreNext = false,
inString = false, inString = false,
cell = "", cell = "",
line = [], line = [];
lines = []; const lines = [];
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
b = data[i]; b = data[i];
@ -952,10 +841,9 @@ class Utils {
// Parse bespoke recipe format // Parse bespoke recipe format
recipe = recipe.replace(/\n/g, ""); recipe = recipe.replace(/\n/g, "");
let m, let m, args;
recipeRegex = /([^(]+)\(((?:'[^'\\]*(?:\\.[^'\\]*)*'|[^)/'])*)(\/[^)]+)?\)/g, const recipeRegex = /([^(]+)\(((?:'[^'\\]*(?:\\.[^'\\]*)*'|[^)/'])*)(\/[^)]+)?\)/g,
recipeConfig = [], recipeConfig = [];
args;
while ((m = recipeRegex.exec(recipe))) { while ((m = recipeRegex.exec(recipe))) {
// Translate strings in args back to double-quotes // Translate strings in args back to double-quotes
@ -966,7 +854,7 @@ class Utils {
.replace(/\\'/g, "'"); // Unescape single quotes .replace(/\\'/g, "'"); // Unescape single quotes
args = "[" + args + "]"; args = "[" + args + "]";
let op = { const op = {
op: m[1].replace(/_/g, " "), op: m[1].replace(/_/g, " "),
args: JSON.parse(args) args: JSON.parse(args)
}; };
@ -1252,7 +1140,7 @@ export default Utils;
* ["One", "Two", "Three", "One"].unique(); * ["One", "Two", "Three", "One"].unique();
*/ */
Array.prototype.unique = function() { Array.prototype.unique = function() {
let u = {}, a = []; const u = {}, a = [];
for (let i = 0, l = this.length; i < l; i++) { for (let i = 0, l = this.length; i < l; i++) {
if (u.hasOwnProperty(this[i])) { if (u.hasOwnProperty(this[i])) {
continue; continue;

View File

@ -21,340 +21,340 @@ const Categories = [
{ {
name: "Favourites", name: "Favourites",
ops: [] ops: []
}/*, },
{ {
name: "Data format", name: "Data format",
ops: [ ops: [
"To Hexdump", // "To Hexdump",
"From Hexdump", // "From Hexdump",
"To Hex", // "To Hex",
"From Hex", // "From Hex",
"To Charcode", // "To Charcode",
"From Charcode", // "From Charcode",
"To Decimal", // "To Decimal",
"From Decimal", // "From Decimal",
"To Binary", // "To Binary",
"From Binary", // "From Binary",
"To Octal", // "To Octal",
"From Octal", // "From Octal",
"To Base64", "To Base64",
"From Base64", "From Base64",
"Show Base64 offsets", "Show Base64 offsets",
"To Base32", "To Base32",
"From Base32", "From Base32",
"To Base58", // "To Base58",
"From Base58", // "From Base58",
"To Base", // "To Base",
"From Base", // "From Base",
"To BCD", // "To BCD",
"From BCD", // "From BCD",
"To HTML Entity", // "To HTML Entity",
"From HTML Entity", // "From HTML Entity",
"URL Encode", // "URL Encode",
"URL Decode", // "URL Decode",
"Escape Unicode Characters", // "Escape Unicode Characters",
"Unescape Unicode Characters", // "Unescape Unicode Characters",
"To Quoted Printable", // "To Quoted Printable",
"From Quoted Printable", // "From Quoted Printable",
"To Punycode", // "To Punycode",
"From Punycode", // "From Punycode",
"To Hex Content", // "To Hex Content",
"From Hex Content", // "From Hex Content",
"PEM to Hex", // "PEM to Hex",
"Hex to PEM", // "Hex to PEM",
"Parse ASN.1 hex string", // "Parse ASN.1 hex string",
"Change IP format", // "Change IP format",
"Encode text", // "Encode text",
"Decode text", // "Decode text",
"Swap endianness", // "Swap endianness",
// ]
// },
// {
// name: "Encryption / Encoding",
// ops: [
// "AES Encrypt",
// "AES Decrypt",
// "Blowfish Encrypt",
// "Blowfish Decrypt",
// "DES Encrypt",
// "DES Decrypt",
// "Triple DES Encrypt",
// "Triple DES Decrypt",
// "RC2 Encrypt",
// "RC2 Decrypt",
// "RC4",
// "RC4 Drop",
// "ROT13",
// "ROT47",
// "XOR",
// "XOR Brute Force",
// "Vigenère Encode",
// "Vigenère Decode",
// "To Morse Code",
// "From Morse Code",
// "Bifid Cipher Encode",
// "Bifid Cipher Decode",
// "Affine Cipher Encode",
// "Affine Cipher Decode",
// "Atbash Cipher",
// "Substitute",
// "Derive PBKDF2 key",
// "Derive EVP key",
// "Bcrypt",
// "Scrypt",
// "Pseudo-Random Number Generator",
] ]
}, },
{ // {
name: "Encryption / Encoding", // name: "Public Key",
ops: [ // ops: [
"AES Encrypt", // "Parse X.509 certificate",
"AES Decrypt", // "Parse ASN.1 hex string",
"Blowfish Encrypt", // "PEM to Hex",
"Blowfish Decrypt", // "Hex to PEM",
"DES Encrypt", // "Hex to Object Identifier",
"DES Decrypt", // "Object Identifier to Hex",
"Triple DES Encrypt", // ]
"Triple DES Decrypt", // },
"RC2 Encrypt", // {
"RC2 Decrypt", // name: "Arithmetic / Logic",
"RC4", // ops: [
"RC4 Drop", // "XOR",
"ROT13", // "XOR Brute Force",
"ROT47", // "OR",
"XOR", // "NOT",
"XOR Brute Force", // "AND",
"Vigenère Encode", // "ADD",
"Vigenère Decode", // "SUB",
"To Morse Code", // "Sum",
"From Morse Code", // "Subtract",
"Bifid Cipher Encode", // "Multiply",
"Bifid Cipher Decode", // "Divide",
"Affine Cipher Encode", // "Mean",
"Affine Cipher Decode", // "Median",
"Atbash Cipher", // "Standard Deviation",
"Substitute", // "Bit shift left",
"Derive PBKDF2 key", // "Bit shift right",
"Derive EVP key", // "Rotate left",
"Bcrypt", // "Rotate right",
"Scrypt", // "ROT13",
"Pseudo-Random Number Generator", // ]
] // },
}, // {
{ // name: "Networking",
name: "Public Key", // ops: [
ops: [ // "HTTP request",
"Parse X.509 certificate", // "Strip HTTP headers",
"Parse ASN.1 hex string", // "Parse User Agent",
"PEM to Hex", // "Parse IP range",
"Hex to PEM", // "Parse IPv6 address",
"Hex to Object Identifier", // "Parse IPv4 header",
"Object Identifier to Hex", // "Parse URI",
] // "URL Encode",
}, // "URL Decode",
{ // "Format MAC addresses",
name: "Arithmetic / Logic", // "Change IP format",
ops: [ // "Group IP addresses",
"XOR", // "Encode NetBIOS Name",
"XOR Brute Force", // "Decode NetBIOS Name",
"OR", // ]
"NOT", // },
"AND", // {
"ADD", // name: "Language",
"SUB", // ops: [
"Sum", // "Encode text",
"Subtract", // "Decode text",
"Multiply", // "Unescape Unicode Characters",
"Divide", // ]
"Mean", // },
"Median", // {
"Standard Deviation", // name: "Utils",
"Bit shift left", // ops: [
"Bit shift right", // "Diff",
"Rotate left", // "Remove whitespace",
"Rotate right", // "Remove null bytes",
"ROT13", // "To Upper case",
] // "To Lower case",
}, // "Add line numbers",
{ // "Remove line numbers",
name: "Networking", // "Reverse",
ops: [ // "Sort",
"HTTP request", // "Unique",
"Strip HTTP headers", // "Split",
"Parse User Agent", // "Filter",
"Parse IP range", // "Head",
"Parse IPv6 address", // "Tail",
"Parse IPv4 header", // "Count occurrences",
"Parse URI", // "Expand alphabet range",
"URL Encode", // "Drop bytes",
"URL Decode", // "Take bytes",
"Format MAC addresses", // "Pad lines",
"Change IP format", // "Find / Replace",
"Group IP addresses", // "Regular expression",
"Encode NetBIOS Name", // "Offset checker",
"Decode NetBIOS Name", // "Hamming Distance",
] // "Convert distance",
}, // "Convert area",
{ // "Convert mass",
name: "Language", // "Convert speed",
ops: [ // "Convert data units",
"Encode text", // "Parse UNIX file permissions",
"Decode text", // "Swap endianness",
"Unescape Unicode Characters", // "Parse colour code",
] // "Escape string",
}, // "Unescape string",
{ // "Pseudo-Random Number Generator",
name: "Utils", // "Sleep",
ops: [ // ]
"Diff", // },
"Remove whitespace", // {
"Remove null bytes", // name: "Date / Time",
"To Upper case", // ops: [
"To Lower case", // "Parse DateTime",
"Add line numbers", // "Translate DateTime Format",
"Remove line numbers", // "From UNIX Timestamp",
"Reverse", // "To UNIX Timestamp",
"Sort", // "Windows Filetime to UNIX Timestamp",
"Unique", // "UNIX Timestamp to Windows Filetime",
"Split", // "Extract dates",
"Filter", // "Sleep",
"Head", // ]
"Tail", // },
"Count occurrences", // {
"Expand alphabet range", // name: "Extractors",
"Drop bytes", // ops: [
"Take bytes", // "Strings",
"Pad lines", // "Extract IP addresses",
"Find / Replace", // "Extract email addresses",
"Regular expression", // "Extract MAC addresses",
"Offset checker", // "Extract URLs",
"Hamming Distance", // "Extract domains",
"Convert distance", // "Extract file paths",
"Convert area", // "Extract dates",
"Convert mass", // "Regular expression",
"Convert speed", // "XPath expression",
"Convert data units", // "JPath expression",
"Parse UNIX file permissions", // "CSS selector",
"Swap endianness", // "Extract EXIF",
"Parse colour code", // ]
"Escape string", // },
"Unescape string", // {
"Pseudo-Random Number Generator", // name: "Compression",
"Sleep", // ops: [
] // "Raw Deflate",
}, // "Raw Inflate",
{ // "Zlib Deflate",
name: "Date / Time", // "Zlib Inflate",
ops: [ // "Gzip",
"Parse DateTime", // "Gunzip",
"Translate DateTime Format", // "Zip",
"From UNIX Timestamp", // "Unzip",
"To UNIX Timestamp", // "Bzip2 Decompress",
"Windows Filetime to UNIX Timestamp", // "Tar",
"UNIX Timestamp to Windows Filetime", // "Untar",
"Extract dates", // ]
"Sleep", // },
] // {
}, // name: "Hashing",
{ // ops: [
name: "Extractors", // "Analyse hash",
ops: [ // "Generate all hashes",
"Strings", // "MD2",
"Extract IP addresses", // "MD4",
"Extract email addresses", // "MD5",
"Extract MAC addresses", // "MD6",
"Extract URLs", // "SHA0",
"Extract domains", // "SHA1",
"Extract file paths", // "SHA2",
"Extract dates", // "SHA3",
"Regular expression", // "Keccak",
"XPath expression", // "Shake",
"JPath expression", // "RIPEMD",
"CSS selector", // "HAS-160",
"Extract EXIF", // "Whirlpool",
] // "Snefru",
}, // "SSDEEP",
{ // "CTPH",
name: "Compression", // "Compare SSDEEP hashes",
ops: [ // "Compare CTPH hashes",
"Raw Deflate", // "HMAC",
"Raw Inflate", // "Bcrypt",
"Zlib Deflate", // "Bcrypt compare",
"Zlib Inflate", // "Bcrypt parse",
"Gzip", // "Scrypt",
"Gunzip", // "Fletcher-8 Checksum",
"Zip", // "Fletcher-16 Checksum",
"Unzip", // "Fletcher-32 Checksum",
"Bzip2 Decompress", // "Fletcher-64 Checksum",
"Tar", // "Adler-32 Checksum",
"Untar", // "CRC-16 Checksum",
] // "CRC-32 Checksum",
}, // "TCP/IP Checksum",
{ // ]
name: "Hashing", // },
ops: [ // {
"Analyse hash", // name: "Code tidy",
"Generate all hashes", // ops: [
"MD2", // "Syntax highlighter",
"MD4", // "Generic Code Beautify",
"MD5", // "JavaScript Parser",
"MD6", // "JavaScript Beautify",
"SHA0", // "JavaScript Minify",
"SHA1", // "JSON Beautify",
"SHA2", // "JSON Minify",
"SHA3", // "XML Beautify",
"Keccak", // "XML Minify",
"Shake", // "SQL Beautify",
"RIPEMD", // "SQL Minify",
"HAS-160", // "CSS Beautify",
"Whirlpool", // "CSS Minify",
"Snefru", // "XPath expression",
"SSDEEP", // "JPath expression",
"CTPH", // "CSS selector",
"Compare SSDEEP hashes", // "PHP Deserialize",
"Compare CTPH hashes", // "Microsoft Script Decoder",
"HMAC", // "Strip HTML tags",
"Bcrypt", // "Diff",
"Bcrypt compare", // "To Snake case",
"Bcrypt parse", // "To Camel case",
"Scrypt", // "To Kebab case",
"Fletcher-8 Checksum", // "BSON serialise",
"Fletcher-16 Checksum", // "BSON deserialise",
"Fletcher-32 Checksum", // ]
"Fletcher-64 Checksum", // },
"Adler-32 Checksum", // {
"CRC-16 Checksum", // name: "Other",
"CRC-32 Checksum", // ops: [
"TCP/IP Checksum", // "Entropy",
] // "Frequency distribution",
}, // "Chi Square",
{ // "Detect File Type",
name: "Code tidy", // "Scan for Embedded Files",
ops: [ // "Disassemble x86",
"Syntax highlighter", // "Pseudo-Random Number Generator",
"Generic Code Beautify", // "Generate UUID",
"JavaScript Parser", // "Generate TOTP",
"JavaScript Beautify", // "Generate HOTP",
"JavaScript Minify", // "Render Image",
"JSON Beautify", // "Remove EXIF",
"JSON Minify", // "Extract EXIF",
"XML Beautify", // "Numberwang",
"XML Minify", // "XKCD Random Number",
"SQL Beautify", // ]
"SQL Minify", // },
"CSS Beautify", // {
"CSS Minify", // name: "Flow control",
"XPath expression", // ops: [
"JPath expression", // "Fork",
"CSS selector", // "Merge",
"PHP Deserialize", // "Register",
"Microsoft Script Decoder", // "Label",
"Strip HTML tags", // "Jump",
"Diff", // "Conditional Jump",
"To Snake case", // "Return",
"To Camel case", // "Comment"
"To Kebab case", // ]
"BSON serialise", // },
"BSON deserialise",
]
},
{
name: "Other",
ops: [
"Entropy",
"Frequency distribution",
"Chi Square",
"Detect File Type",
"Scan for Embedded Files",
"Disassemble x86",
"Pseudo-Random Number Generator",
"Generate UUID",
"Generate TOTP",
"Generate HOTP",
"Render Image",
"Remove EXIF",
"Extract EXIF",
"Numberwang",
"XKCD Random Number",
]
},
{
name: "Flow control",
ops: [
"Fork",
"Merge",
"Register",
"Label",
"Jump",
"Conditional Jump",
"Return",
"Comment"
]
},*/
]; ];
export default Categories; export default Categories;

View File

@ -1,68 +1,20 @@
{ {
"To Base64": { "From Base32": {
"module": "Default", "module": "Default",
"description": "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>", "description": "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.",
"inputType": "ArrayBuffer", "inputType": "string",
"outputType": "string", "outputType": "byteArray",
"flowControl": false, "flowControl": false,
"args": [ "args": [
{ {
"name": "Alphabet", "name": "Alphabet",
"type": "editableOption", "type": "binaryString",
"value": [ "value": "A-Z2-7="
{ },
"name": "Standard: A-Za-z0-9+/=", {
"value": "A-Za-z0-9+/=" "name": "Remove non-alphabet chars",
}, "type": "boolean",
{ "value": true
"name": "URL safe: A-Za-z0-9-_",
"value": "A-Za-z0-9-_"
},
{
"name": "Filename safe: A-Za-z0-9+-=",
"value": "A-Za-z0-9+\\-="
},
{
"name": "itoa64: ./0-9A-Za-z=",
"value": "./0-9A-Za-z="
},
{
"name": "XML: A-Za-z0-9_.",
"value": "A-Za-z0-9_."
},
{
"name": "y64: A-Za-z0-9._-",
"value": "A-Za-z0-9._-"
},
{
"name": "z64: 0-9a-zA-Z+/=",
"value": "0-9a-zA-Z+/="
},
{
"name": "Radix-64: 0-9A-Za-z+/=",
"value": "0-9A-Za-z+/="
},
{
"name": "Uuencoding: [space]-_",
"value": " -_"
},
{
"name": "Xxencoding: +-0-9A-Za-z",
"value": "+\\-0-9A-Za-z"
},
{
"name": "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r",
"value": "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"
},
{
"name": "ROT13: N-ZA-Mn-za-m0-9+/=",
"value": "N-ZA-Mn-za-m0-9+/="
},
{
"name": "UNIX crypt: ./0-9A-Za-z",
"value": "./0-9A-Za-z"
}
]
} }
] ]
}, },
@ -137,5 +89,105 @@
"value": true "value": true
} }
] ]
},
"Show Base64 offsets": {
"module": "Default",
"description": "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.",
"inputType": "byteArray",
"outputType": "html",
"flowControl": false,
"args": [
{
"name": "Alphabet",
"type": "binaryString",
"value": "A-Za-z0-9+/="
},
{
"name": "Show variable chars and padding",
"type": "boolean",
"value": true
}
]
},
"To Base32": {
"module": "Default",
"description": "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.",
"inputType": "byteArray",
"outputType": "string",
"flowControl": false,
"args": [
{
"name": "Alphabet",
"type": "binaryString",
"value": "A-Z2-7="
}
]
},
"To Base64": {
"module": "Default",
"description": "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>",
"inputType": "ArrayBuffer",
"outputType": "string",
"flowControl": false,
"args": [
{
"name": "Alphabet",
"type": "editableOption",
"value": [
{
"name": "Standard: A-Za-z0-9+/=",
"value": "A-Za-z0-9+/="
},
{
"name": "URL safe: A-Za-z0-9-_",
"value": "A-Za-z0-9-_"
},
{
"name": "Filename safe: A-Za-z0-9+-=",
"value": "A-Za-z0-9+\\-="
},
{
"name": "itoa64: ./0-9A-Za-z=",
"value": "./0-9A-Za-z="
},
{
"name": "XML: A-Za-z0-9_.",
"value": "A-Za-z0-9_."
},
{
"name": "y64: A-Za-z0-9._-",
"value": "A-Za-z0-9._-"
},
{
"name": "z64: 0-9a-zA-Z+/=",
"value": "0-9a-zA-Z+/="
},
{
"name": "Radix-64: 0-9A-Za-z+/=",
"value": "0-9A-Za-z+/="
},
{
"name": "Uuencoding: [space]-_",
"value": " -_"
},
{
"name": "Xxencoding: +-0-9A-Za-z",
"value": "+\\-0-9A-Za-z"
},
{
"name": "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r",
"value": "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"
},
{
"name": "ROT13: N-ZA-Mn-za-m0-9+/=",
"value": "N-ZA-Mn-za-m0-9+/="
},
{
"name": "UNIX crypt: ./0-9A-Za-z",
"value": "./0-9A-Za-z"
}
]
}
]
} }
} }

View File

@ -14,7 +14,7 @@
import path from "path"; import path from "path";
import fs from "fs"; import fs from "fs";
import process from "process"; import process from "process";
import OpIndex from "../operations/index"; import * as Ops from "../operations/index";
const dir = path.join(process.cwd() + "/src/core/config/"); const dir = path.join(process.cwd() + "/src/core/config/");
if (!fs.existsSync(dir)) { if (!fs.existsSync(dir)) {
@ -25,14 +25,14 @@ if (!fs.existsSync(dir)) {
} }
let operationConfig = {}, const operationConfig = {},
modules = {}; modules = {};
/** /**
* Generate operation config and module lists. * Generate operation config and module lists.
*/ */
OpIndex.forEach(opObj => { for (const opObj in Ops) {
const op = new opObj(); const op = new Ops[opObj]();
operationConfig[op.name] = { operationConfig[op.name] = {
module: op.module, module: op.module,
@ -45,8 +45,8 @@ OpIndex.forEach(opObj => {
if (!modules.hasOwnProperty(op.module)) if (!modules.hasOwnProperty(op.module))
modules[op.module] = {}; modules[op.module] = {};
modules[op.module][op.name] = op.name.replace(/\s/g, ""); modules[op.module][op.name] = opObj;
}); }
/** /**
@ -67,7 +67,7 @@ fs.writeFile(
/** /**
* Write modules. * Write modules.
*/ */
for (let module in modules) { for (const module in modules) {
let code = `/** let code = `/**
* THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/generateConfig.mjs * THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/generateConfig.mjs
* *
@ -77,17 +77,17 @@ for (let module in modules) {
*/ */
`; `;
for (let opName in modules[module]) { for (const opName in modules[module]) {
const objName = modules[module][opName]; const objName = modules[module][opName];
code += `import ${objName} from "../../operations/${objName}";\n`; code += `import ${objName} from "../../operations/${objName}";\n`;
} }
code += ` code += `
let OpModules = typeof self === "undefined" ? {} : self.OpModules || {}; const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
OpModules.${module} = { OpModules.${module} = {
`; `;
for (let opName in modules[module]) { for (const opName in modules[module]) {
const objName = modules[module][opName]; const objName = modules[module][opName];
code += ` "${opName}": ${objName},\n`; code += ` "${opName}": ${objName},\n`;
} }
@ -123,18 +123,18 @@ let opModulesCode = `/**
*/ */
`; `;
for (let module in modules) { for (const module in modules) {
opModulesCode += `import ${module}Module from "./${module}";\n`; opModulesCode += `import ${module}Module from "./${module}";\n`;
} }
opModulesCode += ` opModulesCode += `
let OpModules = {}; const OpModules = {};
Object.assign( Object.assign(
OpModules, OpModules,
`; `;
for (let module in modules) { for (const module in modules) {
opModulesCode += ` ${module}Module,\n`; opModulesCode += ` ${module}Module,\n`;
} }

View File

@ -5,14 +5,20 @@
* @copyright Crown Copyright 2018 * @copyright Crown Copyright 2018
* @license Apache-2.0 * @license Apache-2.0
*/ */
import ToBase64 from "../../operations/ToBase64"; import FromBase32 from "../../operations/FromBase32";
import FromBase64 from "../../operations/FromBase64"; import FromBase64 from "../../operations/FromBase64";
import ShowBase64Offsets from "../../operations/ShowBase64Offsets";
import ToBase32 from "../../operations/ToBase32";
import ToBase64 from "../../operations/ToBase64";
let OpModules = typeof self === "undefined" ? {} : self.OpModules || {}; const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
OpModules.Default = { OpModules.Default = {
"To Base64": ToBase64, "From Base32": FromBase32,
"From Base64": FromBase64, "From Base64": FromBase64,
"Show Base64 offsets": ShowBase64Offsets,
"To Base32": ToBase32,
"To Base64": ToBase64,
}; };
export default OpModules; export default OpModules;

View File

@ -9,7 +9,7 @@
*/ */
import DefaultModule from "./Default"; import DefaultModule from "./Default";
let OpModules = {}; const OpModules = {};
Object.assign( Object.assign(
OpModules, OpModules,

View File

@ -1,263 +1,129 @@
import Utils from "../Utils";
/** /**
* Base64 operations. * Base64 functions.
* *
* @author n1474335 [n1474335@gmail.com] * @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016 * @copyright Crown Copyright 2016
* @license Apache-2.0 * @license Apache-2.0
*
* @namespace
*/ */
const Base64 = {
/** import Utils from "../Utils";
* @constant
* @default
*/
BASE32_ALPHABET: "A-Z2-7=",
/**
* To Base32 operation.
*
* @param {byteArray} input
* @param {Object[]} args
* @returns {string}
*/
runTo32: function(input, args) {
if (!input) return "";
let alphabet = args[0] ? /**
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=", * Base64's the input byte array using the given alphabet, returning a string.
output = "", *
chr1, chr2, chr3, chr4, chr5, * @param {byteArray|Uint8Array|string} data
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8, * @param {string} [alphabet="A-Za-z0-9+/="]
i = 0; * @returns {string}
*
* @example
* // returns "SGVsbG8="
* toBase64([72, 101, 108, 108, 111]);
*
* // returns "SGVsbG8="
* toBase64("Hello");
*/
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
if (!data) return "";
if (typeof data == "string") {
data = Utils.strToByteArray(data);
}
while (i < input.length) { alphabet = Utils.expandAlphRange(alphabet).join("");
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
chr4 = input[i++];
chr5 = input[i++];
enc1 = chr1 >> 3; let output = "",
enc2 = ((chr1 & 7) << 2) | (chr2 >> 6); chr1, chr2, chr3,
enc3 = (chr2 >> 1) & 31; enc1, enc2, enc3, enc4,
enc4 = ((chr2 & 1) << 4) | (chr3 >> 4); i = 0;
enc5 = ((chr3 & 15) << 1) | (chr4 >> 7);
enc6 = (chr4 >> 2) & 31;
enc7 = ((chr4 & 3) << 3) | (chr5 >> 5);
enc8 = chr5 & 31;
if (isNaN(chr2)) { while (i < data.length) {
enc3 = enc4 = enc5 = enc6 = enc7 = enc8 = 32; chr1 = data[i++];
} else if (isNaN(chr3)) { chr2 = data[i++];
enc5 = enc6 = enc7 = enc8 = 32; chr3 = data[i++];
} else if (isNaN(chr4)) {
enc6 = enc7 = enc8 = 32;
} else if (isNaN(chr5)) {
enc8 = 32;
}
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) + enc1 = chr1 >> 2;
alphabet.charAt(enc4) + alphabet.charAt(enc5) + alphabet.charAt(enc6) + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
alphabet.charAt(enc7) + alphabet.charAt(enc8); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
} }
return output; output += alphabet.charAt(enc1) + alphabet.charAt(enc2) +
}, alphabet.charAt(enc3) + alphabet.charAt(enc4);
}
return output;
}
/** /**
* From Base32 operation. * UnBase64's the input string using the given alphabet, returning a byte array.
* *
* @param {string} input * @param {byteArray} data
* @param {Object[]} args * @param {string} [alphabet="A-Za-z0-9+/="]
* @returns {byteArray} * @param {string} [returnType="string"] - Either "string" or "byteArray"
*/ * @param {boolean} [removeNonAlphChars=true]
runFrom32: function(input, args) { * @returns {byteArray}
if (!input) return []; *
* @example
* // returns "Hello"
* fromBase64("SGVsbG8=");
*
* // returns [72, 101, 108, 108, 111]
* fromBase64("SGVsbG8=", null, "byteArray");
*/
export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true) {
if (!data) {
return returnType === "string" ? "" : [];
}
let alphabet = args[0] ? alphabet = Utils.expandAlphRange(alphabet).join("");
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
removeNonAlphChars = args[0];
let output = [], const output = [];
chr1, chr2, chr3, chr4, chr5, let chr1, chr2, chr3,
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8, enc1, enc2, enc3, enc4,
i = 0; i = 0;
if (removeNonAlphChars) { if (removeNonAlphChars) {
const re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g"); const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
input = input.replace(re, ""); data = data.replace(re, "");
}
while (i < data.length) {
enc1 = alphabet.indexOf(data.charAt(i++));
enc2 = alphabet.indexOf(data.charAt(i++) || "=");
enc3 = alphabet.indexOf(data.charAt(i++) || "=");
enc4 = alphabet.indexOf(data.charAt(i++) || "=");
enc2 = enc2 === -1 ? 64 : enc2;
enc3 = enc3 === -1 ? 64 : enc3;
enc4 = enc4 === -1 ? 64 : enc4;
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output.push(chr1);
if (enc3 !== 64) {
output.push(chr2);
} }
if (enc4 !== 64) {
while (i < input.length) { output.push(chr3);
enc1 = alphabet.indexOf(input.charAt(i++));
enc2 = alphabet.indexOf(input.charAt(i++) || "=");
enc3 = alphabet.indexOf(input.charAt(i++) || "=");
enc4 = alphabet.indexOf(input.charAt(i++) || "=");
enc5 = alphabet.indexOf(input.charAt(i++) || "=");
enc6 = alphabet.indexOf(input.charAt(i++) || "=");
enc7 = alphabet.indexOf(input.charAt(i++) || "=");
enc8 = alphabet.indexOf(input.charAt(i++) || "=");
chr1 = (enc1 << 3) | (enc2 >> 2);
chr2 = ((enc2 & 3) << 6) | (enc3 << 1) | (enc4 >> 4);
chr3 = ((enc4 & 15) << 4) | (enc5 >> 1);
chr4 = ((enc5 & 1) << 7) | (enc6 << 2) | (enc7 >> 3);
chr5 = ((enc7 & 7) << 5) | enc8;
output.push(chr1);
if (enc2 & 3 !== 0 || enc3 !== 32) output.push(chr2);
if (enc4 & 15 !== 0 || enc5 !== 32) output.push(chr3);
if (enc5 & 1 !== 0 || enc6 !== 32) output.push(chr4);
if (enc7 & 7 !== 0 || enc8 !== 32) output.push(chr5);
} }
}
return output; return returnType === "string" ? Utils.byteArrayToUtf8(output) : output;
}, }
/** /**
* @constant * Base64 alphabets.
* @default */
*/
SHOW_IN_BINARY: false,
/**
* @constant
* @default
*/
OFFSETS_SHOW_VARIABLE: true,
/**
* Show Base64 offsets operation.
*
* @param {byteArray} input
* @param {Object[]} args
* @returns {html}
*/
runOffsets: function(input, args) {
let alphabet = args[0] || Base64.ALPHABET,
showVariable = args[1],
offset0 = Utils.toBase64(input, alphabet),
offset1 = Utils.toBase64([0].concat(input), alphabet),
offset2 = Utils.toBase64([0, 0].concat(input), alphabet),
len0 = offset0.indexOf("="),
len1 = offset1.indexOf("="),
len2 = offset2.indexOf("="),
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>",
staticSection = "",
padding = "";
if (input.length < 1) {
return "Please enter a string.";
}
// Highlight offset 0
if (len0 % 4 === 2) {
staticSection = offset0.slice(0, -3);
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
"<span class='hl3'>" + offset0.substr(offset0.length - 2) + "</span>";
} else if (len0 % 4 === 3) {
staticSection = offset0.slice(0, -2);
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
"<span class='hl3'>" + offset0.substr(offset0.length - 1) + "</span>";
} else {
staticSection = offset0;
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet)) + "'>" +
staticSection + "</span>";
}
if (!showVariable) {
offset0 = staticSection;
}
// Highlight offset 1
padding = "<span class='hl3'>" + offset1.substr(0, 1) + "</span>" +
"<span class='hl5'>" + offset1.substr(1, 1) + "</span>";
offset1 = offset1.substr(2);
if (len1 % 4 === 2) {
staticSection = offset1.slice(0, -3);
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
"<span class='hl3'>" + offset1.substr(offset1.length - 2) + "</span>";
} else if (len1 % 4 === 3) {
staticSection = offset1.slice(0, -2);
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
"<span class='hl3'>" + offset1.substr(offset1.length - 1) + "</span>";
} else {
staticSection = offset1;
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1)) + "'>" +
staticSection + "</span>";
}
if (!showVariable) {
offset1 = staticSection;
}
// Highlight offset 2
padding = "<span class='hl3'>" + offset2.substr(0, 2) + "</span>" +
"<span class='hl5'>" + offset2.substr(2, 1) + "</span>";
offset2 = offset2.substr(3);
if (len2 % 4 === 2) {
staticSection = offset2.slice(0, -3);
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
"<span class='hl3'>" + offset2.substr(offset2.length - 2) + "</span>";
} else if (len2 % 4 === 3) {
staticSection = offset2.slice(0, -2);
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
"<span class='hl3'>" + offset2.substr(offset2.length - 1) + "</span>";
} else {
staticSection = offset2;
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2)) + "'>" +
staticSection + "</span>";
}
if (!showVariable) {
offset2 = staticSection;
}
return (showVariable ? "Characters highlighted in <span class='hl5'>green</span> could change if the input is surrounded by more data." +
"\nCharacters highlighted in <span class='hl3'>red</span> are for padding purposes only." +
"\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
"\nHover over the static sections to see what they decode to on their own.\n" +
"\nOffset 0: " + offset0 +
"\nOffset 1: " + offset1 +
"\nOffset 2: " + offset2 +
script :
offset0 + "\n" + offset1 + "\n" + offset2);
},
};
export default Base64;
export const ALPHABET = "A-Za-z0-9+/=";
export const ALPHABET_OPTIONS = [ export const ALPHABET_OPTIONS = [
{name: "Standard: A-Za-z0-9+/=", value: "A-Za-z0-9+/="}, {name: "Standard: A-Za-z0-9+/=", value: "A-Za-z0-9+/="},
{name: "URL safe: A-Za-z0-9-_", value: "A-Za-z0-9-_"}, {name: "URL safe: A-Za-z0-9-_", value: "A-Za-z0-9-_"},

View File

@ -0,0 +1,90 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation";
import Utils from "../Utils";
/**
* From Base32 operation
*/
class FromBase32 extends Operation {
/**
* FromBase32 constructor
*/
constructor() {
super();
this.name = "From Base32";
this.module = "Default";
this.description = "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.";
this.inputType = "string";
this.outputType = "byteArray";
this.args = [
{
name: "Alphabet",
type: "binaryString",
value: "A-Z2-7="
},
{
name: "Remove non-alphabet chars",
type: "boolean",
value: true
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {byteArray}
*/
run(input, args) {
if (!input) return [];
const alphabet = args[0] ?
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
removeNonAlphChars = args[1],
output = [];
let chr1, chr2, chr3, chr4, chr5,
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
i = 0;
if (removeNonAlphChars) {
const re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g");
input = input.replace(re, "");
}
while (i < input.length) {
enc1 = alphabet.indexOf(input.charAt(i++));
enc2 = alphabet.indexOf(input.charAt(i++) || "=");
enc3 = alphabet.indexOf(input.charAt(i++) || "=");
enc4 = alphabet.indexOf(input.charAt(i++) || "=");
enc5 = alphabet.indexOf(input.charAt(i++) || "=");
enc6 = alphabet.indexOf(input.charAt(i++) || "=");
enc7 = alphabet.indexOf(input.charAt(i++) || "=");
enc8 = alphabet.indexOf(input.charAt(i++) || "=");
chr1 = (enc1 << 3) | (enc2 >> 2);
chr2 = ((enc2 & 3) << 6) | (enc3 << 1) | (enc4 >> 4);
chr3 = ((enc4 & 15) << 4) | (enc5 >> 1);
chr4 = ((enc5 & 1) << 7) | (enc6 << 2) | (enc7 >> 3);
chr5 = ((enc7 & 7) << 5) | enc8;
output.push(chr1);
if (enc2 & 3 !== 0 || enc3 !== 32) output.push(chr2);
if (enc4 & 15 !== 0 || enc5 !== 32) output.push(chr3);
if (enc5 & 1 !== 0 || enc6 !== 32) output.push(chr4);
if (enc7 & 7 !== 0 || enc8 !== 32) output.push(chr5);
}
return output;
}
}
export default FromBase32;

View File

@ -5,8 +5,7 @@
*/ */
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import {fromBase64, ALPHABET_OPTIONS} from "../lib/Base64";
import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
/** /**
* From Base64 operation * From Base64 operation
@ -14,17 +13,17 @@ import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
class FromBase64 extends Operation { class FromBase64 extends Operation {
/** /**
* ToBase64 constructor * FromBase64 constructor
*/ */
constructor() { constructor() {
super(); super();
this.name = "From Base64"; this.name = "From Base64";
this.module = "Default"; this.module = "Default";
this.description = "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>"; this.description = "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>";
this.inputType = "string"; this.inputType = "string";
this.outputType = "byteArray"; this.outputType = "byteArray";
this.args = [ this.args = [
{ {
name: "Alphabet", name: "Alphabet",
type: "editableOption", type: "editableOption",
@ -44,10 +43,9 @@ class FromBase64 extends Operation {
* @returns {string} * @returns {string}
*/ */
run(input, args) { run(input, args) {
let alphabet = args[0] || ALPHABET, const [alphabet, removeNonAlphChars] = args;
removeNonAlphChars = args[1];
return Utils.fromBase64(input, alphabet, "byteArray", removeNonAlphChars); return fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
} }
/** /**

View File

@ -0,0 +1,162 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation";
import Utils from "../Utils";
import {fromBase64, toBase64} from "../lib/Base64";
/**
* Show Base64 offsets operation
*/
class ShowBase64Offsets extends Operation {
/**
* ShowBase64Offsets constructor
*/
constructor() {
super();
this.name = "Show Base64 offsets";
this.module = "Default";
this.description = "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.";
this.inputType = "byteArray";
this.outputType = "html";
this.args = [
{
name: "Alphabet",
type: "binaryString",
value: "A-Za-z0-9+/="
},
{
name: "Show variable chars and padding",
type: "boolean",
value: true
}
];
}
/**
* @param {byteArray} input
* @param {Object[]} args
* @returns {html}
*/
run(input, args) {
const [alphabet, showVariable] = args;
let offset0 = toBase64(input, alphabet),
offset1 = toBase64([0].concat(input), alphabet),
offset2 = toBase64([0, 0].concat(input), alphabet),
staticSection = "",
padding = "";
const len0 = offset0.indexOf("="),
len1 = offset1.indexOf("="),
len2 = offset2.indexOf("="),
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>";
if (input.length < 1) {
return "Please enter a string.";
}
// Highlight offset 0
if (len0 % 4 === 2) {
staticSection = offset0.slice(0, -3);
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
"<span class='hl3'>" + offset0.substr(offset0.length - 2) + "</span>";
} else if (len0 % 4 === 3) {
staticSection = offset0.slice(0, -2);
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
"<span class='hl3'>" + offset0.substr(offset0.length - 1) + "</span>";
} else {
staticSection = offset0;
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64(staticSection, alphabet)) + "'>" +
staticSection + "</span>";
}
if (!showVariable) {
offset0 = staticSection;
}
// Highlight offset 1
padding = "<span class='hl3'>" + offset1.substr(0, 1) + "</span>" +
"<span class='hl5'>" + offset1.substr(1, 1) + "</span>";
offset1 = offset1.substr(2);
if (len1 % 4 === 2) {
staticSection = offset1.slice(0, -3);
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
"<span class='hl3'>" + offset1.substr(offset1.length - 2) + "</span>";
} else if (len1 % 4 === 3) {
staticSection = offset1.slice(0, -2);
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
"<span class='hl3'>" + offset1.substr(offset1.length - 1) + "</span>";
} else {
staticSection = offset1;
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1)) + "'>" +
staticSection + "</span>";
}
if (!showVariable) {
offset1 = staticSection;
}
// Highlight offset 2
padding = "<span class='hl3'>" + offset2.substr(0, 2) + "</span>" +
"<span class='hl5'>" + offset2.substr(2, 1) + "</span>";
offset2 = offset2.substr(3);
if (len2 % 4 === 2) {
staticSection = offset2.slice(0, -3);
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
"<span class='hl3'>" + offset2.substr(offset2.length - 2) + "</span>";
} else if (len2 % 4 === 3) {
staticSection = offset2.slice(0, -2);
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
staticSection + "</span>" +
"<span class='hl5'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
"<span class='hl3'>" + offset2.substr(offset2.length - 1) + "</span>";
} else {
staticSection = offset2;
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2)) + "'>" +
staticSection + "</span>";
}
if (!showVariable) {
offset2 = staticSection;
}
return (showVariable ? "Characters highlighted in <span class='hl5'>green</span> could change if the input is surrounded by more data." +
"\nCharacters highlighted in <span class='hl3'>red</span> are for padding purposes only." +
"\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
"\nHover over the static sections to see what they decode to on their own.\n" +
"\nOffset 0: " + offset0 +
"\nOffset 1: " + offset1 +
"\nOffset 2: " + offset2 +
script :
offset0 + "\n" + offset1 + "\n" + offset2);
}
}
export default ShowBase64Offsets;

View File

@ -0,0 +1,85 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation";
import Utils from "../Utils";
/**
* To Base32 operation
*/
class ToBase32 extends Operation {
/**
* ToBase32 constructor
*/
constructor() {
super();
this.name = "To Base32";
this.module = "Default";
this.description = "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.";
this.inputType = "byteArray";
this.outputType = "string";
this.args = [
{
name: "Alphabet",
type: "binaryString",
value: "A-Z2-7="
}
];
}
/**
* @param {byteArray} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
if (!input) return "";
const alphabet = args[0] ? Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=";
let output = "",
chr1, chr2, chr3, chr4, chr5,
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
i = 0;
while (i < input.length) {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
chr4 = input[i++];
chr5 = input[i++];
enc1 = chr1 >> 3;
enc2 = ((chr1 & 7) << 2) | (chr2 >> 6);
enc3 = (chr2 >> 1) & 31;
enc4 = ((chr2 & 1) << 4) | (chr3 >> 4);
enc5 = ((chr3 & 15) << 1) | (chr4 >> 7);
enc6 = (chr4 >> 2) & 31;
enc7 = ((chr4 & 3) << 3) | (chr5 >> 5);
enc8 = chr5 & 31;
if (isNaN(chr2)) {
enc3 = enc4 = enc5 = enc6 = enc7 = enc8 = 32;
} else if (isNaN(chr3)) {
enc5 = enc6 = enc7 = enc8 = 32;
} else if (isNaN(chr4)) {
enc6 = enc7 = enc8 = 32;
} else if (isNaN(chr5)) {
enc8 = 32;
}
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) +
alphabet.charAt(enc4) + alphabet.charAt(enc5) + alphabet.charAt(enc6) +
alphabet.charAt(enc7) + alphabet.charAt(enc8);
}
return output;
}
}
export default ToBase32;

View File

@ -5,8 +5,7 @@
*/ */
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import {toBase64, ALPHABET_OPTIONS} from "../lib/Base64";
import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
/** /**
* To Base64 operation * To Base64 operation
@ -19,12 +18,12 @@ class ToBase64 extends Operation {
constructor() { constructor() {
super(); super();
this.name = "To Base64"; this.name = "To Base64";
this.module = "Default"; this.module = "Default";
this.description = "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>"; this.description = "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>";
this.inputType = "ArrayBuffer"; this.inputType = "ArrayBuffer";
this.outputType = "string"; this.outputType = "string";
this.args = [ this.args = [
{ {
name: "Alphabet", name: "Alphabet",
type: "editableOption", type: "editableOption",
@ -39,8 +38,8 @@ class ToBase64 extends Operation {
* @returns {string} * @returns {string}
*/ */
run(input, args) { run(input, args) {
const alphabet = args[0] || ALPHABET; const alphabet = args[0];
return Utils.toBase64(new Uint8Array(input), alphabet); return toBase64(new Uint8Array(input), alphabet);
} }
/** /**

View File

@ -1,7 +1,13 @@
import ToBase64 from "./ToBase64"; import ToBase64 from "./ToBase64";
import FromBase64 from "./FromBase64"; import FromBase64 from "./FromBase64";
import ToBase32 from "./ToBase32";
import FromBase32 from "./FromBase32";
import ShowBase64Offsets from "./ShowBase64Offsets";
export default [ export {
ToBase64, ToBase64,
FromBase64 FromBase64,
]; ToBase32,
FromBase32,
ShowBase64Offsets
};

View File

@ -1,4 +1,5 @@
import Utils from "../Utils.js"; import Utils from "../Utils.js";
import {toBase64} from "../lib/Base64";
import CryptoJS from "crypto-js"; import CryptoJS from "crypto-js";
import forge from "imports-loader?jQuery=>null!node-forge/dist/forge.min.js"; import forge from "imports-loader?jQuery=>null!node-forge/dist/forge.min.js";
import {blowfish as Blowfish} from "sladex-blowfish"; import {blowfish as Blowfish} from "sladex-blowfish";
@ -366,7 +367,7 @@ DES uses a key length of 8 bytes (64 bits).`;
input = Utils.convertToByteString(input, inputType); input = Utils.convertToByteString(input, inputType);
Blowfish.setIV(Utils.toBase64(iv), 0); Blowfish.setIV(toBase64(iv), 0);
const enc = Blowfish.encrypt(input, key, { const enc = Blowfish.encrypt(input, key, {
outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType], outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
@ -395,7 +396,7 @@ DES uses a key length of 8 bytes (64 bits).`;
input = inputType === "Raw" ? Utils.strToByteArray(input) : input; input = inputType === "Raw" ? Utils.strToByteArray(input) : input;
Blowfish.setIV(Utils.toBase64(iv), 0); Blowfish.setIV(toBase64(iv), 0);
const result = Blowfish.decrypt(input, key, { const result = Blowfish.decrypt(input, key, {
outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird. outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.

View File

@ -2,6 +2,7 @@ import * as ExifParser from "exif-parser";
import removeEXIF from "../vendor/remove-exif.js"; import removeEXIF from "../vendor/remove-exif.js";
import Utils from "../Utils.js"; import Utils from "../Utils.js";
import FileType from "./FileType.js"; import FileType from "./FileType.js";
import {fromBase64, toBase64} from "../lib/Base64";
/** /**
@ -96,7 +97,7 @@ const Image = {
case "Base64": case "Base64":
// Don't trust the Base64 entered by the user. // Don't trust the Base64 entered by the user.
// Unwrap it first, then re-encode later. // Unwrap it first, then re-encode later.
input = Utils.fromBase64(input, null, "byteArray"); input = fromBase64(input, null, "byteArray");
break; break;
case "Raw": case "Raw":
default: default:
@ -113,7 +114,7 @@ const Image = {
} }
// Add image data to URI // Add image data to URI
dataURI += "base64," + Utils.toBase64(input); dataURI += "base64," + toBase64(input);
return "<img src='" + dataURI + "'>"; return "<img src='" + dataURI + "'>";
}, },

View File

@ -1,4 +1,5 @@
import Utils from "../Utils.js"; import Utils from "../Utils.js";
import {fromBase64} from "../lib/Base64";
import * as r from "jsrsasign"; import * as r from "jsrsasign";
@ -43,7 +44,7 @@ const PublicKey = {
cert.readCertPEM(input); cert.readCertPEM(input);
break; break;
case "Base64": case "Base64":
cert.readCertHex(Utils.toHex(Utils.fromBase64(input, null, "byteArray"), "")); cert.readCertHex(Utils.toHex(fromBase64(input, null, "byteArray"), ""));
break; break;
case "Raw": case "Raw":
cert.readCertHex(Utils.toHex(Utils.strToByteArray(input), "")); cert.readCertHex(Utils.toHex(Utils.strToByteArray(input), ""));

View File

@ -1,4 +1,5 @@
import Utils from "../core/Utils"; import Utils from "../core/Utils";
import {fromBase64} from "../core/lib/Base64";
import Manager from "./Manager.js"; import Manager from "./Manager.js";
import HTMLCategory from "./HTMLCategory.js"; import HTMLCategory from "./HTMLCategory.js";
import HTMLOperation from "./HTMLOperation.js"; import HTMLOperation from "./HTMLOperation.js";
@ -193,12 +194,12 @@ App.prototype.populateOperationsList = function() {
let i; let i;
for (i = 0; i < this.categories.length; i++) { for (i = 0; i < this.categories.length; i++) {
let catConf = this.categories[i], const catConf = this.categories[i],
selected = i === 0, selected = i === 0,
cat = new HTMLCategory(catConf.name, selected); cat = new HTMLCategory(catConf.name, selected);
for (let j = 0; j < catConf.ops.length; j++) { for (let j = 0; j < catConf.ops.length; j++) {
let opName = catConf.ops[j], const opName = catConf.ops[j],
op = new HTMLOperation(opName, this.operations[opName], this, this.manager); op = new HTMLOperation(opName, this.operations[opName], this, this.manager);
cat.addOperation(op); cat.addOperation(op);
} }
@ -405,7 +406,7 @@ App.prototype.loadURIParams = function() {
// Read in input data from URI params // Read in input data from URI params
if (this.uriParams.input) { if (this.uriParams.input) {
try { try {
const inputData = Utils.fromBase64(this.uriParams.input); const inputData = fromBase64(this.uriParams.input);
this.setInput(inputData); this.setInput(inputData);
} catch (err) {} } catch (err) {}
} }
@ -503,11 +504,11 @@ App.prototype.resetLayout = function() {
*/ */
App.prototype.setCompileMessage = function() { App.prototype.setCompileMessage = function() {
// Display time since last build and compile message // Display time since last build and compile message
let now = new Date(), const now = new Date(),
timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime); timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime);
// Calculate previous version to compare to // Calculate previous version to compare to
let prev = PKG_VERSION.split(".").map(n => { const prev = PKG_VERSION.split(".").map(n => {
return parseInt(n, 10); return parseInt(n, 10);
}); });
if (prev[2] > 0) prev[2]--; if (prev[2] > 0) prev[2]--;
@ -574,7 +575,7 @@ App.prototype.alert = function(str, style, timeout, silent) {
style = style || "danger"; style = style || "danger";
timeout = timeout || 0; timeout = timeout || 0;
let alertEl = document.getElementById("alert"), const alertEl = document.getElementById("alert"),
alertContent = document.getElementById("alert-content"); alertContent = document.getElementById("alert-content");
alertEl.classList.remove("alert-danger"); alertEl.classList.remove("alert-danger");

View File

@ -1,4 +1,5 @@
import Utils from "../core/Utils"; import Utils from "../core/Utils";
import {toBase64} from "../core/lib/Base64";
/** /**
@ -169,7 +170,7 @@ ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput
window.location.host + window.location.host +
window.location.pathname; window.location.pathname;
const recipeStr = Utils.generatePrettyRecipe(recipeConfig); const recipeStr = Utils.generatePrettyRecipe(recipeConfig);
const inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding const inputStr = toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
includeRecipe = includeRecipe && (recipeConfig.length > 0); includeRecipe = includeRecipe && (recipeConfig.length > 0);
// Only inlcude input if it is less than 50KB (51200 * 4/3 as it is Base64 encoded) // Only inlcude input if it is less than 50KB (51200 * 4/3 as it is Base64 encoded)
@ -271,9 +272,9 @@ ControlsWaiter.prototype.saveButtonClick = function() {
return; return;
} }
let savedRecipes = localStorage.savedRecipes ? const savedRecipes = localStorage.savedRecipes ?
JSON.parse(localStorage.savedRecipes) : [], JSON.parse(localStorage.savedRecipes) : [];
recipeId = localStorage.recipeId || 0; let recipeId = localStorage.recipeId || 0;
savedRecipes.push({ savedRecipes.push({
id: ++recipeId, id: ++recipeId,

View File

@ -32,12 +32,14 @@ const HTMLIngredient = function(config, app, manager) {
* @returns {string} * @returns {string}
*/ */
HTMLIngredient.prototype.toHtml = function() { HTMLIngredient.prototype.toHtml = function() {
let inline = (this.type === "boolean" || const inline = (
this.type === "number" || this.type === "boolean" ||
this.type === "option" || this.type === "number" ||
this.type === "shortString" || this.type === "option" ||
this.type === "binaryShortString"), this.type === "shortString" ||
html = inline ? "" : "<div class='clearfix'>&nbsp;</div>", this.type === "binaryShortString"
);
let html = inline ? "" : "<div class='clearfix'>&nbsp;</div>",
i, m; i, m;
html += "<div class='arg-group" + (inline ? " inline-args" : "") + html += "<div class='arg-group" + (inline ? " inline-args" : "") +
@ -202,7 +204,7 @@ HTMLIngredient.prototype.populateOptionChange = function(e) {
* @param {event} e * @param {event} e
*/ */
HTMLIngredient.prototype.editableOptionChange = function(e) { HTMLIngredient.prototype.editableOptionChange = function(e) {
let select = e.target, const select = e.target,
input = select.nextSibling; input = select.nextSibling;
input.value = select.childNodes[select.selectedIndex].value; input.value = select.childNodes[select.selectedIndex].value;

View File

@ -40,8 +40,8 @@ HighlighterWaiter.OUTPUT = 1;
* @returns {boolean} * @returns {boolean}
*/ */
HighlighterWaiter.prototype._isSelectionBackwards = function() { HighlighterWaiter.prototype._isSelectionBackwards = function() {
let backwards = false, let backwards = false;
sel = window.getSelection(); const sel = window.getSelection();
if (!sel.isCollapsed) { if (!sel.isCollapsed) {
const range = document.createRange(); const range = document.createRange();

View File

@ -25,7 +25,7 @@ self.addEventListener("message", function(e) {
*/ */
self.loadFile = function(file) { self.loadFile = function(file) {
const reader = new FileReader(); const reader = new FileReader();
let data = new Uint8Array(file.size); const data = new Uint8Array(file.size);
let offset = 0; let offset = 0;
const CHUNK_SIZE = 10485760; // 10MiB const CHUNK_SIZE = 10485760; // 10MiB

View File

@ -453,7 +453,7 @@ RecipeWaiter.prototype.setRegisters = function(opIndex, numPrevRegisters, regist
// Remove previous div // Remove previous div
if (prevRegList) prevRegList.remove(); if (prevRegList) prevRegList.remove();
let registerList = []; const registerList = [];
for (let i = 0; i < registers.length; i++) { for (let i = 0; i < registers.length; i++) {
registerList.push(`$R${numPrevRegisters + i} = ${Utils.escapeHtml(Utils.truncate(Utils.printable(registers[i]), 100))}`); registerList.push(`$R${numPrevRegisters + i} = ${Utils.escapeHtml(Utils.truncate(Utils.printable(registers[i]), 100))}`);
} }

View File

@ -20,7 +20,7 @@ sitemap.add({
priority: 1.0 priority: 1.0
}); });
for (let op in OperationConfig) { for (const op in OperationConfig) {
sitemap.add({ sitemap.add({
url: `/?op=${encodeURIComponent(op)}`, url: `/?op=${encodeURIComponent(op)}`,
changeFreq: "yearly", changeFreq: "yearly",