From b0a18660bbea92b9ab8846b2b6314d888fb43b08 Mon Sep 17 00:00:00 2001 From: sanex3339 Date: Sat, 17 Dec 2016 23:59:00 +0300 Subject: [PATCH] controlFlowFlatteningThreshold option tests for BinaryExpressionControlFlowReplacer --- README.md | 9 ++ dist/index.js | 128 ++++++++++-------- src/cli/JavaScriptObfuscatorCLI.ts | 5 + src/interfaces/options/IOptions.d.ts | 1 + .../FunctionControlFlowTransformer.ts | 7 +- src/options/Options.ts | 8 ++ src/options/OptionsNormalizer.ts | 34 ++++- src/preset-options/DefaultPreset.ts | 1 + src/preset-options/NoCustomNodesPreset.ts | 1 + test/dev/dev.ts | 75 +--------- ...nary-expression-control-flow-replacer-1.js | 3 + ...nary-expression-control-flow-replacer-2.js | 4 + ...inaryExpressionControlFlowReplacer.spec.ts | 73 ++++++++++ .../CatchClauseObfuscator.spec.ts | 8 +- test/index.spec.ts | 3 +- .../{ => options}/OptionsNormalizer.spec.ts | 26 +++- 16 files changed, 238 insertions(+), 148 deletions(-) create mode 100644 test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-1.js create mode 100644 test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-2.js create mode 100644 test/functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.spec.ts rename test/unit-tests/{ => options}/OptionsNormalizer.spec.ts (84%) diff --git a/README.md b/README.md index 497a0173..d02e70ca 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,15 @@ Example: }()); ``` +### `controlFlowFlatteningThreshold` +Type: `number` Default: `0.75` Min: `0` Max: `1` + +The probability that the [`controlFlowFlattening`](#controlflowflattening) transformation will be applied to the node. + +This setting is especially useful for large code size because large amount of control flow transformations can slow down your code and increase code size. + +`controlFlowFlatteningThreshold: 0` equals to `controlFlowFlattening: false`. + ### `debugProtection` Type: `boolean` Default: `false` diff --git a/dist/index.js b/dist/index.js index 77f5c964..7a4be24d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -577,7 +577,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var AbstractCustomNode = function () { function AbstractCustomNode(options) { _classCallCheck(this, AbstractCustomNode); @@ -609,12 +609,6 @@ exports.AbstractCustomNode = AbstractCustomNode; /***/ }, /* 8 */ -/***/ function(module, exports) { - -module.exports = require("string-template"); - -/***/ }, -/* 9 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -624,7 +618,7 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var escodegen = __webpack_require__(17); +var escodegen = __webpack_require__(18); var esprima = __webpack_require__(32); var estraverse = __webpack_require__(6); var NodeType_1 = __webpack_require__(10); @@ -797,6 +791,12 @@ var NodeUtils = function () { NodeUtils.nodesWithBlockScope = [NodeType_1.NodeType.ArrowFunctionExpression, NodeType_1.NodeType.FunctionDeclaration, NodeType_1.NodeType.FunctionExpression, NodeType_1.NodeType.MethodDefinition, NodeType_1.NodeType.Program]; exports.NodeUtils = NodeUtils; +/***/ }, +/* 9 */ +/***/ function(module, exports) { + +module.exports = require("string-template"); + /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { @@ -1104,12 +1104,6 @@ exports.NodeAppender = NodeAppender; /***/ }, /* 17 */ -/***/ function(module, exports) { - -module.exports = require("escodegen"); - -/***/ }, -/* 18 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1172,6 +1166,12 @@ var AbstractCustomNodeGroup = function () { AbstractCustomNodeGroup = __decorate([inversify_1.injectable(), __param(0, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.IOptions)), __metadata('design:paramtypes', [Object])], AbstractCustomNodeGroup); exports.AbstractCustomNodeGroup = AbstractCustomNodeGroup; +/***/ }, +/* 18 */ +/***/ function(module, exports) { + +module.exports = require("escodegen"); + /***/ }, /* 19 */ /***/ function(module, exports) { @@ -1232,6 +1232,7 @@ var SourceMapMode_1 = __webpack_require__(19); exports.NO_CUSTOM_NODES_PRESET = Object.freeze({ compact: true, controlFlowFlattening: false, + controlFlowFlatteningThreshold: 0, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: false, @@ -1529,6 +1530,7 @@ var SourceMapMode_1 = __webpack_require__(19); exports.DEFAULT_PRESET = Object.freeze({ compact: true, controlFlowFlattening: false, + controlFlowFlatteningThreshold: 0.75, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: true, @@ -1700,7 +1702,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); var esprima = __webpack_require__(32); -var escodegen = __webpack_require__(17); +var escodegen = __webpack_require__(18); var JavaScriptObfuscatorInternal = JavaScriptObfuscatorInternal_1 = function () { function JavaScriptObfuscatorInternal(obfuscator, sourceMapCorrector, options) { _classCallCheck(this, JavaScriptObfuscatorInternal); @@ -1853,7 +1855,7 @@ var NodeType_1 = __webpack_require__(10); var ObfuscationEvents_1 = __webpack_require__(14); var VisitorDirection_1 = __webpack_require__(66); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var Obfuscator = Obfuscator_1 = function () { function Obfuscator(stackTraceAnalyzer, obfuscationEventEmitter, customNodeGroupStorage, nodeTransformersFactory, options) { _classCallCheck(this, Obfuscator); @@ -2142,7 +2144,7 @@ var JavaScriptObfuscatorCLI = function () { }, { key: "configureCommands", value: function configureCommands() { - this.commands = new commander.Command().version(JavaScriptObfuscatorCLI.getBuildVersion(), '-v, --version').usage(' [options]').option('-o, --output ', 'Output path for obfuscated code').option('--compact ', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean).option('--controlFlowFlattening ', 'Enables control flow flattening', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtection ', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtectionInterval ', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--disableConsoleOutput ', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean).option('--domainLock ', 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)', function (val) { + this.commands = new commander.Command().version(JavaScriptObfuscatorCLI.getBuildVersion(), '-v, --version').usage(' [options]').option('-o, --output ', 'Output path for obfuscated code').option('--compact ', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean).option('--controlFlowFlattening ', 'Enables control flow flattening', JavaScriptObfuscatorCLI.parseBoolean).option('--controlFlowFlatteningThreshold ', 'The probability that the control flow flattening transformation will be applied to the node', parseFloat).option('--debugProtection ', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtectionInterval ', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--disableConsoleOutput ', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean).option('--domainLock ', 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)', function (val) { return val.split(','); }).option('--reservedNames ', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', function (val) { return val.split(','); @@ -2561,7 +2563,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(98); var Initializable_1 = __webpack_require__(3); var AbstractCustomNode_1 = __webpack_require__(7); @@ -2634,7 +2636,7 @@ var ServiceIdentifiers_1 = __webpack_require__(1); var Initializable_1 = __webpack_require__(3); var CustomNodes_1 = __webpack_require__(13); var ObfuscationEvents_1 = __webpack_require__(14); -var AbstractCustomNodeGroup_1 = __webpack_require__(18); +var AbstractCustomNodeGroup_1 = __webpack_require__(17); var NodeAppender_1 = __webpack_require__(16); var RandomGeneratorUtils_1 = __webpack_require__(2); var ConsoleOutputCustomNodeGroup = function (_AbstractCustomNodeGr) { @@ -2726,7 +2728,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var BinaryExpressionFunctionTemplate_1 = __webpack_require__(99); var AbstractCustomNode_1 = __webpack_require__(7); @@ -2796,7 +2798,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var ControlFlowStorageCallTemplate_1 = __webpack_require__(100); var AbstractCustomNode_1 = __webpack_require__(7); @@ -2873,7 +2875,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var ControlFlowStorageTemplate_1 = __webpack_require__(101); var AbstractCustomNode_1 = __webpack_require__(7); @@ -2942,7 +2944,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(102); var AbstractCustomNode_1 = __webpack_require__(7); @@ -3010,7 +3012,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(103); var AbstractCustomNode_1 = __webpack_require__(7); @@ -3078,7 +3080,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var DebugProtectionFunctionTemplate_1 = __webpack_require__(104); var AbstractCustomNode_1 = __webpack_require__(7); @@ -3149,7 +3151,7 @@ var ServiceIdentifiers_1 = __webpack_require__(1); var Initializable_1 = __webpack_require__(3); var CustomNodes_1 = __webpack_require__(13); var ObfuscationEvents_1 = __webpack_require__(14); -var AbstractCustomNodeGroup_1 = __webpack_require__(18); +var AbstractCustomNodeGroup_1 = __webpack_require__(17); var NodeAppender_1 = __webpack_require__(16); var RandomGeneratorUtils_1 = __webpack_require__(2); var DebugProtectionCustomNodeGroup = function (_AbstractCustomNodeGr) { @@ -3246,7 +3248,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var DomainLockNodeTemplate_1 = __webpack_require__(105); var AbstractCustomNode_1 = __webpack_require__(7); @@ -3327,7 +3329,7 @@ var ServiceIdentifiers_1 = __webpack_require__(1); var Initializable_1 = __webpack_require__(3); var CustomNodes_1 = __webpack_require__(13); var ObfuscationEvents_1 = __webpack_require__(14); -var AbstractCustomNodeGroup_1 = __webpack_require__(18); +var AbstractCustomNodeGroup_1 = __webpack_require__(17); var NodeAppender_1 = __webpack_require__(16); var RandomGeneratorUtils_1 = __webpack_require__(2); var DomainLockCustomNodeGroup = function (_AbstractCustomNodeGr) { @@ -3428,7 +3430,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var ObfuscationEvents_1 = __webpack_require__(14); var Initializable_1 = __webpack_require__(3); var SingleNodeCallControllerTemplate_1 = __webpack_require__(97); @@ -3515,7 +3517,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var NoCustomNodesPreset_1 = __webpack_require__(21); var SelfDefendingTemplate_1 = __webpack_require__(106); @@ -3590,7 +3592,7 @@ var ServiceIdentifiers_1 = __webpack_require__(1); var Initializable_1 = __webpack_require__(3); var CustomNodes_1 = __webpack_require__(13); var ObfuscationEvents_1 = __webpack_require__(14); -var AbstractCustomNodeGroup_1 = __webpack_require__(18); +var AbstractCustomNodeGroup_1 = __webpack_require__(17); var NodeAppender_1 = __webpack_require__(16); var RandomGeneratorUtils_1 = __webpack_require__(2); var SelfDefendingCustomNodeGroup = function (_AbstractCustomNodeGr) { @@ -3691,7 +3693,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var StringArrayEncoding_1 = __webpack_require__(22); var Initializable_1 = __webpack_require__(3); var NoCustomNodesPreset_1 = __webpack_require__(21); @@ -3806,7 +3808,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var StringArrayTemplate_1 = __webpack_require__(111); var AbstractCustomNode_1 = __webpack_require__(7); @@ -3894,7 +3896,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var format = __webpack_require__(8); +var format = __webpack_require__(9); var Initializable_1 = __webpack_require__(3); var NoCustomNodesPreset_1 = __webpack_require__(21); var SelfDefendingTemplate_1 = __webpack_require__(112); @@ -3989,7 +3991,7 @@ var ServiceIdentifiers_1 = __webpack_require__(1); var Initializable_1 = __webpack_require__(3); var CustomNodes_1 = __webpack_require__(13); var ObfuscationEvents_1 = __webpack_require__(14); -var AbstractCustomNodeGroup_1 = __webpack_require__(18); +var AbstractCustomNodeGroup_1 = __webpack_require__(17); var NodeAppender_1 = __webpack_require__(16); var RandomGeneratorUtils_1 = __webpack_require__(2); var Utils_1 = __webpack_require__(5); @@ -4170,7 +4172,7 @@ var AbstractNodeTransformer_1 = __webpack_require__(11); var Node_1 = __webpack_require__(4); var NodeAppender_1 = __webpack_require__(16); var NodeControlFlowReplacers_1 = __webpack_require__(28); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var RandomGeneratorUtils_1 = __webpack_require__(2); var FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = function (_AbstractNodeTransfor) { _inherits(FunctionControlFlowTransformer, _AbstractNodeTransfor); @@ -4213,7 +4215,7 @@ var FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = function } estraverse.replace(functionNode.body, { enter: function enter(node, parentNode) { - if (RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomFloat(0, 1) > FunctionControlFlowTransformer_1.controlFlowReplacersThreshold) { + if (RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomFloat(0, 1) > _this2.options.controlFlowFlatteningThreshold) { return; } var controlFlowReplacerName = FunctionControlFlowTransformer_1.controlFlowReplacersMap.get(node.type); @@ -4288,7 +4290,6 @@ var FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = function return FunctionControlFlowTransformer; }(AbstractNodeTransformer_1.AbstractNodeTransformer); FunctionControlFlowTransformer.controlFlowReplacersMap = new Map([[NodeType_1.NodeType.BinaryExpression, NodeControlFlowReplacers_1.NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer]]); -FunctionControlFlowTransformer.controlFlowReplacersThreshold = 0.75; FunctionControlFlowTransformer.hostNodeSearchMinDepth = 2; FunctionControlFlowTransformer.hostNodeSearchMaxDepth = 10; FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = __decorate([inversify_1.injectable(), __param(0, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory>'])), __param(1, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory'])), __param(2, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory'])), __param(3, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.IOptions)), __metadata("design:paramtypes", [Function, Function, Function, Object])], FunctionControlFlowTransformer); @@ -4370,7 +4371,7 @@ var ServiceIdentifiers_1 = __webpack_require__(1); var CustomNodes_1 = __webpack_require__(13); var AbstractControlFlowReplacer_1 = __webpack_require__(69); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var RandomGeneratorUtils_1 = __webpack_require__(2); var BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1 = function (_AbstractControlFlowR) { _inherits(BinaryExpressionControlFlowReplacer, _AbstractControlFlowR); @@ -4470,7 +4471,7 @@ var NodeObfuscatorsReplacers_1 = __webpack_require__(12); var NodeType_1 = __webpack_require__(10); var AbstractNodeTransformer_1 = __webpack_require__(11); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var RandomGeneratorUtils_1 = __webpack_require__(2); var CatchClauseObfuscator = function (_AbstractNodeTransfor) { _inherits(CatchClauseObfuscator, _AbstractNodeTransfor); @@ -4562,7 +4563,7 @@ var NodeObfuscatorsReplacers_1 = __webpack_require__(12); var NodeType_1 = __webpack_require__(10); var AbstractNodeTransformer_1 = __webpack_require__(11); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var RandomGeneratorUtils_1 = __webpack_require__(2); var FunctionDeclarationObfuscator = function (_AbstractNodeTransfor) { _inherits(FunctionDeclarationObfuscator, _AbstractNodeTransfor); @@ -4658,7 +4659,7 @@ var NodeObfuscatorsReplacers_1 = __webpack_require__(12); var NodeType_1 = __webpack_require__(10); var AbstractNodeTransformer_1 = __webpack_require__(11); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var RandomGeneratorUtils_1 = __webpack_require__(2); var FunctionObfuscator = function (_AbstractNodeTransfor) { _inherits(FunctionObfuscator, _AbstractNodeTransfor); @@ -4760,7 +4761,7 @@ var NodeObfuscatorsReplacers_1 = __webpack_require__(12); var NodeType_1 = __webpack_require__(10); var AbstractNodeTransformer_1 = __webpack_require__(11); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var RandomGeneratorUtils_1 = __webpack_require__(2); var LabeledStatementObfuscator = function (_AbstractNodeTransfor) { _inherits(LabeledStatementObfuscator, _AbstractNodeTransfor); @@ -4847,7 +4848,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var escodegen = __webpack_require__(17); +var escodegen = __webpack_require__(18); var NodeObfuscatorsReplacers_1 = __webpack_require__(12); var AbstractNodeTransformer_1 = __webpack_require__(11); var Node_1 = __webpack_require__(4); @@ -4930,7 +4931,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var escodegen = __webpack_require__(17); +var escodegen = __webpack_require__(18); var estraverse = __webpack_require__(6); var NodeObfuscatorsReplacers_1 = __webpack_require__(12); var NodeType_1 = __webpack_require__(10); @@ -5118,7 +5119,7 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var escodegen = __webpack_require__(17); +var escodegen = __webpack_require__(18); var estraverse = __webpack_require__(6); var NodeType_1 = __webpack_require__(10); var AbstractNodeTransformer_1 = __webpack_require__(11); @@ -5228,7 +5229,7 @@ var NodeObfuscatorsReplacers_1 = __webpack_require__(12); var NodeType_1 = __webpack_require__(10); var AbstractNodeTransformer_1 = __webpack_require__(11); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var RandomGeneratorUtils_1 = __webpack_require__(2); var VariableDeclarationObfuscator = function (_AbstractNodeTransfor) { _inherits(VariableDeclarationObfuscator, _AbstractNodeTransfor); @@ -5635,6 +5636,7 @@ Options.validatorOptions = { }; __decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "compact", void 0); __decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "controlFlowFlattening", void 0); +__decorate([class_validator_1.IsNumber(), class_validator_1.Min(0), class_validator_1.Max(1), __metadata("design:type", Number)], Options.prototype, "controlFlowFlatteningThreshold", void 0); __decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "debugProtection", void 0); __decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "debugProtectionInterval", void 0); __decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "disableConsoleOutput", void 0); @@ -5722,6 +5724,14 @@ var OptionsNormalizer = function () { return normalizedOptions; } + }, { + key: "controlFlowFlatteningThresholdRule", + value: function controlFlowFlatteningThresholdRule(options) { + if (options.controlFlowFlatteningThreshold === 0) { + options = __assign({}, options, OptionsNormalizer.DISABLED_CONTROL_FLOW_FLATTENING_OPTIONS); + } + return options; + } }, { key: "domainLockRule", value: function domainLockRule(options) { @@ -5795,7 +5805,7 @@ var OptionsNormalizer = function () { key: "stringArrayRule", value: function stringArrayRule(options) { if (!options.stringArray) { - options = __assign({}, options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS); + options = __assign({}, options, OptionsNormalizer.DISABLED_STRING_ARRAY_OPTIONS); } return options; } @@ -5803,7 +5813,7 @@ var OptionsNormalizer = function () { key: "stringArrayEncodingRule", value: function stringArrayEncodingRule(options) { if (options.stringArrayEncoding === true) { - options = __assign({}, options, OptionsNormalizer.UNICODE_ARRAY_ENCODING_OPTIONS); + options = __assign({}, options, OptionsNormalizer.STRING_ARRAY_ENCODING_OPTIONS); } return options; } @@ -5811,7 +5821,7 @@ var OptionsNormalizer = function () { key: "stringArrayThresholdRule", value: function stringArrayThresholdRule(options) { if (options.stringArrayThreshold === 0) { - options = __assign({}, options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS); + options = __assign({}, options, OptionsNormalizer.DISABLED_STRING_ARRAY_OPTIONS); } return options; } @@ -5820,7 +5830,11 @@ var OptionsNormalizer = function () { return OptionsNormalizer; }(); -OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS = { +OptionsNormalizer.DISABLED_CONTROL_FLOW_FLATTENING_OPTIONS = { + controlFlowFlattening: false, + controlFlowFlatteningThreshold: 0 +}; +OptionsNormalizer.DISABLED_STRING_ARRAY_OPTIONS = { rotateStringArray: false, stringArray: false, stringArrayEncoding: false, @@ -5830,10 +5844,10 @@ OptionsNormalizer.SELF_DEFENDING_OPTIONS = { compact: true, selfDefending: true }; -OptionsNormalizer.UNICODE_ARRAY_ENCODING_OPTIONS = { +OptionsNormalizer.STRING_ARRAY_ENCODING_OPTIONS = { stringArrayEncoding: 'base64' }; -OptionsNormalizer.normalizerRules = [OptionsNormalizer.domainLockRule, OptionsNormalizer.selfDefendingRule, OptionsNormalizer.sourceMapBaseUrlRule, OptionsNormalizer.sourceMapFileNameRule, OptionsNormalizer.stringArrayRule, OptionsNormalizer.stringArrayEncodingRule, OptionsNormalizer.stringArrayThresholdRule]; +OptionsNormalizer.normalizerRules = [OptionsNormalizer.controlFlowFlatteningThresholdRule, OptionsNormalizer.domainLockRule, OptionsNormalizer.selfDefendingRule, OptionsNormalizer.sourceMapBaseUrlRule, OptionsNormalizer.sourceMapFileNameRule, OptionsNormalizer.stringArrayRule, OptionsNormalizer.stringArrayEncodingRule, OptionsNormalizer.stringArrayThresholdRule]; exports.OptionsNormalizer = OptionsNormalizer; /***/ }, @@ -5946,7 +5960,7 @@ var ServiceIdentifiers_1 = __webpack_require__(1); var estraverse = __webpack_require__(6); var CalleeDataExtractors_1 = __webpack_require__(26); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var StackTraceAnalyzer = StackTraceAnalyzer_1 = function () { function StackTraceAnalyzer(calleeDataExtractorsFactory) { _classCallCheck(this, StackTraceAnalyzer); @@ -6060,7 +6074,7 @@ var inversify_1 = __webpack_require__(0); var estraverse = __webpack_require__(6); var AbstractCalleeDataExtractor_1 = __webpack_require__(23); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var FunctionDeclarationCalleeDataExtractor = function (_AbstractCalleeDataEx) { _inherits(FunctionDeclarationCalleeDataExtractor, _AbstractCalleeDataEx); @@ -6138,7 +6152,7 @@ var inversify_1 = __webpack_require__(0); var estraverse = __webpack_require__(6); var AbstractCalleeDataExtractor_1 = __webpack_require__(23); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var FunctionExpressionCalleeDataExtractor = function (_AbstractCalleeDataEx) { _inherits(FunctionExpressionCalleeDataExtractor, _AbstractCalleeDataEx); @@ -6218,7 +6232,7 @@ var __metadata = undefined && undefined.__metadata || function (k, v) { var inversify_1 = __webpack_require__(0); var estraverse = __webpack_require__(6); var Node_1 = __webpack_require__(4); -var NodeUtils_1 = __webpack_require__(9); +var NodeUtils_1 = __webpack_require__(8); var AbstractCalleeDataExtractor_1 = __webpack_require__(23); var ObjectExpressionCalleeDataExtractor = function (_AbstractCalleeDataEx) { _inherits(ObjectExpressionCalleeDataExtractor, _AbstractCalleeDataEx); diff --git a/src/cli/JavaScriptObfuscatorCLI.ts b/src/cli/JavaScriptObfuscatorCLI.ts index 3d307248..45468abc 100644 --- a/src/cli/JavaScriptObfuscatorCLI.ts +++ b/src/cli/JavaScriptObfuscatorCLI.ts @@ -159,6 +159,11 @@ export class JavaScriptObfuscatorCLI { 'Enables control flow flattening', JavaScriptObfuscatorCLI.parseBoolean ) + .option( + '--controlFlowFlatteningThreshold ', + 'The probability that the control flow flattening transformation will be applied to the node', + parseFloat + ) .option( '--debugProtection ', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', diff --git a/src/interfaces/options/IOptions.d.ts b/src/interfaces/options/IOptions.d.ts index 093f2d3d..c2df6a01 100644 --- a/src/interfaces/options/IOptions.d.ts +++ b/src/interfaces/options/IOptions.d.ts @@ -4,6 +4,7 @@ import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding'; export interface IOptions { readonly compact: boolean; readonly controlFlowFlattening: boolean; + readonly controlFlowFlatteningThreshold: number; readonly debugProtection: boolean; readonly debugProtectionInterval: boolean; readonly disableConsoleOutput: boolean; diff --git a/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts b/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts index 2b5cdfb8..b367a667 100644 --- a/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts +++ b/src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts @@ -34,11 +34,6 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { [NodeType.BinaryExpression, NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer] ]); - /** - * @type {number} - */ - private static readonly controlFlowReplacersThreshold: number = 0.75; - /** * @type {number} */ @@ -171,7 +166,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer { estraverse.replace(functionNode.body, { enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { - if (RandomGeneratorUtils.getRandomFloat(0, 1) > FunctionControlFlowTransformer.controlFlowReplacersThreshold) { + if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) { return; } diff --git a/src/options/Options.ts b/src/options/Options.ts index b6c97220..97adf9ec 100644 --- a/src/options/Options.ts +++ b/src/options/Options.ts @@ -51,6 +51,14 @@ export class Options implements IOptions { @IsBoolean() public readonly controlFlowFlattening: boolean; + /** + * @type {boolean} + */ + @IsNumber() + @Min(0) + @Max(1) + public readonly controlFlowFlatteningThreshold: number; + /** * @type {boolean} */ diff --git a/src/options/OptionsNormalizer.ts b/src/options/OptionsNormalizer.ts index 5147c3f9..7cc8894e 100644 --- a/src/options/OptionsNormalizer.ts +++ b/src/options/OptionsNormalizer.ts @@ -10,7 +10,15 @@ export class OptionsNormalizer { /** * @type {TInputOptions} */ - private static readonly DISABLED_UNICODE_ARRAY_OPTIONS: TInputOptions = { + private static readonly DISABLED_CONTROL_FLOW_FLATTENING_OPTIONS: TInputOptions = { + controlFlowFlattening: false, + controlFlowFlatteningThreshold: 0 + }; + + /** + * @type {TInputOptions} + */ + private static readonly DISABLED_STRING_ARRAY_OPTIONS: TInputOptions = { rotateStringArray: false, stringArray: false, stringArrayEncoding: false, @@ -28,7 +36,7 @@ export class OptionsNormalizer { /** * @type {TInputOptions} */ - private static readonly UNICODE_ARRAY_ENCODING_OPTIONS: TInputOptions = { + private static readonly STRING_ARRAY_ENCODING_OPTIONS: TInputOptions = { stringArrayEncoding: 'base64' }; @@ -36,6 +44,7 @@ export class OptionsNormalizer { * @type {TOptionsNormalizerRule[]} */ private static readonly normalizerRules: TOptionsNormalizerRule[] = [ + OptionsNormalizer.controlFlowFlatteningThresholdRule, OptionsNormalizer.domainLockRule, OptionsNormalizer.selfDefendingRule, OptionsNormalizer.sourceMapBaseUrlRule, @@ -61,6 +70,21 @@ export class OptionsNormalizer { return normalizedOptions; } + /** + * @param options + * @returns {IOptions} + */ + private static controlFlowFlatteningThresholdRule (options: IOptions): IOptions { + if (options.controlFlowFlatteningThreshold === 0) { + options = { + ...options, + ...OptionsNormalizer.DISABLED_CONTROL_FLOW_FLATTENING_OPTIONS + }; + } + + return options; + } + /** * @param options * @returns {IOptions} @@ -152,7 +176,7 @@ export class OptionsNormalizer { if (!options.stringArray) { options = { ...options, - ...OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS + ...OptionsNormalizer.DISABLED_STRING_ARRAY_OPTIONS }; } @@ -167,7 +191,7 @@ export class OptionsNormalizer { if (options.stringArrayEncoding === true) { options = { ...options, - ...OptionsNormalizer.UNICODE_ARRAY_ENCODING_OPTIONS + ...OptionsNormalizer.STRING_ARRAY_ENCODING_OPTIONS }; } @@ -182,7 +206,7 @@ export class OptionsNormalizer { if (options.stringArrayThreshold === 0) { options = { ...options, - ...OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS + ...OptionsNormalizer.DISABLED_STRING_ARRAY_OPTIONS }; } diff --git a/src/preset-options/DefaultPreset.ts b/src/preset-options/DefaultPreset.ts index e536011e..a0e431d4 100644 --- a/src/preset-options/DefaultPreset.ts +++ b/src/preset-options/DefaultPreset.ts @@ -5,6 +5,7 @@ import { SourceMapMode } from '../enums/SourceMapMode'; export const DEFAULT_PRESET: TInputOptions = Object.freeze({ compact: true, controlFlowFlattening: false, + controlFlowFlatteningThreshold: 0.75, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: true, diff --git a/src/preset-options/NoCustomNodesPreset.ts b/src/preset-options/NoCustomNodesPreset.ts index d48d7a29..327838ea 100644 --- a/src/preset-options/NoCustomNodesPreset.ts +++ b/src/preset-options/NoCustomNodesPreset.ts @@ -5,6 +5,7 @@ import { SourceMapMode } from '../enums/SourceMapMode'; export const NO_CUSTOM_NODES_PRESET: TInputOptions = Object.freeze({ compact: true, controlFlowFlattening: false, + controlFlowFlatteningThreshold: 0, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: false, diff --git a/test/dev/dev.ts b/test/dev/dev.ts index 5307d3d8..0bfd7db8 100644 --- a/test/dev/dev.ts +++ b/test/dev/dev.ts @@ -9,81 +9,16 @@ if (!(global)._babelPolyfill) { let obfuscatedCode: string = JavaScriptObfuscator.obfuscate( ` - (function(){ - var result = 1, - term1 = 0, - term2 = 1, - i = 1; - while(i < 10) - { - var test = 10; - result = term1 + term2; - console.log(result); - term1 = term2; - term2 = result; - i++; - } - - console.log(test); - - var test = function (test) { - console.log(test); - - if (true) { - var test = 5 - } - - return test; - } - - console.log(test(1)); - - function test2 (abc) { - function test1 () { - console.log('inside', abc.item); - } - - console.log('ั‚ะตัั‚', abc); - - var abc = {}; - - return abc.item = 15, test1(); - }; - - var regexptest = /version\\/(\\d+)/i; - console.log(regexptest); - - test2(22); - console.log(105.4); - console.log(true, false); - - var sA = 'shorthand1'; - var sB = 'shorthand2'; - - console.log({sA, sB}); - - try { - } catch (error) { - console.log(error); - } - - function foo () { - return function () { - var sum1 = 10 + 20; - var sum2 = 20 + 30; - var sum3 = 30 + 50; - var sub = sum3 - sum2; - - return sum1 + sub; - } - } - - console.log(foo()()); + (function () { + var variable1 = 1 + 2; + var variable2 = 2 + 3; })(); + `, { compact: false, controlFlowFlattening: true, + controlFlowFlatteningThreshold: 1, disableConsoleOutput: false } ).getObfuscatedCode(); diff --git a/test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-1.js b/test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-1.js new file mode 100644 index 00000000..d7ade6fd --- /dev/null +++ b/test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-1.js @@ -0,0 +1,3 @@ +(function () { + var variable = 1 + 2; +})(); diff --git a/test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-2.js b/test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-2.js new file mode 100644 index 00000000..3ee5a085 --- /dev/null +++ b/test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-2.js @@ -0,0 +1,4 @@ +(function () { + var variable1 = 1 + 2; + var variable2 = 2 + 3; +})(); diff --git a/test/functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.spec.ts b/test/functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.spec.ts new file mode 100644 index 00000000..3617170c --- /dev/null +++ b/test/functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.spec.ts @@ -0,0 +1,73 @@ +import { assert } from 'chai'; + +import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult'; + +import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/preset-options/NoCustomNodesPreset'; + +import { readFileAsString } from '../../../../helpers/readFileAsString'; + +import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator'; + +describe('BinaryExpressionControlFlowReplacer', () => { + describe('replace (binaryExpressionNode: ESTree.BinaryExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage )', () => { + describe('variant #1 - single binary expression', () => { + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + readFileAsString( + './test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-1.js' + ), + { + ...NO_CUSTOM_NODES_PRESET, + controlFlowFlattening: true, + controlFlowFlatteningThreshold: 1 + } + ); + const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); + const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(0x1, *0x2\);/; + + it('should replace binary expression node by call to control flow storage node', () => { + assert.match(obfuscatedCode, controlFlowStorageCallRegExp); + }); + }); + + describe('variant #2 - multiple binary expressions with threshold = 1', () => { + it('should replace binary expression node by call to control flow storage node', () => { + const samplesCount: number = 50; + + let equalsValue: number = 0; + + for (let i = 0; i < samplesCount; i++) { + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + readFileAsString( + './test/fixtures/node-transformers/node-control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer-2.js' + ), + { + ...NO_CUSTOM_NODES_PRESET, + controlFlowFlattening: true, + controlFlowFlatteningThreshold: 1 + } + ); + const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); + const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x1, *0x2\);/; + const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x2, *0x3\);/; + + const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1); + const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2); + + const firstMatch: string | undefined = firstMatchArray ? firstMatchArray[2] : undefined; + const secondMatch: string | undefined = secondMatchArray ? secondMatchArray[2] : undefined; + + assert.match(obfuscatedCode, controlFlowStorageCallRegExp1); + assert.match(obfuscatedCode, controlFlowStorageCallRegExp2); + assert.isOk(firstMatch); + assert.isOk(secondMatch); + + if (firstMatch === secondMatch) { + equalsValue++; + } + } + + assert.closeTo(equalsValue / samplesCount, 0.5, 0.05); + }); + }); + }); +}); diff --git a/test/functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec.ts b/test/functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec.ts index c08fb67f..cb627882 100644 --- a/test/functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec.ts +++ b/test/functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec.ts @@ -28,11 +28,11 @@ describe('CatchClauseObfuscator', () => { }); it('catch clause arguments param name and param name in body should be same', () => { - const firstMatchArray: RegExpMatchArray|null = obfuscatedCode.match(paramNameRegExp); - const secondMatchArray: RegExpMatchArray|null = obfuscatedCode.match(bodyParamNameRegExp); + const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(paramNameRegExp); + const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(bodyParamNameRegExp); - const firstMatch: string|undefined = firstMatchArray ? firstMatchArray[1] : undefined; - const secondMatch: string|undefined = secondMatchArray ? secondMatchArray[1] : undefined; + const firstMatch: string | undefined = firstMatchArray ? firstMatchArray[1] : undefined; + const secondMatch: string | undefined = secondMatchArray ? secondMatchArray[1] : undefined; assert.isOk(firstMatch); assert.isOk(secondMatch); diff --git a/test/index.spec.ts b/test/index.spec.ts index 455fd3e4..2fb109c8 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -8,7 +8,7 @@ BabelPolyfill.append(); * Unit tests */ import './unit-tests/ObfuscationResult.spec'; -import './unit-tests/OptionsNormalizer.spec'; +import './unit-tests/options/OptionsNormalizer.spec'; import './unit-tests/SourceMapCorrector.spec'; import './unit-tests/cli/CLIUtils.spec'; import './unit-tests/decorators/Initializable.spec'; @@ -31,6 +31,7 @@ import './functional-tests/custom-nodes/domain-lock-nodes/DomainLockNode.spec'; import './functional-tests/custom-nodes/string-array-nodes/StringArrayCallsWrapper.spec'; import './functional-tests/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.spec'; import './functional-tests/custom-nodes/string-array-nodes/StringArrayNode.spec'; +import './functional-tests/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.spec'; import './functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec'; import './functional-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec'; import './functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec'; diff --git a/test/unit-tests/OptionsNormalizer.spec.ts b/test/unit-tests/options/OptionsNormalizer.spec.ts similarity index 84% rename from test/unit-tests/OptionsNormalizer.spec.ts rename to test/unit-tests/options/OptionsNormalizer.spec.ts index ace4ae39..f004fcf6 100644 --- a/test/unit-tests/OptionsNormalizer.spec.ts +++ b/test/unit-tests/options/OptionsNormalizer.spec.ts @@ -1,13 +1,13 @@ import { assert } from 'chai'; -import { TInputOptions } from '../../src/types/options/TInputOptions'; +import { TInputOptions } from '../../../src/types/options/TInputOptions'; -import { IOptions } from '../../src/interfaces/options/IOptions'; +import { IOptions } from '../../../src/interfaces/options/IOptions'; -import { DEFAULT_PRESET } from '../../src/preset-options/DefaultPreset'; +import { DEFAULT_PRESET } from '../../../src/preset-options/DefaultPreset'; -import { Options } from '../../src/options/Options'; -import { OptionsNormalizer } from '../../src/options/OptionsNormalizer'; +import { Options } from '../../../src/options/Options'; +import { OptionsNormalizer } from '../../../src/options/OptionsNormalizer'; /** * @param optionsPreset @@ -24,6 +24,22 @@ describe('OptionsNormalizer', () => { let optionsPreset: TInputOptions, expectedOptionsPreset: TInputOptions; + it('should normalize options preset: controlFlowFlatteningThresholdRule', () => { + optionsPreset = { + ...DEFAULT_PRESET, + controlFlowFlattening: true, + controlFlowFlatteningThreshold: 0 + }; + + expectedOptionsPreset = { + ...DEFAULT_PRESET, + controlFlowFlattening: false, + controlFlowFlatteningThreshold: 0 + }; + + assert.deepEqual(getNormalizedOptions(optionsPreset), expectedOptionsPreset); + }); + it('should normalize options preset: domainLockRule', () => { optionsPreset = { ...DEFAULT_PRESET,