Browse Source

disabled `unicodeEscapeSequence` option by default. Corrected tests.

sanex3339 8 năm trước cách đây
mục cha
commit
bef947f8ce
22 tập tin đã thay đổi với 140 bổ sung182 xóa
  1. 4 4
      README.md
  2. 6 25
      dist/index.js
  3. 2 1
      src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts
  4. 1 1
      src/node-transformers/control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts
  5. 3 29
      src/node-transformers/obfuscating-transformers/ObjectExpressionTransformer.ts
  6. 1 1
      src/options/presets/Default.ts
  7. 1 1
      src/options/presets/NoCustomNodes.ts
  8. 1 1
      test/dev/dev.ts
  9. 9 3
      test/functional-tests/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.spec.ts
  10. 14 9
      test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  11. 17 15
      test/functional-tests/node-transformers/control-flow-transformers/block-statement-control-flow-transformer/BlockStatementControlFlowTransformer.spec.ts
  12. 3 3
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer/BinaryExpressionControlFlowReplacer.spec.ts
  13. 4 4
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec.ts
  14. 4 4
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec.ts
  15. 6 6
      test/functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec.ts
  16. 3 3
      test/functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec.ts
  17. 2 2
      test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts
  18. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/catch-clause-transformer/CatchClauseTransformer.spec.ts
  19. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts
  20. 38 38
      test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts
  21. 3 14
      test/functional-tests/node-transformers/obfuscating-transformers/object-expression-transformer/ObjectExpressionTransformer.spec.ts
  22. 16 16
      test/functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec.ts

+ 4 - 4
README.md

@@ -190,7 +190,7 @@ Following options are available for the JS Obfuscator:
     stringArray: true,
     stringArrayEncoding: false,
     stringArrayThreshold: 0.8,
-    unicodeEscapeSequence: true
+    unicodeEscapeSequence: false
 }
 ```
 
@@ -445,11 +445,11 @@ This setting is especially useful for large code size because it repeatedly call
 `stringArrayThreshold: 0` equals to `stringArray: false`.
 
 ### `unicodeEscapeSequence`
-Type: `boolean` Default: `true`
+Type: `boolean` Default: `false`
 
 Allows to enable/disable string conversion to unicode escape sequence.
 
-Unicode escape sequence increases code size greatly. It is recommended to disable this option when using [`stringArrayEncoding`](#stringarrayencoding) (especially with `rc4` encoding).
+Unicode escape sequence increases code size greatly and strings easily can be reverted to their original view. Recommended to enable this option only for small source code. 
 
 ## Preset Options
 ### High obfuscation, low performance
@@ -510,7 +510,7 @@ Performance will slightly slower than without obfuscation
     stringArray: true,
     stringArrayEncoding: false,
     stringArrayThreshold: 0.75,
-    unicodeEscapeSequence: true
+    unicodeEscapeSequence: false
 }
 ```
 

+ 6 - 25
dist/index.js

@@ -1532,7 +1532,7 @@ exports.NO_CUSTOM_NODES_PRESET = Object.freeze({
     stringArray: false,
     stringArrayEncoding: false,
     stringArrayThreshold: 0,
-    unicodeEscapeSequence: true
+    unicodeEscapeSequence: false
 });
 
 /***/ }),
@@ -1826,7 +1826,7 @@ var AbstractControlFlowReplacer = AbstractControlFlowReplacer_1 = function () {
             var controlFlowStorageId = controlFlowStorage.getStorageId();
             var storageKeysById = AbstractControlFlowReplacer_1.getStorageKeysByIdForCurrentStorage(this.replacerDataByControlFlowStorageId, controlFlowStorageId);
             var storageKeysForCurrentId = storageKeysById.get(replacerId);
-            if (RandomGeneratorUtils_1.RandomGeneratorUtils.getMathRandom() > usingExistingIdentifierChance && storageKeysForCurrentId && storageKeysForCurrentId.length) {
+            if (RandomGeneratorUtils_1.RandomGeneratorUtils.getMathRandom() < usingExistingIdentifierChance && storageKeysForCurrentId && storageKeysForCurrentId.length) {
                 return RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomGenerator().pickone(storageKeysForCurrentId);
             }
             var generateStorageKey = function generateStorageKey(length) {
@@ -1939,7 +1939,7 @@ exports.DEFAULT_PRESET = Object.freeze({
     stringArray: true,
     stringArrayEncoding: false,
     stringArrayThreshold: 0.8,
-    unicodeEscapeSequence: true
+    unicodeEscapeSequence: false
 });
 
 /***/ }),
@@ -3966,7 +3966,7 @@ var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) {
             return JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(format(SelfDefendingTemplate_1.SelfDefendingTemplate(), {
                 selfDefendingFunctionName: RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomVariableName(6),
                 singleNodeCallControllerFunctionName: this.callsControllerFunctionName
-            }), Object.assign({}, NoCustomNodes_1.NO_CUSTOM_NODES_PRESET, { seed: this.options.seed })).getObfuscatedCode();
+            }), Object.assign({}, NoCustomNodes_1.NO_CUSTOM_NODES_PRESET, { seed: this.options.seed, unicodeEscapeSequence: true })).getObfuscatedCode();
         }
     }]);
 
@@ -5542,11 +5542,9 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 var tslib_1 = __webpack_require__(1);
 var inversify_1 = __webpack_require__(0);
 var ServiceIdentifiers_1 = __webpack_require__(2);
-var escodegen = __webpack_require__(20);
 var NodeType_1 = __webpack_require__(13);
 var AbstractNodeTransformer_1 = __webpack_require__(10);
 var Node_1 = __webpack_require__(6);
-var Utils_1 = __webpack_require__(8);
 var ObjectExpressionTransformer = ObjectExpressionTransformer_1 = function (_AbstractNodeTransfor) {
     _inherits(ObjectExpressionTransformer, _AbstractNodeTransfor);
 
@@ -5576,36 +5574,19 @@ var ObjectExpressionTransformer = ObjectExpressionTransformer_1 = function (_Abs
                 if (property.shorthand) {
                     property.shorthand = false;
                 }
-                if (Node_1.Node.isLiteralNode(property.key)) {
-                    property.key = ObjectExpressionTransformer_1.transformLiteralPropertyKey(property.key);
-                } else if (Node_1.Node.isIdentifierNode(property.key)) {
+                if (Node_1.Node.isIdentifierNode(property.key)) {
                     property.key = ObjectExpressionTransformer_1.transformIdentifierPropertyKey(property.key);
                 }
             });
             return objectExpressionNode;
         }
     }], [{
-        key: "transformLiteralPropertyKey",
-        value: function transformLiteralPropertyKey(node) {
-            if (typeof node.value === 'string' && !node['x-verbatim-property']) {
-                node['x-verbatim-property'] = {
-                    content: "'" + Utils_1.Utils.stringToUnicodeEscapeSequence(node.value) + "'",
-                    precedence: escodegen.Precedence.Primary
-                };
-            }
-            return node;
-        }
-    }, {
         key: "transformIdentifierPropertyKey",
         value: function transformIdentifierPropertyKey(node) {
             return {
                 type: NodeType_1.NodeType.Literal,
                 value: node.name,
-                raw: "'" + node.name + "'",
-                'x-verbatim-property': {
-                    content: "'" + Utils_1.Utils.stringToUnicodeEscapeSequence(node.name) + "'",
-                    precedence: escodegen.Precedence.Primary
-                }
+                raw: "'" + node.name + "'"
             };
         }
     }]);

+ 2 - 1
src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts

@@ -60,7 +60,8 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
             }),
             {
                 ...NO_CUSTOM_NODES_PRESET,
-                seed: this.options.seed
+                seed: this.options.seed,
+                unicodeEscapeSequence: true
             }
         ).getObfuscatedCode();
     }

+ 1 - 1
src/node-transformers/control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts

@@ -88,7 +88,7 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
         const storageKeysForCurrentId: string[] | undefined = storageKeysById.get(replacerId);
 
         if (
-            RandomGeneratorUtils.getMathRandom() > usingExistingIdentifierChance &&
+            RandomGeneratorUtils.getMathRandom() < usingExistingIdentifierChance &&
             storageKeysForCurrentId &&
             storageKeysForCurrentId.length
         ) {

+ 3 - 29
src/node-transformers/obfuscating-transformers/ObjectExpressionTransformer.ts

@@ -1,7 +1,6 @@
 import { injectable, inject } from 'inversify';
 import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
 
-import * as escodegen from 'escodegen';
 import * as ESTree from 'estree';
 
 import { IOptions } from '../../interfaces/options/IOptions';
@@ -11,17 +10,13 @@ import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { Node } from '../../node/Node';
-import { Utils } from '../../utils/Utils';
 
 /**
  * replaces:
- *     var object = { 'PSEUDO': 1 };
- *
- * or:
  *     var object = { PSEUDO: 1 };
  *
  * on:
- *     var object = { '\u0050\u0053\u0045\u0055\u0044\u004f': 1 };
+ *     var object = { 'PSEUDO': 1 };
  */
 @injectable()
 export class ObjectExpressionTransformer extends AbstractNodeTransformer {
@@ -34,21 +29,6 @@ export class ObjectExpressionTransformer extends AbstractNodeTransformer {
         super(options);
     }
 
-    /**
-     * @param node
-     * @returns {ESTree.Literal}
-     */
-    private static transformLiteralPropertyKey (node: ESTree.Literal): ESTree.Literal {
-        if (typeof node.value === 'string' && !node['x-verbatim-property']) {
-            node['x-verbatim-property'] = {
-                content : `'${Utils.stringToUnicodeEscapeSequence(node.value)}'`,
-                precedence: escodegen.Precedence.Primary
-            };
-        }
-
-        return node;
-    }
-
     /**
      * @param node
      * @returns {ESTree.Literal}
@@ -57,11 +37,7 @@ export class ObjectExpressionTransformer extends AbstractNodeTransformer {
         return {
             type: NodeType.Literal,
             value: node.name,
-            raw: `'${node.name}'`,
-            'x-verbatim-property': {
-                content : `'${Utils.stringToUnicodeEscapeSequence(node.name)}'`,
-                precedence: escodegen.Precedence.Primary
-            }
+            raw: `'${node.name}'`
         };
     }
 
@@ -90,9 +66,7 @@ export class ObjectExpressionTransformer extends AbstractNodeTransformer {
                     property.shorthand = false;
                 }
 
-                if (Node.isLiteralNode(property.key)) {
-                    property.key = ObjectExpressionTransformer.transformLiteralPropertyKey(property.key);
-                } else if (Node.isIdentifierNode(property.key)) {
+                if (Node.isIdentifierNode(property.key)) {
                     property.key = ObjectExpressionTransformer.transformIdentifierPropertyKey(property.key);
                 }
             });

+ 1 - 1
src/options/presets/Default.ts

@@ -21,5 +21,5 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     stringArray: true,
     stringArrayEncoding: false,
     stringArrayThreshold: 0.8,
-    unicodeEscapeSequence: true
+    unicodeEscapeSequence: false
 });

+ 1 - 1
src/options/presets/NoCustomNodes.ts

@@ -21,5 +21,5 @@ export const NO_CUSTOM_NODES_PRESET: TInputOptions = Object.freeze({
     stringArray: false,
     stringArrayEncoding: false,
     stringArrayThreshold: 0,
-    unicodeEscapeSequence: true
+    unicodeEscapeSequence: false
 });

+ 1 - 1
test/dev/dev.ts

@@ -18,7 +18,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../src/options/presets/NoCustomNodes'
                         console.log('qrs');
                         console.log('tuv');
                         console.log('wxy');
-                        console.log('z');
+                        console.log('w');
                     };
                 
                     foo();

+ 9 - 3
test/functional-tests/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.spec.ts

@@ -9,7 +9,9 @@ import { readFileAsString } from '../../../helpers/readFileAsString';
 import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
 
 describe('ConsoleOutputDisableExpressionNode', () => {
-    const regExp = /(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*)*'\]\['(\\x[a-f0-9]*)*'\] *= *_0x([a-f0-9]){4,6};){7}/u;
+    const consoleLogRegExp: RegExp = /_0x([a-f0-9]){4,6}\['console'\]\['log'\] *= *_0x([a-f0-9]){4,6};/u;
+    const consoleErrorRegExp: RegExp = /_0x([a-f0-9]){4,6}\['console'\]\['error'\] *= *_0x([a-f0-9]){4,6};/u;
+    const consoleWarnRegExp: RegExp = /_0x([a-f0-9]){4,6}\['console'\]\['warn'\] *= *_0x([a-f0-9]){4,6};/u;
 
     it('should correctly append `ConsoleOutputDisableExpressionNode` custom node into the obfuscated code if `disableConsoleOutput` option is set', () => {
         let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
@@ -20,7 +22,9 @@ describe('ConsoleOutputDisableExpressionNode', () => {
             }
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(), regExp);
+        assert.match(obfuscationResult.getObfuscatedCode(), consoleLogRegExp);
+        assert.match(obfuscationResult.getObfuscatedCode(), consoleErrorRegExp);
+        assert.match(obfuscationResult.getObfuscatedCode(), consoleWarnRegExp);
     });
 
     it('should\'t append `ConsoleOutputDisableExpressionNode` custom node into the obfuscated code if `disableConsoleOutput` option is not set', () => {
@@ -33,6 +37,8 @@ describe('ConsoleOutputDisableExpressionNode', () => {
             }
         );
 
-        assert.notMatch(obfuscationResult.getObfuscatedCode(), regExp);
+        assert.notMatch(obfuscationResult.getObfuscatedCode(), consoleLogRegExp);
+        assert.notMatch(obfuscationResult.getObfuscatedCode(), consoleErrorRegExp);
+        assert.notMatch(obfuscationResult.getObfuscatedCode(), consoleWarnRegExp);
     });
 });

+ 14 - 9
test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts

@@ -117,9 +117,9 @@ describe('JavaScriptObfuscator', () => {
             );
         });
 
-        it('should obfuscate simple code with literal variable value', () => {
-            let pattern1: RegExp = /^var _0x(\w){4} *= *\['(\\[x|u]\d+)+'\];/,
-                pattern2: RegExp = /var *test *= *_0x(\w){4}\('0x0'\);$/,
+        it('should obfuscate simple code with latin literal variable value', () => {
+            let stringArrayLatinRegExp: RegExp = /^var _0x(\w){4} *= *\['abc'\];/,
+                stringArrayCallRegExp: RegExp = /var *test *= *_0x(\w){4}\('0x0'\);$/,
                 obfuscatedCode1: string = JavaScriptObfuscator.obfuscate(
                     readFileAsString(__dirname + '/fixtures/simple-input-2.js'),
                     {
@@ -127,7 +127,15 @@ describe('JavaScriptObfuscator', () => {
                         stringArray: true,
                         stringArrayThreshold: 1
                     }
-                ).getObfuscatedCode(),
+                ).getObfuscatedCode();
+
+            assert.match(obfuscatedCode1, stringArrayLatinRegExp);
+            assert.match(obfuscatedCode1, stringArrayCallRegExp);
+        });
+
+        it('should obfuscate simple code with cyrillic literal variable value', () => {
+            let stringArrayCyrillicRegExp: RegExp = /^var _0x(\w){4} *= *\['(\\u\d+)+'\];/,
+                stringArrayCallRegExp: RegExp = /var *test *= *_0x(\w){4}\('0x0'\);$/,
                 obfuscatedCode2: string = JavaScriptObfuscator.obfuscate(
                     readFileAsString(__dirname + '/fixtures/simple-input-cyrillic.js'),
                     {
@@ -137,11 +145,8 @@ describe('JavaScriptObfuscator', () => {
                     }
                 ).getObfuscatedCode();
 
-            assert.match(obfuscatedCode1, pattern1);
-            assert.match(obfuscatedCode1, pattern2);
-
-            assert.match(obfuscatedCode2, pattern1);
-            assert.match(obfuscatedCode2, pattern2);
+            assert.match(obfuscatedCode2, stringArrayCyrillicRegExp);
+            assert.match(obfuscatedCode2, stringArrayCallRegExp);
         });
 
         it('should returns same code every time with same `seed`', function () {

+ 17 - 15
test/functional-tests/node-transformers/control-flow-transformers/block-statement-control-flow-transformer/BlockStatementControlFlowTransformer.spec.ts

@@ -10,14 +10,16 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
 
 describe('BlockStatementControlFlowTransformer', () => {
     describe('transformNode (blockStatementNode: ESTree.BlockStatement): ESTree.Node', () => {
+        const switchCaseMapStringRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *\{'.*' *: *'(.*)'\};/;
+        const switchCaseMapVariableRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *_0x(?:[a-f0-9]){4,6}\['.*'\]\['split'\]\('\\x7c'\)/;
+
         describe('variant #1: 5 simple statements', () => {
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 readFileAsString(__dirname + '/fixtures/input-1.js'),
                 {
                     ...NO_CUSTOM_NODES_PRESET,
                     controlFlowFlattening: true,
-                    controlFlowFlatteningThreshold: 1,
-                    unicodeEscapeSequence: false
+                    controlFlowFlatteningThreshold: 1
                 }
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
@@ -32,9 +34,8 @@ describe('BlockStatementControlFlowTransformer', () => {
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const switchCaseLength: number = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
 
-            const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *'(.*?)'/;
-            const switchCaseMapMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapRegExp);
-            const switchCaseMapMatch: string = switchCaseMapMatches[1];
+            const switchCaseMapStringMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapStringRegExp);
+            const switchCaseMapMatch: string = switchCaseMapStringMatches[1];
             const switchCaseMap: string[] = switchCaseMapMatch.replace(/\\x7c/g, '|').split('|').sort();
 
             it('should save all statements', () => {
@@ -52,6 +53,7 @@ describe('BlockStatementControlFlowTransformer', () => {
 
             it('should create variable with order of switch cases sequence', () => {
                 assert.deepEqual(switchCaseMap, ['0', '1', '2', '3', '4']);
+                assert.match(obfuscatedCode, switchCaseMapVariableRegExp);
             });
         });
 
@@ -77,9 +79,8 @@ describe('BlockStatementControlFlowTransformer', () => {
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const switchCaseLength: number = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
 
-            const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *'(.*?)'/;
-            const switchCaseMapMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapRegExp);
-            const switchCaseMapMatch: string = switchCaseMapMatches[1];
+            const switchCaseMapStringMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapStringRegExp);
+            const switchCaseMapMatch: string = switchCaseMapStringMatches[1];
             const switchCaseMap: string[] = switchCaseMapMatch.replace(/\\x7c/g, '|').split('|').sort();
 
             it('should save all statements', () => {
@@ -97,6 +98,7 @@ describe('BlockStatementControlFlowTransformer', () => {
 
             it('should create variable with order of switch cases sequence', () => {
                 assert.deepEqual(switchCaseMap, ['0', '1', '2', '3', '4']);
+                assert.match(obfuscatedCode, switchCaseMapVariableRegExp);
             });
         });
 
@@ -111,7 +113,7 @@ describe('BlockStatementControlFlowTransformer', () => {
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
-            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *console\['(\\x[a-f0-9]*){3}'\]\(0x1\); *\} *\( *\) *\);$/;
+            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *console\['log'\]\(0x1\); *\} *\( *\) *\);$/;
 
             it('shouldn\'t transform block statement if statements length less than 5', () => {
                 assert.match(obfuscatedCode, statementRegExp);
@@ -129,7 +131,7 @@ describe('BlockStatementControlFlowTransformer', () => {
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
-            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-f0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
+            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-f0-9]){4,6} *= *0x1; *console\['log'\]\(0x1\);/;
 
             it('shouldn\'t transform block statement if block statement contain variable declaration with `const` kind', () => {
                 assert.match(obfuscatedCode, statementRegExp);
@@ -147,7 +149,7 @@ describe('BlockStatementControlFlowTransformer', () => {
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
-            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-f0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
+            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-f0-9]){4,6} *= *0x1; *console\['log'\]\(0x1\);/;
 
             it('shouldn\'t transform block statement if block statement contain variable declaration with `let` kind', () => {
                 assert.match(obfuscatedCode, statementRegExp);
@@ -165,7 +167,7 @@ describe('BlockStatementControlFlowTransformer', () => {
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
-            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *break; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
+            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *break; *console\['log'\]\(0x1\);/;
 
             it('shouldn\'t transform block statement if block statement contain break statement', () => {
                 assert.match(obfuscatedCode, statementRegExp);
@@ -183,7 +185,7 @@ describe('BlockStatementControlFlowTransformer', () => {
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
-            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *continue; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
+            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *continue; *console\['log'\]\(0x1\);/;
 
             it('shouldn\'t transform block statement if block statement contain continue statement', () => {
                 assert.match(obfuscatedCode, statementRegExp);
@@ -201,7 +203,7 @@ describe('BlockStatementControlFlowTransformer', () => {
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
-            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-f0-9]){4,6} *\( *\) *\{ *\} *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
+            const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-f0-9]){4,6} *\( *\) *\{ *\} *console\['log'\]\(0x1\);/;
 
             it('shouldn\'t transform block statement if block statement contain function declaration', () => {
                 assert.match(obfuscatedCode, statementRegExp);
@@ -222,7 +224,7 @@ describe('BlockStatementControlFlowTransformer', () => {
             );
 
             const regExp1: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/g;
-            const regExp2: RegExp = /\(function *\( *\) *\{ *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/g;
+            const regExp2: RegExp = /\(function *\( *\) *\{ *console\['log'\]\(0x1\);/g;
             const transformedStatementMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp1)!.length;
             const untouchedStatementMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp2)!.length;
 

+ 3 - 3
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer/BinaryExpressionControlFlowReplacer.spec.ts

@@ -20,7 +20,7 @@ describe('BinaryExpressionControlFlowReplacer', () => {
                 }
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(0x1, *0x2\);/;
+            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{3}'\]\(0x1, *0x2\);/;
 
             it('should replace binary expression node by call to control flow storage node', () => {
                 assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -47,8 +47,8 @@ describe('BinaryExpressionControlFlowReplacer', () => {
                         }
                     );
                     const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-                    const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x1, *0x2\);/;
-                    const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x2, *0x3\);/;
+                    const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['\w{3}'\])\(0x1, *0x2\);/;
+                    const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['\w{3}'\])\(0x2, *0x3\);/;
 
                     const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
                     const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);

+ 4 - 4
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec.ts

@@ -20,7 +20,7 @@ describe('CallExpressionControlFlowReplacer', () => {
                 }
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
+            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{3}'\]\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
 
             it('should replace call expression node by call to control flow storage node', () => {
                 assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -47,8 +47,8 @@ describe('CallExpressionControlFlowReplacer', () => {
                         }
                     );
                     const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-                    const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
-                    const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-f0-9]){4,6}, *0x2, *0x3\);/;
+                    const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['\w{3}'\])\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
+                    const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['\w{3}'\])\(_0x([a-f0-9]){4,6}, *0x2, *0x3\);/;
 
                     const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
                     const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
@@ -78,7 +78,7 @@ describe('CallExpressionControlFlowReplacer', () => {
                 }
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\\x73\\x75\\x6d'\]\(0x1, *0x2\);/;
+            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['sum'\]\(0x1, *0x2\);/;
 
             it('shouldn\'t replace call expression node by call to control flow storage node if call expression callee is member expression node', () => {
                 assert.match(obfuscatedCode, controlFlowStorageCallRegExp);

+ 4 - 4
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec.ts

@@ -20,7 +20,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
                 }
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!!\[\], *!\[\]\);/;
+            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{3}'\]\(!!\[\], *!\[\]\);/;
 
             it('should replace logical expression node by call to control flow storage node', () => {
                 assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -47,8 +47,8 @@ describe('LogicalExpressionControlFlowReplacer', () => {
                         }
                     );
                     const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-                    const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!!\[\], *!\[\]\);/;
-                    const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!\[\], *!!\[\]\);/;
+                    const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['\w{3}'\])\(!!\[\], *!\[\]\);/;
+                    const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['\w{3}'\])\(!\[\], *!!\[\]\);/;
 
                     const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
                     const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
@@ -78,7 +78,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
                 }
             );
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!_0x([a-f0-9]){4,6}, *!_0x([a-f0-9]){4,6}\);/;
+            const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{3}'\]\(!_0x([a-f0-9]){4,6}, *!_0x([a-f0-9]){4,6}\);/;
 
             it('should replace logical expression node with unary expression by call to control flow storage node', () => {
                 assert.match(obfuscatedCode, controlFlowStorageCallRegExp);

+ 6 - 6
test/functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec.ts

@@ -12,15 +12,15 @@ describe('FunctionControlFlowTransformer', () => {
     const variableMatch: string = '_0x([a-f0-9]){4,6}';
     const rootControlFlowStorageNodeMatch: string = `` +
         `var *${variableMatch} *= *\\{` +
-            `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
+            `'\\w{3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
                 `return *${variableMatch} *\\+ *${variableMatch};` +
             `\\}` +
         `\\};` +
     ``;
     const innerControlFlowStorageNodeMatch: string = `` +
         `var *${variableMatch} *= *\\{` +
-            `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
-                `return *${variableMatch}\\['(\\\\x[a-f0-9]*){3}'\\]\\(${variableMatch}, *${variableMatch}\\);` +
+            `'\\w{3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
+                `return *${variableMatch}\\['\\w{3}'\\]\\(${variableMatch}, *${variableMatch}\\);` +
             `\\}` +
         `\\};` +
     ``;
@@ -95,10 +95,10 @@ describe('FunctionControlFlowTransformer', () => {
             const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
             const regexp: RegExp = new RegExp(
                 `var *${variableMatch} *= *\\{` +
-                    `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
+                    `'\\w{3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
                         `return *${variableMatch} *\\+ *${variableMatch};` +
                     `\\}, *` +
-                    `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
+                    `'\\w{3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
                         `return *${variableMatch} *- *${variableMatch};` +
                     `\\}` +
                 `\\};`
@@ -130,7 +130,7 @@ describe('FunctionControlFlowTransformer', () => {
             const expectedValue: number = 0;
             const regExp: RegExp = new RegExp(
                 `var *[a-zA-Z]{6} *= *\\{` +
-                    `'(\\\\x[a-f0-9]*){3}' *: *function *_0x[0-9] *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
+                    `'\\w{3}' *: *function *_0x[0-9] *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
                         `return *${variableMatch} *\\+ *${variableMatch};` +
                     `\\}` +
                 `\\};`

+ 3 - 3
test/functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec.ts

@@ -18,7 +18,7 @@ describe('MemberExpressionTransformer', () => {
                 }
             );
 
-            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *console\['\\x6c\\x6f\\x67'\];/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *console\['log'\];/);
         });
 
         it('should replace member expression dot notation call by square brackets call to unicode array', () => {
@@ -31,7 +31,7 @@ describe('MemberExpressionTransformer', () => {
                 }
             );
 
-            assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4} *= *\['log'\];/);
             assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/);
         });
     });
@@ -47,7 +47,7 @@ describe('MemberExpressionTransformer', () => {
                 }
             );
 
-            assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4} *= *\['log'\];/);
             assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/);
         });
 

+ 2 - 2
test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts

@@ -19,7 +19,7 @@ describe('MethodDefinitionTransformer', () => {
             }
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /\['\\x62\\x61\\x72'\]\(\)\{\}/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /\['bar'\]\(\)\{\}/);
     });
 
     it('should replace method definition node `key` property with unicode array call', () => {
@@ -32,7 +32,7 @@ describe('MethodDefinitionTransformer', () => {
             }
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4} *= *\['\\x62\\x61\\x72'\];/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4} *= *\['bar'\];/);
         assert.match(obfuscationResult.getObfuscatedCode(),  /\[_0x([a-f0-9]){4}\('0x0'\)\]\(\)\{\}/);
     });
 

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/catch-clause-transformer/CatchClauseTransformer.spec.ts

@@ -18,7 +18,7 @@ describe('CatchClauseTransformer', () => {
         );
         const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
         const paramNameRegExp: RegExp = /catch *\((_0x([a-f0-9]){4,6})\) *\{/;
-        const bodyParamNameRegExp: RegExp = /console\['\\x6c\\x6f\\x67'\]\((_0x([a-f0-9]){4,6})\);/;
+        const bodyParamNameRegExp: RegExp = /console\['log'\]\((_0x([a-f0-9]){4,6})\);/;
 
         it('should transform catch clause node', () => {
             assert.match(obfuscatedCode, paramNameRegExp);

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts

@@ -22,7 +22,7 @@ describe('FunctionTransformer', () => {
             const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
                 .match(/var _0x[a-f0-9]{4,6} *= *function *\((_0x[a-f0-9]{4,6})\) *\{/);
             const functionBodyIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
-                .match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
+                .match(/console\['log'\]\((_0x[a-f0-9]{4,6})\)/);
 
             const functionParamIdentifierName: string = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
             const functionBodyIdentifierName: string = (<RegExpMatchArray>functionBodyIdentifierMatch)[1];

+ 38 - 38
test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts

@@ -10,59 +10,55 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
 
 describe('LiteralTransformer', () => {
     describe('transformation of literal node with string value', () => {
-        it('should replace literal node value with unicode escape sequence', () => {
+        it('should replace literal node value with value from string array', () => {
             let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 readFileAsString(__dirname + '/fixtures/simple-input.js'),
                 {
-                    ...NO_CUSTOM_NODES_PRESET
+                    ...NO_CUSTOM_NODES_PRESET,
+                    stringArray: true,
+                    stringArrayThreshold: 1
                 }
             );
 
-            assert.match(obfuscationResult.getObfuscatedCode(),  /^var *test *= *'\\x74\\x65\\x73\\x74';$/);
+            assert.match(
+                obfuscationResult.getObfuscatedCode(),
+                /^var *_0x([a-f0-9]){4} *= *\['test'\];/
+            );
+            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
         });
 
-        it('should replace literal node value with unicode escape sequence from string array', () => {
+        it('shouldn\'t replace literal node value with value from string array if `stringArray` option is disabled', () => {
             let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 readFileAsString(__dirname + '/fixtures/simple-input.js'),
                 {
-                    ...NO_CUSTOM_NODES_PRESET,
-                    stringArray: true,
-                    stringArrayThreshold: 1
+                    ...NO_CUSTOM_NODES_PRESET
                 }
             );
 
             assert.match(
                 obfuscationResult.getObfuscatedCode(),
-                /^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
+                /^var *test *= *'test';/
             );
-            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
         });
 
-        it('should create only one item in string array for same literal node values', () => {
-            let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                readFileAsString(__dirname + '/fixtures/same-literal-values.js'),
+        it('should\'t throw an error when string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
+            assert.doesNotThrow(() => JavaScriptObfuscator.obfuscate(
+                readFileAsString(__dirname + '/fixtures/error-when-non-latin.js'),
                 {
                     ...NO_CUSTOM_NODES_PRESET,
                     stringArray: true,
                     stringArrayThreshold: 1
                 }
-            );
-
-            assert.match(
-                obfuscationResult.getObfuscatedCode(),
-                /^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
-            );
-            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
+            ));
         });
 
-        it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` is disabled', () => {
+        it('should create only one item in string array for same literal node values', () => {
             let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                readFileAsString(__dirname + '/fixtures/simple-input.js'),
+                readFileAsString(__dirname + '/fixtures/same-literal-values.js'),
                 {
                     ...NO_CUSTOM_NODES_PRESET,
                     stringArray: true,
-                    stringArrayThreshold: 1,
-                    unicodeEscapeSequence: false
+                    stringArrayThreshold: 1
                 }
             );
 
@@ -73,31 +69,35 @@ describe('LiteralTransformer', () => {
             assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
         });
 
-        it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` and `stringArray` are disabled', () => {
+        it('should replace literal node value with unicode escape sequence if `unicodeEscapeSequence` is enabled', () => {
             let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 readFileAsString(__dirname + '/fixtures/simple-input.js'),
                 {
                     ...NO_CUSTOM_NODES_PRESET,
-                    unicodeEscapeSequence: false
+                    unicodeEscapeSequence: true
+
                 }
             );
 
-            assert.match(
-                obfuscationResult.getObfuscatedCode(),
-                /^var *test *= *'test';/
-            );
+            assert.match(obfuscationResult.getObfuscatedCode(),  /^var *test *= *'\\x74\\x65\\x73\\x74';$/);
         });
 
-        it('should\'t throw an error when string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
-            assert.doesNotThrow(() => JavaScriptObfuscator.obfuscate(
-                readFileAsString(__dirname + '/fixtures/error-when-non-latin.js'),
+        it('should replace literal node value with unicode escape sequence from string array if `unicodeEscapeSequence` is enabled', () => {
+            let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                readFileAsString(__dirname + '/fixtures/simple-input.js'),
                 {
                     ...NO_CUSTOM_NODES_PRESET,
                     stringArray: true,
                     stringArrayThreshold: 1,
-                    unicodeEscapeSequence: false
+                    unicodeEscapeSequence: true
                 }
-            ));
+            );
+
+            assert.match(
+                obfuscationResult.getObfuscatedCode(),
+                /^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
+            );
+            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
         });
 
         it('shouldn\'t replace short literal node value with value from string array', () => {
@@ -110,7 +110,7 @@ describe('LiteralTransformer', () => {
                 }
             );
 
-            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *'\\x74\\x65';/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *'te';/);
         });
 
         it('should replace literal node value with value from string array encoded using base64', () => {
@@ -126,7 +126,7 @@ describe('LiteralTransformer', () => {
 
             assert.match(
                 obfuscationResult.getObfuscatedCode(),
-                /^var *_0x([a-f0-9]){4} *= *\['\\x64\\x47\\x56\\x7a\\x64\\x41\\x3d\\x3d'\];/
+                /^var *_0x([a-f0-9]){4} *= *\['dGVzdA\\x3d\\x3d'\];/
             );
             assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
         });
@@ -144,7 +144,7 @@ describe('LiteralTransformer', () => {
 
             assert.match(
                 obfuscationResult.getObfuscatedCode(),
-                /var *test *= *_0x([a-f0-9]){4}\('0x0', '(\\x[a-f0-9]*){4}'\);/
+                /var *test *= *_0x([a-f0-9]){4}\('0x0', '(?:\w|(?:\\x[a-f0-9]*)){4}'\);/
             );
         });
 
@@ -162,7 +162,7 @@ describe('LiteralTransformer', () => {
             );
 
             const regExp1: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/g;
-            const regExp2: RegExp = /var *test *= *'\\x74\\x65\\x73\\x74';/g;
+            const regExp2: RegExp = /var *test *= *'test';/g;
             const stringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp1)!.length;
             const noStringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp2)!.length;
 

+ 3 - 14
test/functional-tests/node-transformers/obfuscating-transformers/object-expression-transformer/ObjectExpressionTransformer.spec.ts

@@ -9,18 +9,7 @@ import { readFileAsString } from '../../../../helpers/readFileAsString';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
 
 describe('ObjectExpressionTransformer', () => {
-    it('should replace object expression node `key` property with literal value by unicode value', () => {
-        let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-            readFileAsString(__dirname + '/fixtures/property-with-literal-value.js'),
-            {
-                ...NO_CUSTOM_NODES_PRESET
-            }
-        );
-
-        assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *\{'\\x66\\x6f\\x6f':0x0\};/);
-    });
-
-    it('should replace object expression node `key` property with identifier value by unicode value', () => {
+    it('should replace object expression node `key` property with identifier value by property with literal value', () => {
         let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             readFileAsString(__dirname + '/fixtures/property-with-identifier-value.js'),
             {
@@ -28,7 +17,7 @@ describe('ObjectExpressionTransformer', () => {
             }
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *\{'\\x66\\x6f\\x6f':0x0\};/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *\{'foo':0x0\};/);
     });
 
     it('should correct convert shorthand ES6 object expression to non-shorthand object expression', () => {
@@ -41,7 +30,7 @@ describe('ObjectExpressionTransformer', () => {
 
         assert.match(
             obfuscationResult.getObfuscatedCode(),
-            /var *_0x[a-f0-9]{4,6} *= *\{'\\x61': *_0x[a-f0-9]{4,6}\, *'\\x62': *_0x[a-f0-9]{4,6}\};/
+            /var *_0x[a-f0-9]{4,6} *= *\{'a': *_0x[a-f0-9]{4,6}\, *'b': *_0x[a-f0-9]{4,6}\};/
         );
     });
 });

+ 16 - 16
test/functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec.ts

@@ -17,8 +17,8 @@ describe('VariableDeclarationTransformer', () => {
             }
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4,6} *= *'\\x61\\x62\\x63';/);
-        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-f0-9]){4,6} *= *'abc';/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['log'\]\(_0x([a-f0-9]){4,6}\);/);
     });
 
     it('should not transform `variableDeclaration` node if parent block scope node is `Program` node', () => {
@@ -30,7 +30,7 @@ describe('VariableDeclarationTransformer', () => {
         );
 
         assert.match(obfuscationResult.getObfuscatedCode(),  /var *test *= *0xa;/);
-        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(test\);/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['log'\]\(test\);/);
     });
 
     it('should transform variable call (`identifier` node) outside of block scope of node in which this variable was declared with `var` kind', () => {
@@ -41,7 +41,7 @@ describe('VariableDeclarationTransformer', () => {
             }
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['log'\]\(_0x([a-f0-9]){4,6}\);/);
     });
 
     it('should not transform variable call (`identifier` node) outside of block scope of node in which this variable was declared with `let` kind', () => {
@@ -52,7 +52,7 @@ describe('VariableDeclarationTransformer', () => {
             }
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(test\);/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['log'\]\(test\);/);
     });
 
     describe(`variable calls before variable declaration`, () => {
@@ -68,11 +68,11 @@ describe('VariableDeclarationTransformer', () => {
         });
 
         it('should transform variable call (`identifier` node name) before variable declaration if this call is inside function body', () => {
-            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\['\\x69\\x74\\x65\\x6d'\]\);/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['log'\]\(_0x([a-f0-9]){4,6}\['item'\]\);/);
         });
 
         it('should transform variable call (`identifier` node name) before variable declaration', () => {
-            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['log'\]\(_0x([a-f0-9]){4,6}\);/);
         });
     });
 
@@ -90,9 +90,9 @@ describe('VariableDeclarationTransformer', () => {
         const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
             .match(/function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/);
         const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
-            .match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
+            .match(/console\['log'\]\((_0x[a-f0-9]{4,6})\)/);
         const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
-            .match(/return\{'\\x74':(_0x[a-f0-9]{4,6})\}/);
+            .match(/return\{'t':(_0x[a-f0-9]{4,6})\}/);
         const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
             .match(/var *(_0x[a-f0-9]{4,6});/);
 
@@ -135,9 +135,9 @@ describe('VariableDeclarationTransformer', () => {
         const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
             .match(/function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/);
         const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
-            .match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
+            .match(/console\['log'\]\((_0x[a-f0-9]{4,6})\)/);
         const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
-            .match(/return\{'\\x74':(_0x[a-f0-9]{4,6})\}/);
+            .match(/return\{'t':(_0x[a-f0-9]{4,6})\}/);
         const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
             .match(/var *(_0x[a-f0-9]{4,6});/);
 
@@ -175,7 +175,7 @@ describe('VariableDeclarationTransformer', () => {
                 }
             );
 
-            assert.match(obfuscationResult.getObfuscatedCode(),  /var _0x([a-f0-9]){4,6} *= *\{'\\x74\\x65\\x73\\x74/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /var _0x([a-f0-9]){4,6} *= *\{'test/);
         });
 
         it('shouldn\'t replace computed member expression identifier', () => {
@@ -186,7 +186,7 @@ describe('VariableDeclarationTransformer', () => {
                 }
             );
 
-            assert.match(obfuscationResult.getObfuscatedCode(),  /_0x([a-f0-9]){4,6}\['\\x74\\x65\\x73\\x74'\]/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /_0x([a-f0-9]){4,6}\['test'\]/);
         });
     });
 
@@ -200,8 +200,8 @@ describe('VariableDeclarationTransformer', () => {
         const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
         it('shouldn\'t transform object pattern variable declarator', () => {
-            const objectPatternVariableDeclaratorMatch: RegExp = /var *\{ *bar *\} *= *\{ *'\\x62\\x61\\x72' *: *'\\x66\\x6f\\x6f' *\};/;
-            const variableUsageMatch: RegExp = /console\['\\x6c\\x6f\\x67'\]\(bar\);/;
+            const objectPatternVariableDeclaratorMatch: RegExp = /var *\{ *bar *\} *= *\{ *'bar' *: *'foo' *\};/;
+            const variableUsageMatch: RegExp = /console\['log'\]\(bar\);/;
 
             assert.match(obfuscatedCode, objectPatternVariableDeclaratorMatch);
             assert.match(obfuscatedCode, variableUsageMatch);
@@ -218,7 +218,7 @@ describe('VariableDeclarationTransformer', () => {
         const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
         const objectPatternVariableDeclaratorMatch: RegExp = /var *\[ *(_0x([a-f0-9]){4,6}), *(_0x([a-f0-9]){4,6}) *\] *= *\[0x1, *0x2\];/;
-        const variableUsageMatch: RegExp = /console\['\\x6c\\x6f\\x67'\]\((_0x([a-f0-9]){4,6}), *(_0x([a-f0-9]){4,6})\);/;
+        const variableUsageMatch: RegExp = /console\['log'\]\((_0x([a-f0-9]){4,6}), *(_0x([a-f0-9]){4,6})\);/;
 
         const objectPatternIdentifierName1: string = obfuscatedCode.match(objectPatternVariableDeclaratorMatch)![1];
         const objectPatternIdentifierName2: string = obfuscatedCode.match(objectPatternVariableDeclaratorMatch)![2];