فهرست منبع

merge from upstream

d98762625 6 سال پیش
والد
کامیت
214d6c4405

+ 2 - 2
.babelrc

@@ -1,6 +1,6 @@
 {
     "presets": [
-        ["env", {
+        ["@babel/preset-env", {
             "targets": {
                 "chrome": 40,
                 "firefox": 35,
@@ -8,7 +8,7 @@
                 "node": "6.5"
             },
             "modules": false,
-            "useBuiltIns": true
+            "useBuiltIns": "usage"
         }]
     ],
     "plugins": [

+ 4 - 0
CHANGELOG.md

@@ -1,6 +1,8 @@
 # Changelog
 All notable changes to CyberChef will be documented in this file.
 
+### [8.8.0] - 2018-10-10
+- 'Parse TLV' operation added [@GCHQ77703] | [#351]
 
 ### [8.7.0] - 2018-08-31
 - 'JWT Sign', 'JWT Verify' and 'JWT Decode' operations added [@GCHQ77703] | [#348]
@@ -51,6 +53,7 @@ All notable changes to CyberChef will be documented in this file.
 -  Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
 
 
+[8.8.0]: https://github.com/gchq/CyberChef/releases/tag/v8.8.0
 [8.7.0]: https://github.com/gchq/CyberChef/releases/tag/v8.7.0
 [8.6.0]: https://github.com/gchq/CyberChef/releases/tag/v8.6.0
 [8.5.0]: https://github.com/gchq/CyberChef/releases/tag/v8.5.0
@@ -91,3 +94,4 @@ All notable changes to CyberChef will be documented in this file.
 [#340]: https://github.com/gchq/CyberChef/pull/340
 [#344]: https://github.com/gchq/CyberChef/pull/344
 [#348]: https://github.com/gchq/CyberChef/pull/348
+[#351]: https://github.com/gchq/CyberChef/pull/351

+ 5 - 1
Gruntfile.js

@@ -320,7 +320,11 @@ module.exports = function (grunt) {
                     chunks: false,
                     modules: false,
                     entrypoints: false,
-                    warningsFilter: [/source-map/, /dependency is an expression/],
+                    warningsFilter: [
+                        /source-map/,
+                        /dependency is an expression/,
+                        /export 'default'/
+                    ],
                 }
             },
             start: {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1203 - 929
package-lock.json


+ 26 - 26
package.json

@@ -1,6 +1,6 @@
 {
   "name": "cyberchef",
-  "version": "8.7.0",
+  "version": "8.8.4",
   "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
   "author": "n1474335 <n1474335@gmail.com>",
   "homepage": "https://gchq.github.io/CyberChef",
@@ -31,46 +31,46 @@
   "module": "src/node/index.mjs",
   "bugs": "https://github.com/gchq/CyberChef/issues",
   "devDependencies": {
-    "autoprefixer": "^9.1.0",
-    "babel-core": "^6.26.3",
-    "babel-loader": "^7.1.5",
-    "babel-preset-env": "^1.7.0",
+    "@babel/core": "^7.1.2",
+    "@babel/preset-env": "^7.1.0",
+    "autoprefixer": "^9.1.5",
+    "babel-loader": "^8.0.4",
     "bootstrap": "^4.1.3",
-    "colors": "^1.3.1",
+    "colors": "^1.3.2",
     "css-loader": "^1.0.0",
-    "eslint": "^5.3.0",
+    "eslint": "^5.6.1",
     "exports-loader": "^0.7.0",
     "extract-text-webpack-plugin": "^4.0.0-alpha0",
-    "file-loader": "^1.1.11",
+    "file-loader": "^2.0.0",
     "grunt": "^1.0.3",
     "grunt-accessibility": "~6.0.0",
     "grunt-chmod": "~1.1.1",
     "grunt-concurrent": "^2.3.1",
-    "grunt-contrib-clean": "~1.1.0",
+    "grunt-contrib-clean": "~2.0.0",
     "grunt-contrib-copy": "~1.0.0",
     "grunt-contrib-watch": "^1.1.0",
     "grunt-eslint": "^21.0.0",
     "grunt-exec": "~3.0.0",
-    "grunt-jsdoc": "^2.2.1",
-    "grunt-webpack": "^3.1.2",
+    "grunt-jsdoc": "^2.3.0",
+    "grunt-webpack": "^3.1.3",
     "html-webpack-plugin": "^3.2.0",
     "imports-loader": "^0.8.0",
     "ink-docstrap": "^1.3.2",
     "js-to-mjs": "^0.2.0",
-    "jsdoc-babel": "^0.4.0",
-    "node-sass": "^4.9.2",
-    "postcss-css-variables": "^0.9.0",
+    "jsdoc-babel": "^0.5.0",
+    "node-sass": "^4.9.3",
+    "postcss-css-variables": "^0.11.0",
     "postcss-import": "^12.0.0",
-    "postcss-loader": "^2.1.6",
+    "postcss-loader": "^3.0.0",
     "prompt": "^1.0.0",
     "sass-loader": "^7.1.0",
-    "sitemap": "^1.13.0",
-    "style-loader": "^0.21.0",
+    "sitemap": "^2.0.1",
+    "style-loader": "^0.23.1",
     "uglifyjs-webpack-plugin": "^2.0.1",
-    "url-loader": "^1.0.1",
+    "url-loader": "^1.1.2",
     "web-resource-inliner": "^4.2.1",
-    "webpack": "^4.16.4",
-    "webpack-dev-server": "^3.1.5",
+    "webpack": "^4.20.2",
+    "webpack-dev-server": "^3.1.9",
     "webpack-node-externals": "^1.7.2",
     "worker-loader": "^2.0.0"
   },
@@ -93,24 +93,24 @@
     "esmangle": "^1.0.1",
     "esprima": "^4.0.1",
     "exif-parser": "^0.1.12",
-    "file-saver": "^1.3.8",
+    "file-saver": "^2.0.0-rc.3",
     "highlight.js": "^9.12.0",
     "jquery": "^3.3.1",
     "js-crc": "^0.2.0",
-    "js-sha3": "^0.7.0",
+    "js-sha3": "^0.8.0",
     "jsbn": "^1.1.0",
     "jsesc": "^2.5.1",
     "jsonpath": "^1.0.0",
     "jsonwebtoken": "^8.3.0",
     "jsrsasign": "8.0.12",
-    "kbpgp": "^2.0.77",
-    "lodash": "^4.17.10",
+    "kbpgp": "^2.0.80",
+    "lodash": "^4.17.11",
     "loglevel": "^1.6.1",
     "loglevel-message-prefix": "^3.0.0",
     "moment": "^2.22.2",
     "moment-timezone": "^0.5.21",
     "ngeohash": "^0.6.0",
-    "node-forge": "^0.7.5",
+    "node-forge": "^0.7.6",
     "node-md6": "^0.1.0",
     "notepack.io": "^2.1.3",
     "nwmatcher": "^1.4.4",
@@ -119,7 +119,7 @@
     "scryptsy": "^2.0.0",
     "snackbarjs": "^1.1.0",
     "sortablejs": "^1.7.0",
-    "split.js": "^1.3.5",
+    "split.js": "^1.5.2",
     "ssdeep.js": "0.0.2",
     "ua-parser-js": "^0.7.18",
     "utf8": "^3.0.0",

+ 0 - 2
src/core/Utils.mjs

@@ -555,8 +555,6 @@ class Utils {
             if (renderNext) {
                 cell += b;
                 renderNext = false;
-            } else if (b === "\\") {
-                renderNext = true;
             } else if (b === "\"" && !inString) {
                 inString = true;
             } else if (b === "\"" && inString) {

+ 2 - 1
src/core/config/Categories.json

@@ -53,7 +53,8 @@
             "To MessagePack",
             "From MessagePack",
             "To Braille",
-            "From Braille"
+            "From Braille",
+            "Parse TLV"
         ]
     },
     {

+ 78 - 0
src/core/lib/TLVParser.mjs

@@ -0,0 +1,78 @@
+/**
+ * Parser for Type-length-value data.
+ *
+ * @author gchq77703 []
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+const defaults = {
+    location: 0,
+    bytesInLength: 1,
+    basicEncodingRules: false
+};
+
+/**
+ * TLVParser library
+ */
+export default class TLVParser {
+
+    /**
+     * TLVParser constructor
+     *
+     * @param {byteArray} input
+     * @param {Object} options
+     */
+    constructor(input, options) {
+        this.input = input;
+        Object.assign(this, defaults, options);
+    }
+
+    /**
+     * @returns {number}
+     */
+    getLength() {
+        if (this.basicEncodingRules) {
+            const bit = this.input[this.location];
+            if (bit & 0x80) {
+                this.bytesInLength = bit & ~0x80;
+            } else {
+                this.location++;
+                return bit & ~0x80;
+            }
+        }
+
+        let length = 0;
+
+        for (let i = 0; i < this.bytesInLength; i++) {
+            length += this.input[this.location] * Math.pow(Math.pow(2, 8), i);
+            this.location++;
+        }
+
+        return length;
+    }
+
+    /**
+     * @param {number} length
+     * @returns {number[]}
+     */
+    getValue(length) {
+        const value = [];
+
+        for (let i = 0; i < length; i++) {
+            if (this.location > this.input.length) return value;
+            value.push(this.input[this.location]);
+            this.location++;
+        }
+
+        return value;
+    }
+
+    /**
+     * @returns {boolean}
+     */
+    atEnd() {
+        return this.input.length <= this.location;
+    }
+}

+ 1 - 1
src/core/operations/Bzip2Decompress.mjs

@@ -5,7 +5,7 @@
  */
 
 import Operation from "../Operation";
-import bzip2 from "../vendor/bzip2.js";
+import bzip2 from "../vendor/bzip2";
 import OperationError from "../errors/OperationError";
 
 /**

+ 2 - 2
src/core/operations/ExtractEmailAddresses.mjs

@@ -39,8 +39,8 @@ class ExtractEmailAddresses extends Operation {
      */
     run(input, args) {
         const displayTotal = args[0],
-            regex = /\b\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}\b/ig;
-
+        // email regex from: https://www.regextester.com/98066
+            regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/ig;
         return search(input, regex, null, displayTotal);
     }
 

+ 76 - 0
src/core/operations/ParseTLV.mjs

@@ -0,0 +1,76 @@
+/**
+ * @author gchq77703 []
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import TLVParser from "../lib/TLVParser";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Parse TLV operation
+ */
+class ParseTLV extends Operation {
+
+    /**
+     * ParseTLV constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Parse TLV";
+        this.module = "Default";
+        this.description = "Converts a Type-Length-Value (TLV) encoded string into a JSON object.  Can optionally include a <code>Key</code> / <code>Type</code> entry. <br><br>Tags: Key-Length-Value, KLV, Length-Value, LV";
+        this.infoURL = "https://wikipedia.org/wiki/Type-length-value";
+        this.inputType = "byteArray";
+        this.outputType = "JSON";
+        this.args = [
+            {
+                name: "Type/Key size",
+                type: "number",
+                value: 1
+            },
+            {
+                name: "Length size",
+                type: "number",
+                value: 1
+            },
+            {
+                name: "Use BER",
+                type: "boolean",
+                value: false
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const [bytesInKey, bytesInLength, basicEncodingRules] = args;
+
+        if (bytesInKey <= 0 && bytesInLength <= 0)
+            throw new OperationError("Type or Length size must be greater than 0");
+
+        const tlv = new TLVParser(input, { bytesInLength, basicEncodingRules });
+
+        const data = [];
+
+        while (!tlv.atEnd()) {
+            const key = bytesInKey ? tlv.getValue(bytesInKey) : undefined;
+            const length = tlv.getLength();
+            const value = tlv.getValue(length);
+
+            data.push({ key, length, value });
+        }
+
+        return data;
+    }
+
+}
+
+export default ParseTLV;

+ 1 - 1
src/core/vendor/bzip2.js → src/core/vendor/bzip2.mjs

@@ -262,4 +262,4 @@ bzip2.decompress = function(bits, size, len){
   return output;
 }
 
-module.exports = bzip2;
+export default bzip2;

+ 1 - 0
src/web/BackgroundWorkerWaiter.mjs

@@ -67,6 +67,7 @@ class BackgroundWorkerWaiter {
                 log.debug("Background ChefWorker loaded");
                 break;
             case "optionUpdate":
+            case "statusMessage":
                 // Ignore these messages
                 break;
             default:

+ 1 - 1
src/web/HTMLIngredient.mjs

@@ -154,7 +154,7 @@ class HTMLIngredient {
                     } else if ((m = this.value[i].name.match(/\[\/([a-z0-9 -()^]+)\]/i))) {
                         html += "</optgroup>";
                     } else {
-                        html += `<option populate-value="${this.value[i].value}">${this.value[i].name}</option>`;
+                        html += `<option populate-value='${this.value[i].value}'>${this.value[i].name}</option>`;
                     }
                 }
                 html += `</select>

+ 2 - 0
test/index.mjs

@@ -40,6 +40,7 @@ import "./tests/operations/Compress";
 import "./tests/operations/ConditionalJump";
 import "./tests/operations/Crypt";
 import "./tests/operations/DateTime";
+import "./tests/operations/ExtractEmailAddresses";
 import "./tests/operations/Fork";
 import "./tests/operations/FromGeohash.mjs";
 import "./tests/operations/Hash";
@@ -71,6 +72,7 @@ import "./tests/operations/SymmetricDifference";
 import "./tests/operations/ToGeohash.mjs";
 import "./tests/operations/TranslateDateTimeFormat";
 import "./tests/operations/Magic";
+import "./tests/operations/ParseTLV";
 
 import "./tests/nodeApi/nodeApi";
 import "./tests/nodeApi/ops";

+ 55 - 0
test/tests/operations/ExtractEmailAddresses.mjs

@@ -0,0 +1,55 @@
+/**
+ * extract email address tests.
+ *
+ * @author Klaxon [klaxon@veyr.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+import TestRegister from "../../TestRegister";
+
+TestRegister.addTests([
+    {
+        name: "Extract email address",
+        input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
+        expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n",
+        recipeConfig: [
+            {
+                "op": "Extract email addresses",
+                "args": [false]
+            },
+        ],
+    },
+    {
+        name: "Extract email address - Display total",
+        input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
+        expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n",
+        recipeConfig: [
+            {
+                "op": "Extract email addresses",
+                "args": [true]
+            },
+        ],
+    },
+    {
+        name: "Extract email address (Internationalized)",
+        input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
+        expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n",
+        recipeConfig: [
+            {
+                "op": "Extract email addresses",
+                "args": [false]
+            },
+        ],
+    },
+    {
+        name: "Extract email address - Display total (Internationalized)",
+        input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
+        expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n",
+        recipeConfig: [
+            {
+                "op": "Extract email addresses",
+                "args": [true]
+            },
+        ],
+    },
+]);

+ 56 - 0
test/tests/operations/ParseTLV.mjs

@@ -0,0 +1,56 @@
+/**
+ * Parse TLV tests.
+ *
+ * @author gchq77703 []
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import TestRegister from "../../TestRegister";
+
+TestRegister.addTests([
+    {
+        name: "Parse TLV: LengthValue",
+        input: "\x05\x48\x6f\x75\x73\x65\x04\x72\x6f\x6f\x6d\x04\x64\x6f\x6f\x72",
+        expectedOutput: JSON.stringify([{"length": 5, "value": [72, 111, 117, 115, 101]}, {"length": 4, "value": [114, 111, 111, 109]}, {"length": 4, "value": [100, 111, 111, 114]}], null, 4),
+        recipeConfig: [
+            {
+                "op": "Parse TLV",
+                "args": [0, 1, false]
+            }
+        ]
+    },
+    {
+        name: "Parse TLV: LengthValue with BER",
+        input: "\x05\x48\x6f\x75\x73\x65\x04\x72\x6f\x6f\x6d\x04\x64\x6f\x6f\x72",
+        expectedOutput: JSON.stringify([{"length": 5, "value": [72, 111, 117, 115, 101]}, {"length": 4, "value": [114, 111, 111, 109]}, {"length": 4, "value": [100, 111, 111, 114]}], null, 4),
+        recipeConfig: [
+            {
+                "op": "Parse TLV",
+                "args": [0, 4, true] // length value is patently wrong, should be ignored by BER.
+            }
+        ]
+    },
+    {
+        name: "Parse TLV: KeyLengthValue",
+        input: "\x04\x05\x48\x6f\x75\x73\x65\x05\x04\x72\x6f\x6f\x6d\x42\x04\x64\x6f\x6f\x72",
+        expectedOutput: JSON.stringify([{"key": [4], "length": 5, "value": [72, 111, 117, 115, 101]}, {"key": [5], "length": 4, "value": [114, 111, 111, 109]}, {"key": [66], "length": 4, "value": [100, 111, 111, 114]}], null, 4),
+        recipeConfig: [
+            {
+                "op": "Parse TLV",
+                "args": [1, 1, false]
+            }
+        ]
+    },
+    {
+        name: "Parse TLV: KeyLengthValue with BER",
+        input: "\x04\x05\x48\x6f\x75\x73\x65\x05\x04\x72\x6f\x6f\x6d\x42\x04\x64\x6f\x6f\x72",
+        expectedOutput: JSON.stringify([{"key": [4], "length": 5, "value": [72, 111, 117, 115, 101]}, {"key": [5], "length": 4, "value": [114, 111, 111, 109]}, {"key": [66], "length": 4, "value": [100, 111, 111, 114]}], null, 4),
+        recipeConfig: [
+            {
+                "op": "Parse TLV",
+                "args": [1, 4, true] // length value is patently wrong, should be ignored by BER.
+            }
+        ]
+    }
+]);

+ 5 - 1
webpack.config.js

@@ -113,7 +113,11 @@ module.exports = {
         chunks: false,
         modules: false,
         entrypoints: false,
-        warningsFilter: [/source-map/, /dependency is an expression/],
+        warningsFilter: [
+            /source-map/,
+            /dependency is an expression/,
+            /export 'default'/
+        ],
     },
     node: {
         fs: "empty"

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است