mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-23 08:16:17 -04:00
The raw, unpresented dish is now returned to the app after baking, where it can be retrieved as various different data types.
This commit is contained in:
parent
d5b5443a84
commit
fbec0a1c7d
12 changed files with 163 additions and 73 deletions
|
@ -89,7 +89,14 @@ class Chef {
|
|||
const threshold = (options.ioDisplayThreshold || 1024) * 1024;
|
||||
const returnType = this.dish.size > threshold ? Dish.ARRAY_BUFFER : Dish.STRING;
|
||||
|
||||
// Create a raw version of the dish, unpresented
|
||||
const rawDish = new Dish(this.dish);
|
||||
|
||||
// Present the raw result
|
||||
await recipe.present(this.dish);
|
||||
|
||||
return {
|
||||
dish: rawDish,
|
||||
result: this.dish.type === Dish.HTML ?
|
||||
await this.dish.get(Dish.HTML, notUTF8) :
|
||||
await this.dish.get(returnType, notUTF8),
|
||||
|
@ -123,7 +130,7 @@ class Chef {
|
|||
|
||||
const startTime = new Date().getTime(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
dish = new Dish("", Dish.STRING);
|
||||
dish = new Dish();
|
||||
|
||||
try {
|
||||
recipe.execute(dish);
|
||||
|
@ -167,6 +174,19 @@ class Chef {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates the dish to a specified type and returns it.
|
||||
*
|
||||
* @param {Dish} dish
|
||||
* @param {string} type
|
||||
* @returns {Dish}
|
||||
*/
|
||||
async getDishAs(dish, type) {
|
||||
const newDish = new Dish(dish);
|
||||
return await newDish.get(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Chef;
|
||||
|
|
|
@ -60,6 +60,9 @@ self.addEventListener("message", function(e) {
|
|||
case "silentBake":
|
||||
silentBake(r.data);
|
||||
break;
|
||||
case "getDishAs":
|
||||
getDishAs(r.data);
|
||||
break;
|
||||
case "docURL":
|
||||
// Used to set the URL of the current document so that scripts can be
|
||||
// imported into an inline worker.
|
||||
|
@ -125,6 +128,22 @@ function silentBake(data) {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates the dish to a given type.
|
||||
*/
|
||||
async function getDishAs(data) {
|
||||
const value = await self.chef.getDishAs(data.dish, data.type);
|
||||
|
||||
self.postMessage({
|
||||
action: "dishReturned",
|
||||
data: {
|
||||
value: value,
|
||||
id: data.id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks that all required modules are loaded and loads them if not.
|
||||
*
|
||||
|
|
|
@ -17,14 +17,17 @@ class Dish {
|
|||
/**
|
||||
* Dish constructor
|
||||
*
|
||||
* @param {byteArray|string|number|ArrayBuffer|BigNumber} [value=null]
|
||||
* - The value of the input data.
|
||||
* @param {number} [type=Dish.BYTE_ARRAY]
|
||||
* - The data type of value, see Dish enums.
|
||||
* @param {Dish} [dish=null] - A dish to clone
|
||||
*/
|
||||
constructor(value=null, type=Dish.BYTE_ARRAY) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
constructor(dish=null) {
|
||||
this.value = [];
|
||||
this.type = Dish.BYTE_ARRAY;
|
||||
|
||||
if (dish &&
|
||||
dish.hasOwnProperty("value") &&
|
||||
dish.hasOwnProperty("type")) {
|
||||
this.set(dish.value, dish.type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -68,7 +68,9 @@ const FlowControl = {
|
|||
op.ingValues = JSON.parse(JSON.stringify(ingValues[i]));
|
||||
});
|
||||
|
||||
const dish = new Dish(inputs[i], inputType);
|
||||
const dish = new Dish();
|
||||
dish.set(inputs[i], inputType);
|
||||
|
||||
try {
|
||||
progress = await recipe.execute(dish, 0, state);
|
||||
} catch (err) {
|
||||
|
|
|
@ -130,10 +130,12 @@ class Recipe {
|
|||
* - The final progress through the recipe
|
||||
*/
|
||||
async execute(dish, startFrom=0, forkState={}) {
|
||||
let op, input, output, lastRunOp,
|
||||
let op, input, output,
|
||||
numJumps = 0,
|
||||
numRegisters = forkState.numRegisters || 0;
|
||||
|
||||
if (startFrom === 0) this.lastRunOp = null;
|
||||
|
||||
log.debug(`[*] Executing recipe of ${this.opList.length} operations, starting at ${startFrom}`);
|
||||
|
||||
for (let i = startFrom; i < this.opList.length; i++) {
|
||||
|
@ -169,7 +171,7 @@ class Recipe {
|
|||
numRegisters = state.numRegisters;
|
||||
} else {
|
||||
output = await op.run(input, op.ingValues);
|
||||
lastRunOp = op;
|
||||
this.lastRunOp = op;
|
||||
dish.set(output, op.outputType);
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -188,18 +190,24 @@ class Recipe {
|
|||
}
|
||||
}
|
||||
|
||||
// Present the results of the final operation
|
||||
if (lastRunOp) {
|
||||
// TODO try/catch
|
||||
output = await lastRunOp.present(output);
|
||||
dish.set(output, lastRunOp.presentType);
|
||||
}
|
||||
|
||||
log.debug("Recipe complete");
|
||||
return this.opList.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Present the results of the final operation.
|
||||
*
|
||||
* @param {Dish} dish
|
||||
*/
|
||||
async present(dish) {
|
||||
if (!this.lastRunOp) return;
|
||||
|
||||
const output = await this.lastRunOp.present(await dish.get(this.lastRunOp.outputType));
|
||||
dish.set(output, this.lastRunOp.presentType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the recipe configuration in string format.
|
||||
*
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import utf8 from "utf8";
|
||||
import moment from "moment-timezone";
|
||||
import {fromBase64} from "./lib/Base64";
|
||||
import {toHexFast, fromHex} from "./lib/Hex";
|
||||
import {fromHex} from "./lib/Hex";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -833,39 +833,24 @@ class Utils {
|
|||
|
||||
const formatFile = async function(file, i) {
|
||||
const buff = await Utils.readFile(file);
|
||||
const fileStr = Utils.arrayBufferToStr(buff.buffer);
|
||||
const blob = new Blob(
|
||||
[buff],
|
||||
{type: "octet/stream"}
|
||||
);
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
|
||||
const viewFileElem = `<a href='#collapse${i}'
|
||||
class='collapsed'
|
||||
data-toggle='collapse'
|
||||
aria-expanded='true'
|
||||
aria-controls='collapse${i}'
|
||||
title="Show/hide contents of '${Utils.escapeHtml(file.name)}'">👁️</a>`;
|
||||
|
||||
const downloadFileElem = `<a href='${blobUrl}'
|
||||
title='Download ${Utils.escapeHtml(file.name)}'
|
||||
download='${Utils.escapeHtml(file.name)}'>💾</a>`;
|
||||
|
||||
const hexFileData = toHexFast(buff);
|
||||
|
||||
const switchToInputElem = `<a href='#switchFileToInput${i}'
|
||||
class='file-switch'
|
||||
title='Move file to input as hex'
|
||||
fileValue='${hexFileData}'>⇧</a>`;
|
||||
|
||||
const html = `<div class='panel panel-default' style='white-space: normal;'>
|
||||
<div class='panel-heading' role='tab' id='heading${i}'>
|
||||
<h4 class='panel-title'>
|
||||
<div>
|
||||
${Utils.escapeHtml(file.name)}
|
||||
${viewFileElem}
|
||||
${downloadFileElem}
|
||||
${switchToInputElem}
|
||||
<a href='#collapse${i}'
|
||||
class='collapsed'
|
||||
data-toggle='collapse'
|
||||
aria-expanded='true'
|
||||
aria-controls='collapse${i}'
|
||||
title="Show/hide contents of '${Utils.escapeHtml(file.name)}'">${Utils.escapeHtml(file.name)}</a>
|
||||
<a href='${URL.createObjectURL(blob)}'
|
||||
title='Download ${Utils.escapeHtml(file.name)}'
|
||||
download='${Utils.escapeHtml(file.name)}'>💾</a>
|
||||
<span class='pull-right'>
|
||||
${file.size.toLocaleString()} bytes
|
||||
</span>
|
||||
|
@ -875,7 +860,7 @@ class Utils {
|
|||
<div id='collapse${i}' class='panel-collapse collapse'
|
||||
role='tabpanel' aria-labelledby='heading${i}'>
|
||||
<div class='panel-body'>
|
||||
<pre><code>${Utils.escapeHtml(fileStr)}</code></pre>
|
||||
<pre><code>${Utils.escapeHtml(Utils.arrayBufferToStr(buff.buffer))}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
|
|
@ -99,7 +99,7 @@ export default OpModules;
|
|||
path.join(dir, `modules/${module}.mjs`),
|
||||
code
|
||||
);
|
||||
console.log(`Written ${module} module`);
|
||||
console.log(`Written ${module} module`);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue