mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-10 00:05:11 -04:00
adding BraceMatching operation
This commit is contained in:
parent
8d0fcf37c5
commit
85b98f1111
4 changed files with 206 additions and 1 deletions
|
@ -230,7 +230,8 @@
|
|||
"Escape string",
|
||||
"Unescape string",
|
||||
"Pseudo-Random Number Generator",
|
||||
"Sleep"
|
||||
"Sleep",
|
||||
"Brace Matching"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
102
src/core/operations/Bracematching.mjs
Normal file
102
src/core/operations/Bracematching.mjs
Normal file
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* @author DBHeise [david@heiseink.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
//import OperationError from "../errors/OperationError";
|
||||
|
||||
/**
|
||||
* Brace Matching operation
|
||||
*/
|
||||
class BraceMatching extends Operation {
|
||||
|
||||
/**
|
||||
* BraceMatching constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Brace Matching";
|
||||
this.module = "Default";
|
||||
this.description = "Extracts nested grouping";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Brace_matching";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Open Brace Character",
|
||||
type: "string",
|
||||
value: "("
|
||||
},
|
||||
{
|
||||
name: "Close Brace Character",
|
||||
type: "string",
|
||||
value: ")"
|
||||
},
|
||||
{
|
||||
name: "String Chars",
|
||||
type: "string",
|
||||
value: "\"'"
|
||||
},
|
||||
{
|
||||
name: "Escape Char",
|
||||
type: "string",
|
||||
value: "\\"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [openChar, closeChar, strChars, escChar] = args;
|
||||
let ans = "";
|
||||
let isInString = false;
|
||||
let nestLevel = 0;
|
||||
let stringChar = null;
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const ch = input[i];
|
||||
if (ch === openChar) {
|
||||
if (!isInString) {
|
||||
nestLevel++;
|
||||
if (nestLevel === 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (ch === closeChar) {
|
||||
if (!isInString) {
|
||||
nestLevel--;
|
||||
if (nestLevel < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ch === escChar) {
|
||||
ans += ch;
|
||||
ans += input[i + 1];
|
||||
i++;
|
||||
continue;
|
||||
} else if (stringChar && ch === stringChar) {
|
||||
isInString = false;
|
||||
stringChar = null;
|
||||
} else if (strChars.indexOf(ch) > -1) {
|
||||
if (!isInString) {
|
||||
isInString = true;
|
||||
stringChar = ch;
|
||||
}
|
||||
}
|
||||
if (nestLevel > 0) {
|
||||
ans += ch;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
export default BraceMatching;
|
||||
|
|
@ -90,6 +90,7 @@ import "./tests/Typex";
|
|||
import "./tests/BLAKE2b";
|
||||
import "./tests/BLAKE2s";
|
||||
import "./tests/Protobuf";
|
||||
import "./tests/BraceMatching";
|
||||
|
||||
// Cannot test operations that use the File type yet
|
||||
//import "./tests/SplitColourChannels";
|
||||
|
|
101
tests/operations/tests/BraceMatching.mjs
Normal file
101
tests/operations/tests/BraceMatching.mjs
Normal file
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Brace Matching tests.
|
||||
*
|
||||
* @author DBHeise [david@heiseink.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../TestRegister";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Brace Matching Simple",
|
||||
input: "(test)",
|
||||
expectedOutput: "test",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["(", ")", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Brace Matching Simple with extra text",
|
||||
input: "this is a simple (test) of this function",
|
||||
expectedOutput: "test",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["(", ")", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Brace Matching Simple with strings",
|
||||
input: "{test \"}\"}",
|
||||
expectedOutput: "test \"}\"",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["{", "}", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Brace Matching Simple with strings 2",
|
||||
input: "{test '}'}",
|
||||
expectedOutput: "test '}'",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["{", "}", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Brace Matching Simple nested",
|
||||
input: "[this [test] good]",
|
||||
expectedOutput: "this [test] good",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["[", "]", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Brace Matching Simple escaped",
|
||||
input: "<test \\> foo bar>",
|
||||
expectedOutput: "test \\> foo bar",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["<", ">", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Brace Matching Complex multi nesting 1",
|
||||
input: "(((((test)))))(((((test)))))",
|
||||
expectedOutput: "((((test))))",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["(", ")", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Brace Matching Complex multi nesting 2",
|
||||
input: "(((((test))))(((((test))))))",
|
||||
expectedOutput: "((((test))))(((((test)))))",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Brace Matching",
|
||||
"args": ["(", ")", "\"'", "\\"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue