Browse Source

Merge branch 'artemisbot-features/string_escape_unescape'

n1474335 8 years ago
parent
commit
ca75f7fa0b

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

@@ -173,7 +173,6 @@ const Categories = [
             "Tail",
             "Count occurrences",
             "Expand alphabet range",
-            "Parse escaped string",
             "Drop bytes",
             "Take bytes",
             "Pad lines",
@@ -188,6 +187,8 @@ const Categories = [
             "Parse UNIX file permissions",
             "Swap endianness",
             "Parse colour code",
+            "Escape string",
+            "Unescape string",
         ]
     },
     {

+ 14 - 7
src/core/config/OperationConfig.js

@@ -3224,13 +3224,6 @@ const OperationConfig = {
             }
         ]
     },
-    "Parse escaped string": {
-        description: "Replaces escaped characters with the bytes they represent.<br><br>e.g.<code>Hello\\nWorld</code> becomes <code>Hello<br>World</code>",
-        run: StrUtils.runParseEscapedString,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
     "TCP/IP Checksum": {
         description: "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes.",
         run: Checksum.runTCPIP,
@@ -3270,6 +3263,20 @@ const OperationConfig = {
             }
         ]
     },
+    "Escape string": {
+        description: "Escapes special characters in a string so that they do not cause conflicts. For example, <code>Don't stop me now</code> becomes <code>Don\\'t stop me now</code>.",
+        run: StrUtils.runEscape,
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Unescape string": {
+        description: "Unescapes characters in a string that have been escaped. For example, <code>Don\\'t stop me now</code> becomes <code>Don't stop me now</code>.",
+        run: StrUtils.runUnescape,
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
     "To Morse Code": {
         description: "Translates alphanumeric characters into International Morse Code.<br><br>Ignores non-Morse characters.<br><br>e.g. <code>SOS</code> becomes <code>... --- ...</code>",
         run: MorseCode.runTo,

+ 73 - 3
src/core/operations/StrUtils.js

@@ -450,14 +450,84 @@ const StrUtils = {
 
 
     /**
-     * Parse escaped string operation.
+     * @constant
+     * @default
+     */
+    ESCAPE_REPLACEMENTS: [
+        {"escaped": "\\\\", "unescaped": "\\"}, // Must be first
+        {"escaped": "\\'", "unescaped": "'"},
+        {"escaped": "\\\"", "unescaped": "\""},
+        {"escaped": "\\n", "unescaped": "\n"},
+        {"escaped": "\\r", "unescaped": "\r"},
+        {"escaped": "\\t", "unescaped": "\t"},
+        {"escaped": "\\b", "unescaped": "\b"},
+        {"escaped": "\\f", "unescaped": "\f"},
+    ],
+
+    /**
+     * Escape string operation.
+     *
+     * @author Vel0x [dalemy@microsoft.com]
      *
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @example
+     * StrUtils.runUnescape("Don't do that", [])
+     * > "Don\'t do that"
+     * StrUtils.runUnescape(`Hello
+     * World`, [])
+     * > "Hello\nWorld"
      */
-    runParseEscapedString: function(input, args) {
-        return Utils.parseEscapedChars(input);
+    runEscape: function(input, args) {
+        return StrUtils._replaceByKeys(input, "unescaped", "escaped");
+    },
+
+
+    /**
+     * Unescape string operation.
+     *
+     * @author Vel0x [dalemy@microsoft.com]
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     *
+     * @example
+     * StrUtils.runUnescape("Don\'t do that", [])
+     * > "Don't do that"
+     * StrUtils.runUnescape("Hello\nWorld", [])
+     * > `Hello
+     * World`
+     */
+    runUnescape: function(input, args) {
+        return StrUtils._replaceByKeys(input, "escaped", "unescaped");
+    },
+
+
+    /**
+     * Replaces all matching tokens in ESCAPE_REPLACEMENTS with the correction. The
+     * ordering is determined by the patternKey and the replacementKey.
+     *
+     * @author Vel0x [dalemy@microsoft.com]
+     * @author Matt C [matt@artemisbot.uk]
+     *
+     * @param {string} input
+     * @param {string} pattern_key
+     * @param {string} replacement_key
+     * @returns {string}
+     */
+    _replaceByKeys: function(input, patternKey, replacementKey) {
+        let output = input;
+
+        // Catch the \\x encoded characters
+        if (patternKey === "escaped") output = Utils.parseEscapedChars(input);
+
+        StrUtils.ESCAPE_REPLACEMENTS.forEach(replacement => {
+            output = output.split(replacement[patternKey]).join(replacement[replacementKey]);
+        });
+        return output;
     },
 
 

+ 44 - 0
test/tests/operations/StrUtils.js

@@ -232,4 +232,48 @@ TestRegister.addTests([
             }
         ],
     },
+    {
+        name: "Escape String: quotes",
+        input: "Hello \"World\"! Escape 'these' quotes.",
+        expectedOutput: "Hello \\\"World\\\"! Escape \\'these\\' quotes.",
+        recipeConfig: [
+            {
+                "op": "Escape String",
+                "args": []
+            }
+        ],
+    },
+    {
+        name: "Escape String: special characters",
+        input: "Fizz & buzz\n\ttabbed newline\rcarriage returned line\nbackspace character: \"\" form feed character: \"\"",
+        expectedOutput: "Fizz & buzz\\n\\ttabbed newline\\rcarriage returned line\\nbackspace character: \\\"\\b\\\" form feed character: \\\"\\f\\\"",
+        recipeConfig: [
+            {
+                "op": "Escape String",
+                "args": []
+            }
+        ],
+    },
+    {
+        name: "Unescape String: quotes",
+        input: "Hello \\\"World\\\"! Escape \\'these\\' quotes.",
+        expectedOutput: "Hello \"World\"! Escape 'these' quotes.",
+        recipeConfig: [
+            {
+                "op": "Unescape String",
+                "args": []
+            }
+        ],
+    },
+    {
+        name: "Unescape String: special characters",
+        input: "Fizz \x26 buzz\\n\\ttabbed newline\\rcarriage returned line\\nbackspace character: \\\"\\b\\\" form feed character: \\\"\\f\\\"",
+        expectedOutput: "Fizz & buzz\n\ttabbed newline\rcarriage returned line\nbackspace character: \"\" form feed character: \"\"",
+        recipeConfig: [
+            {
+                "op": "Unescape String",
+                "args": []
+            }
+        ],
+    },
 ]);