js-confuser 1.7.1 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +12 -27
  3. package/dist/compiler.js +2 -8
  4. package/dist/constants.js +17 -10
  5. package/dist/index.js +7 -30
  6. package/dist/obfuscator.js +15 -62
  7. package/dist/options.js +21 -38
  8. package/dist/order.js +4 -7
  9. package/dist/parser.js +5 -13
  10. package/dist/precedence.js +6 -8
  11. package/dist/presets.js +4 -6
  12. package/dist/probability.js +13 -24
  13. package/dist/templates/bufferToString.js +100 -5
  14. package/dist/templates/crash.js +51 -9
  15. package/dist/templates/es5.js +125 -6
  16. package/dist/templates/functionLength.js +24 -6
  17. package/dist/templates/globals.js +9 -0
  18. package/dist/templates/template.js +71 -30
  19. package/dist/transforms/antiTooling.js +26 -22
  20. package/dist/transforms/calculator.js +18 -54
  21. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +236 -333
  22. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
  23. package/dist/transforms/deadCode.js +528 -27
  24. package/dist/transforms/dispatcher.js +106 -110
  25. package/dist/transforms/es5/antiClass.js +70 -44
  26. package/dist/transforms/es5/antiDestructuring.js +14 -38
  27. package/dist/transforms/es5/antiES6Object.js +39 -48
  28. package/dist/transforms/es5/antiSpreadOperator.js +5 -14
  29. package/dist/transforms/es5/antiTemplate.js +10 -19
  30. package/dist/transforms/es5/es5.js +7 -40
  31. package/dist/transforms/extraction/classExtraction.js +83 -0
  32. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
  33. package/dist/transforms/extraction/objectExtraction.js +24 -56
  34. package/dist/transforms/finalizer.js +6 -20
  35. package/dist/transforms/flatten.js +51 -99
  36. package/dist/transforms/identifier/globalAnalysis.js +8 -26
  37. package/dist/transforms/identifier/globalConcealing.js +35 -54
  38. package/dist/transforms/identifier/movedDeclarations.js +66 -38
  39. package/dist/transforms/identifier/renameVariables.js +29 -68
  40. package/dist/transforms/identifier/variableAnalysis.js +21 -48
  41. package/dist/transforms/lock/antiDebug.js +20 -25
  42. package/dist/transforms/lock/integrity.js +48 -47
  43. package/dist/transforms/lock/lock.js +62 -113
  44. package/dist/transforms/minify.js +77 -108
  45. package/dist/transforms/opaquePredicates.js +11 -48
  46. package/dist/transforms/preparation.js +17 -50
  47. package/dist/transforms/renameLabels.js +5 -22
  48. package/dist/transforms/rgf.js +93 -69
  49. package/dist/transforms/shuffle.js +41 -46
  50. package/dist/transforms/stack.js +35 -98
  51. package/dist/transforms/string/encoding.js +73 -27
  52. package/dist/transforms/string/stringCompression.js +44 -68
  53. package/dist/transforms/string/stringConcealing.js +125 -134
  54. package/dist/transforms/string/stringEncoding.js +6 -26
  55. package/dist/transforms/string/stringSplitting.js +5 -30
  56. package/dist/transforms/transform.js +50 -100
  57. package/dist/traverse.js +11 -18
  58. package/dist/util/compare.js +27 -29
  59. package/dist/util/gen.js +32 -86
  60. package/dist/util/guard.js +0 -1
  61. package/dist/util/identifiers.js +9 -72
  62. package/dist/util/insert.js +27 -77
  63. package/dist/util/math.js +0 -3
  64. package/dist/util/object.js +3 -7
  65. package/dist/util/random.js +5 -36
  66. package/dist/util/scope.js +6 -3
  67. package/package.json +3 -3
  68. package/src/constants.ts +12 -0
  69. package/src/options.ts +13 -0
  70. package/src/order.ts +2 -2
  71. package/src/templates/bufferToString.ts +49 -11
  72. package/src/templates/functionLength.ts +21 -3
  73. package/src/templates/globals.ts +3 -0
  74. package/src/templates/template.ts +85 -25
  75. package/src/transforms/antiTooling.ts +33 -11
  76. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +2 -2
  77. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
  78. package/src/transforms/deadCode.ts +0 -16
  79. package/src/transforms/dispatcher.ts +91 -69
  80. package/src/transforms/es5/antiClass.ts +10 -1
  81. package/src/transforms/extraction/classExtraction.ts +168 -0
  82. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -10
  83. package/src/transforms/extraction/objectExtraction.ts +4 -15
  84. package/src/transforms/flatten.ts +20 -5
  85. package/src/transforms/identifier/globalConcealing.ts +29 -65
  86. package/src/transforms/identifier/movedDeclarations.ts +90 -24
  87. package/src/transforms/minify.ts +27 -12
  88. package/src/transforms/rgf.ts +94 -5
  89. package/src/transforms/stack.ts +12 -3
  90. package/src/transforms/string/encoding.ts +85 -51
  91. package/src/transforms/string/stringCompression.ts +5 -8
  92. package/src/transforms/string/stringConcealing.ts +139 -113
  93. package/src/transforms/string/stringEncoding.ts +1 -2
  94. package/src/transforms/string/stringSplitting.ts +1 -2
  95. package/src/transforms/transform.ts +30 -1
  96. package/src/util/compare.ts +39 -5
  97. package/src/util/gen.ts +10 -3
  98. package/src/util/insert.ts +17 -0
  99. package/src/util/scope.ts +14 -2
  100. package/test/code/Cash.test.ts +10 -4
  101. package/test/code/StrictMode.src.js +65 -0
  102. package/test/code/StrictMode.test.js +37 -0
  103. package/test/compare.test.ts +62 -2
  104. package/test/options.test.ts +111 -55
  105. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
  106. package/test/transforms/dispatcher.test.ts +55 -0
  107. package/test/transforms/extraction/classExtraction.test.ts +86 -0
  108. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
  109. package/test/transforms/extraction/objectExtraction.test.ts +2 -0
  110. package/test/transforms/identifier/globalConcealing.test.ts +19 -0
  111. package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
  112. package/test/transforms/minify.test.ts +37 -0
  113. package/test/transforms/rgf.test.ts +50 -0
  114. package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
  115. package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
  116. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
  117. package/dist/transforms/eval.js +0 -84
  118. package/dist/transforms/hexadecimalNumbers.js +0 -63
  119. package/dist/transforms/hideInitializingCode.js +0 -270
  120. package/dist/transforms/identifier/nameRecycling.js +0 -218
  121. package/dist/transforms/label.js +0 -67
  122. package/dist/transforms/preparation/nameConflicts.js +0 -116
  123. package/dist/transforms/preparation/preparation.js +0 -188
@@ -4,33 +4,23 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _compiler = require("../compiler");
9
-
10
8
  var _constants = require("../constants");
11
-
12
9
  var _obfuscator = _interopRequireDefault(require("../obfuscator"));
13
-
14
10
  var _order = require("../order");
15
-
16
11
  var _probability = require("../probability");
17
-
12
+ var _functionLength = require("../templates/functionLength");
13
+ var _globals = require("../templates/globals");
18
14
  var _traverse = require("../traverse");
19
-
20
15
  var _gen = require("../util/gen");
21
-
22
16
  var _identifiers = require("../util/identifiers");
23
-
24
17
  var _insert = require("../util/insert");
25
-
26
18
  var _integrity = _interopRequireDefault(require("./lock/integrity"));
27
-
28
19
  var _transform = _interopRequireDefault(require("./transform"));
29
-
30
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
-
32
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
33
-
20
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
22
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
34
24
  /**
35
25
  * Converts function to `new Function("..code..")` syntax as an alternative to `eval`. Eval is disabled in many environments.
36
26
  *
@@ -41,66 +31,79 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
41
31
  * `flatten` can attempt to make function reference-less. Recommended to have flatten enabled with RGF.
42
32
  */
43
33
  class RGF extends _transform.default {
44
- // Array of all the `new Function` calls
45
- // The name of the array holding all the `new Function` expressions
34
+ getFunctionLengthName(parents) {
35
+ if (!this.functionLengthName) {
36
+ this.functionLengthName = this.getPlaceholder();
37
+ }
38
+ return this.functionLengthName;
39
+ }
46
40
  constructor(o) {
47
41
  super(o, _order.ObfuscateOrder.RGF);
48
-
42
+ // Array of all the `new Function` calls
49
43
  _defineProperty(this, "arrayExpressionElements", void 0);
50
-
44
+ // The name of the array holding all the `new Function` expressions
51
45
  _defineProperty(this, "arrayExpressionName", void 0);
52
-
46
+ _defineProperty(this, "functionLengthName", void 0);
53
47
  this.arrayExpressionName = this.getPlaceholder() + "_rgf";
54
48
  this.arrayExpressionElements = [];
55
49
  }
56
-
57
50
  apply(tree) {
58
- super.apply(tree); // Only add the array if there were converted functions
51
+ super.apply(tree);
59
52
 
53
+ // Only add the array if there were converted functions
60
54
  if (this.arrayExpressionElements.length > 0) {
61
55
  (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.ArrayExpression)(this.arrayExpressionElements))));
62
56
  }
63
- }
64
57
 
58
+ // The function.length helper function must be placed last
59
+ if (this.functionLengthName) {
60
+ (0, _insert.prepend)(tree, _functionLength.FunctionLengthTemplate.single({
61
+ name: this.functionLengthName,
62
+ ObjectDefineProperty: this.createInitVariable(_globals.ObjectDefineProperty, [tree])
63
+ }));
64
+ }
65
+ }
65
66
  match(object, parents) {
66
- return (object.type === "FunctionDeclaration" || object.type === "FunctionExpression") && // Does not apply to Arrow functions
67
- !object.async && // Does not apply to async/generator functions
67
+ return (object.type === "FunctionDeclaration" || object.type === "FunctionExpression") &&
68
+ // Does not apply to Arrow functions
69
+ !object.async &&
70
+ // Does not apply to async/generator functions
68
71
  !object.generator;
69
72
  }
70
-
71
73
  transform(object, parents) {
72
74
  var _this$options$lock, _object$id;
73
-
74
75
  // Discard getter/setter methods
75
76
  if (parents[0].type === "Property" && parents[0].value === object) {
76
77
  if (parents[0].method || parents[0].kind === "get" || parents[0].kind === "set") {
77
78
  return;
78
79
  }
79
- } // Discard class methods
80
-
80
+ }
81
81
 
82
+ // Discard class methods
82
83
  if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
83
84
  return;
84
- } // Avoid applying to the countermeasures function
85
-
85
+ }
86
86
 
87
+ // Avoid applying to the countermeasures function
87
88
  if (typeof ((_this$options$lock = this.options.lock) === null || _this$options$lock === void 0 ? void 0 : _this$options$lock.countermeasures) === "string") {
88
89
  // function countermeasures(){...}
89
90
  if (object.type === "FunctionDeclaration" && object.id.type === "Identifier" && object.id.name === this.options.lock.countermeasures) {
90
91
  return;
91
- } // var countermeasures = function(){...}
92
-
92
+ }
93
93
 
94
+ // var countermeasures = function(){...}
94
95
  if (parents[0].type === "VariableDeclarator" && parents[0].init === object && parents[0].id.type === "Identifier" && parents[0].id.name === this.options.lock.countermeasures) {
95
96
  return;
96
97
  }
97
- } // Check user option
98
-
98
+ }
99
99
 
100
- if (!(0, _probability.ComputeProbabilityMap)(this.options.rgf, x => x, object === null || object === void 0 ? void 0 : (_object$id = object.id) === null || _object$id === void 0 ? void 0 : _object$id.name)) return; // Discard functions that use 'eval' function
100
+ // Check user option
101
+ if (!(0, _probability.ComputeProbabilityMap)(this.options.rgf, x => x, object === null || object === void 0 ? void 0 : (_object$id = object.id) === null || _object$id === void 0 ? void 0 : _object$id.name)) return;
101
102
 
102
- if (object.$requiresEval) return; // Check for 'this', 'arguments' (not allowed!)
103
+ // Discard functions that use 'eval' function
104
+ if (object.$requiresEval) return;
103
105
 
106
+ // Check for 'this', 'arguments' (not allowed!)
104
107
  var isIllegal = false;
105
108
  (0, _traverse.walk)(object, parents, (o, p) => {
106
109
  if (o.type === "ThisExpression" || o.type === "Super" || o.type === "Identifier" && o.name === "arguments") {
@@ -115,17 +118,14 @@ class RGF extends _transform.default {
115
118
  var isReferenceLess = true;
116
119
  var identifierPreventingTransformation;
117
120
  (0, _traverse.walk)(object, parents, (o, p) => {
118
- if (o.type === "Identifier" && !_constants.reservedIdentifiers.has(o.name) && !this.options.globalVariables.has(o.name)) {
121
+ if (o.type === "Identifier" && o.name !== this.arrayExpressionName && !_constants.reservedIdentifiers.has(o.name) && !this.options.globalVariables.has(o.name)) {
119
122
  var info = (0, _identifiers.getIdentifierInfo)(o, p);
120
-
121
123
  if (!info.spec.isReferenced) {
122
124
  return;
123
125
  }
124
-
125
126
  if (info.spec.isDefined) {
126
127
  // Add to defined map
127
128
  var definingContext = (0, _insert.getDefiningContext)(o, p);
128
-
129
129
  if (!definedMap.has(definingContext)) {
130
130
  definedMap.set(definingContext, new Set([o.name]));
131
131
  } else {
@@ -134,7 +134,6 @@ class RGF extends _transform.default {
134
134
  } else {
135
135
  // This approach is dirty and does not account for hoisted FunctionDeclarations
136
136
  var isDefinedAbove = false;
137
-
138
137
  for (var pNode of p) {
139
138
  if (definedMap.has(pNode)) {
140
139
  if (definedMap.get(pNode).has(o.name)) {
@@ -143,7 +142,6 @@ class RGF extends _transform.default {
143
142
  }
144
143
  }
145
144
  }
146
-
147
145
  if (!isDefinedAbove) {
148
146
  isReferenceLess = false;
149
147
  identifierPreventingTransformation = o.name;
@@ -151,36 +149,34 @@ class RGF extends _transform.default {
151
149
  }
152
150
  }
153
151
  }
154
- }); // This function is not 'reference-less', cannot be RGF'd
152
+ });
155
153
 
154
+ // This function is not 'reference-less', cannot be RGF'd
156
155
  if (!isReferenceLess) {
157
156
  if (object.id) {
158
157
  var _object$id2;
159
-
160
- this.log("".concat(object === null || object === void 0 ? void 0 : (_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name, "() cannot be transformed because of ").concat(identifierPreventingTransformation));
158
+ this.log(`${object === null || object === void 0 ? void 0 : (_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name}() cannot be transformed because of ${identifierPreventingTransformation}`);
161
159
  }
162
-
163
160
  return;
164
- } // Since `new Function` is completely isolated, create an entire new obfuscator and run remaining transformations.
161
+ }
162
+
163
+ // Since `new Function` is completely isolated, create an entire new obfuscator and run remaining transformations.
165
164
  // RGF runs early and needs completed code before converting to a string.
166
165
  // (^ the variables haven't been renamed yet)
167
-
168
-
169
- var obfuscator = new _obfuscator.default({ ...this.options,
166
+ var obfuscator = new _obfuscator.default({
167
+ ...this.options,
170
168
  stringEncoding: false,
171
169
  compact: true
172
170
  });
173
-
174
171
  if (obfuscator.options.lock) {
175
- delete obfuscator.options.lock.countermeasures; // Integrity will not recursively apply to RGF'd functions. This is intended.
172
+ delete obfuscator.options.lock.countermeasures;
176
173
 
174
+ // Integrity will not recursively apply to RGF'd functions. This is intended.
177
175
  var lockTransform = obfuscator.transforms["Lock"];
178
-
179
176
  if (lockTransform) {
180
177
  lockTransform.before = lockTransform.before.filter(beforeTransform => !(beforeTransform instanceof _integrity.default));
181
178
  }
182
179
  }
183
-
184
180
  var transforms = obfuscator.array.filter(x => x.priority > this.priority);
185
181
  var embeddedFunctionName = this.getPlaceholder();
186
182
  var embeddedFunction = {
@@ -191,41 +187,69 @@ class RGF extends _transform.default {
191
187
  async: false,
192
188
  generator: false
193
189
  };
190
+
191
+ // The new program will look like this
192
+ // new Function(`
193
+ // var rgf_array = this[0]
194
+ // function greet(message){
195
+ // console.log(message)
196
+ // }
197
+ // return greet.apply(this[1], arguments)
198
+ // `)
199
+ //
200
+ // And called like
201
+ // f.apply([ rgf_array, this ], arguments)
194
202
  var tree = {
195
203
  type: "Program",
196
- body: [embeddedFunction, (0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(embeddedFunctionName), (0, _gen.Literal)("apply"), true), [(0, _gen.ThisExpression)(), (0, _gen.Identifier)("arguments")]))]
204
+ body: [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.arrayExpressionName, (0, _gen.MemberExpression)((0, _gen.ThisExpression)(), (0, _gen.Literal)(0)))), embeddedFunction, (0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(embeddedFunctionName), (0, _gen.Literal)("apply"), true), [(0, _gen.MemberExpression)((0, _gen.ThisExpression)(), (0, _gen.Literal)(1)), (0, _gen.Identifier)("arguments")]))]
197
205
  };
198
206
  transforms.forEach(transform => {
199
207
  transform.apply(tree);
200
208
  });
201
- var toString = (0, _compiler.compileJsSync)(tree, obfuscator.options); // new Function(code)
209
+ var toString = (0, _compiler.compileJsSync)(tree, obfuscator.options);
210
+
211
+ // new Function(code)
212
+ var newFunctionExpression = (0, _gen.NewExpression)((0, _gen.Identifier)("Function"), [(0, _gen.Literal)(toString)]);
202
213
 
203
- var newFunctionExpression = (0, _gen.NewExpression)((0, _gen.Identifier)("Function"), [(0, _gen.Literal)(toString)]); // The index where this function is placed in the array
214
+ // The index where this function is placed in the array
215
+ var newFunctionExpressionIndex = this.arrayExpressionElements.length;
204
216
 
205
- var newFunctionExpressionIndex = this.arrayExpressionElements.length; // Add it to the array
217
+ // Add it to the array
218
+ this.arrayExpressionElements.push(newFunctionExpression);
206
219
 
207
- this.arrayExpressionElements.push(newFunctionExpression); // The member expression to retrieve this function
220
+ // The member expression to retrieve this function
221
+ var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.Literal)(newFunctionExpressionIndex), true);
222
+ var originalFunctionLength = (0, _insert.computeFunctionLength)(object.params);
223
+
224
+ // Replace based on type
208
225
 
209
- var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.Literal)(newFunctionExpressionIndex), true); // Replace based on type
210
226
  // (1) Function Declaration:
211
227
  // - Replace body with call to new function
212
-
213
228
  if (object.type === "FunctionDeclaration") {
214
- object.body = (0, _gen.BlockStatement)([(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)(memberExpression, (0, _gen.Literal)("apply"), true), [(0, _gen.ThisExpression)(), (0, _gen.Identifier)("arguments")]))]); // The parameters are no longer needed ('arguments' is used to capture them)
229
+ object.body = (0, _gen.BlockStatement)([(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)(memberExpression, (0, _gen.Literal)("apply"), true), [(0, _gen.ArrayExpression)([(0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.ThisExpression)()]), (0, _gen.Identifier)("arguments")]))]);
215
230
 
231
+ // The parameters are no longer needed ('arguments' is used to capture them)
216
232
  object.params = [];
217
- return;
218
- } // (2) Function Expression:
219
- // - Replace expression with member expression pointing to new function
220
233
 
234
+ // The function is no longer guaranteed to not have extraneous parameters passed in
235
+ object[_constants.predictableFunctionTag] = false;
236
+ if (this.options.preserveFunctionLength && originalFunctionLength !== 0) {
237
+ var body = parents[0];
238
+ body.splice(body.indexOf(object), 0, (0, _gen.ExpressionStatement)((0, _gen.CallExpression)((0, _gen.Identifier)(this.getFunctionLengthName(parents)), [(0, _gen.Identifier)(object.id.name), (0, _gen.Literal)(originalFunctionLength)])));
239
+ }
240
+ return;
241
+ }
221
242
 
243
+ // (2) Function Expression:
244
+ // - Replace expression with member expression pointing to new function
222
245
  if (object.type === "FunctionExpression") {
246
+ if (this.options.preserveFunctionLength && originalFunctionLength !== 0) {
247
+ memberExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(this.getFunctionLengthName(parents)), [memberExpression, (0, _gen.Literal)(originalFunctionLength)]);
248
+ }
223
249
  this.replace(object, memberExpression);
224
250
  return;
225
251
  }
226
252
  };
227
253
  }
228
-
229
254
  }
230
-
231
255
  exports.default = RGF;
@@ -4,36 +4,25 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _assert = require("assert");
9
-
10
8
  var _order = require("../order");
11
-
12
9
  var _probability = require("../probability");
13
-
14
10
  var _template = _interopRequireDefault(require("../templates/template"));
15
-
16
11
  var _gen = require("../util/gen");
17
-
18
12
  var _insert = require("../util/insert");
19
-
20
13
  var _random = require("../util/random");
21
-
22
14
  var _transform = _interopRequireDefault(require("./transform"));
23
-
24
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
-
26
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
27
-
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
17
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
18
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
28
19
  var Hash = function (s) {
29
20
  var a = 1,
30
- c = 0,
31
- h,
32
- o;
33
-
21
+ c = 0,
22
+ h,
23
+ o;
34
24
  if (s) {
35
25
  a = 0;
36
-
37
26
  for (h = s.length - 1; h >= 0; h--) {
38
27
  o = s.charCodeAt(h);
39
28
  a = (a << 6 & 268435455) + o + (o << 14);
@@ -41,72 +30,72 @@ var Hash = function (s) {
41
30
  a = c !== 0 ? a ^ c >> 21 : a;
42
31
  }
43
32
  }
44
-
45
33
  return ~~String(a).slice(0, 3);
46
34
  };
35
+ var HashTemplate = (0, _template.default)(`
36
+ var {name} = function(arr) {
37
+ var s = arr.map(x=>x+"").join(''), a = 1, c = 0, h, o;
38
+ if (s) {
39
+ a = 0;
40
+ for (h = s.length - 1; h >= 0; h--) {
41
+ o = s.charCodeAt(h);
42
+ a = (a<<6&268435455) + o + (o<<14);
43
+ c = a & 266338304;
44
+ a = c!==0?a^c>>21:a;
45
+ }
46
+ }
47
+ return ~~String(a).slice(0, 3);
48
+ };`);
47
49
 
48
- var HashTemplate = (0, _template.default)("\n var {name} = function(arr) {\n var s = arr.map(x=>x+\"\").join(''), a = 1, c = 0, h, o;\n if (s) {\n a = 0;\n for (h = s.length - 1; h >= 0; h--) {\n o = s.charCodeAt(h);\n a = (a<<6&268435455) + o + (o<<14);\n c = a & 266338304;\n a = c!==0?a^c>>21:a;\n }\n }\n return ~~String(a).slice(0, 3);\n};");
49
50
  /**
50
51
  * Shuffles arrays initial order of elements.
51
52
  *
52
53
  * "Un-shuffles" the array at runtime.
53
54
  */
54
-
55
55
  class Shuffle extends _transform.default {
56
56
  constructor(o) {
57
57
  super(o, _order.ObfuscateOrder.Shuffle);
58
-
59
58
  _defineProperty(this, "hashName", void 0);
60
59
  }
61
-
62
60
  match(object, parents) {
63
61
  return object.type == "ArrayExpression" && !parents.find(x => x.$dispatcherSkip);
64
62
  }
65
-
66
63
  transform(object, parents) {
67
64
  return () => {
68
65
  if (object.elements.length < 3) {
69
66
  // Min: 4 elements
70
67
  return;
71
68
  }
72
-
73
69
  function isAllowed(e) {
74
70
  return e.type == "Literal" && {
75
71
  number: 1,
76
72
  boolean: 1,
77
73
  string: 1
78
74
  }[typeof e.value];
79
- } // Only arrays with only literals
80
-
75
+ }
81
76
 
77
+ // Only arrays with only literals
82
78
  var illegal = object.elements.find(x => !isAllowed(x));
83
-
84
79
  if (illegal) {
85
80
  return;
86
81
  }
87
-
88
82
  var mapped = object.elements.map(x => x.value);
89
83
  var mode = (0, _probability.ComputeProbabilityMap)(this.options.shuffle, x => x, mapped);
90
-
91
84
  if (mode) {
92
85
  var shift = (0, _random.getRandomInteger)(1, Math.min(60, object.elements.length * 6));
93
86
  var expr = (0, _gen.Literal)(shift);
94
87
  var name = this.getPlaceholder();
95
-
96
88
  if (mode == "hash") {
97
89
  var str = mapped.join("");
98
90
  shift = Hash(str);
99
-
100
91
  if (!this.hashName) {
101
92
  (0, _insert.prepend)(parents[parents.length - 1], HashTemplate.single({
102
93
  name: this.hashName = this.getPlaceholder()
103
94
  }));
104
95
  }
105
-
106
96
  for (var i = 0; i < shift; i++) {
107
97
  object.elements.push(object.elements.shift());
108
98
  }
109
-
110
99
  var shiftedHash = Hash(object.elements.map(x => x.value + "").join(""));
111
100
  expr = (0, _gen.BinaryExpression)("-", (0, _gen.CallExpression)((0, _gen.Identifier)(this.hashName), [(0, _gen.Identifier)(name)]), (0, _gen.Literal)(shiftedHash - shift));
112
101
  } else {
@@ -114,7 +103,6 @@ class Shuffle extends _transform.default {
114
103
  object.elements.push(object.elements.shift());
115
104
  }
116
105
  }
117
-
118
106
  var code = [];
119
107
  var iName = this.getPlaceholder();
120
108
  var inPlace = false;
@@ -122,13 +110,10 @@ class Shuffle extends _transform.default {
122
110
  var inPlaceBody;
123
111
  var inPlaceIndex;
124
112
  var varDeclarator = parents[0];
125
-
126
113
  if (varDeclarator.type == "VariableDeclarator") {
127
114
  var varDec = parents[2];
128
-
129
115
  if (varDec.type == "VariableDeclaration" && varDec.kind !== "const") {
130
116
  var body = parents[3];
131
-
132
117
  if (varDec.declarations.length == 1 && Array.isArray(body) && varDeclarator.id.type === "Identifier" && varDeclarator.init === object) {
133
118
  inPlaceIndex = body.indexOf(varDec);
134
119
  inPlaceBody = body;
@@ -137,28 +122,38 @@ class Shuffle extends _transform.default {
137
122
  }
138
123
  }
139
124
  }
140
-
141
125
  if (mode !== "hash") {
142
126
  var varPrefix = this.getPlaceholder();
143
- code.push((0, _template.default)("\n for ( var ".concat(varPrefix, "x = 16; ").concat(varPrefix, "x%4 === 0; ").concat(varPrefix, "x++) {\n var ").concat(varPrefix, "z = 0;\n ").concat(inPlace ? "".concat(inPlaceName, " = ").concat(name) : name, " = ").concat(name, ".concat((function(){\n ").concat(varPrefix, "z++;\n if(").concat(varPrefix, "z === 1){\n return [];\n }\n\n for( var ").concat(varPrefix, "i = ").concat((0, _random.getRandomInteger)(5, 105), "; ").concat(varPrefix, "i; ").concat(varPrefix, "i-- ){\n ").concat(name, ".unshift(").concat(name, ".pop());\n }\n return [];\n })());\n }\n ")).single());
127
+ code.push((0, _template.default)(`
128
+ for ( var ${varPrefix}x = 16; ${varPrefix}x%4 === 0; ${varPrefix}x++) {
129
+ var ${varPrefix}z = 0;
130
+ ${inPlace ? `${inPlaceName} = ${name}` : name} = ${name}.concat((function(){
131
+ ${varPrefix}z++;
132
+ if(${varPrefix}z === 1){
133
+ return [];
134
+ }
135
+
136
+ for( var ${varPrefix}i = ${(0, _random.getRandomInteger)(5, 105)}; ${varPrefix}i; ${varPrefix}i-- ){
137
+ ${name}.unshift(${name}.pop());
138
+ }
139
+ return [];
140
+ })());
141
+ }
142
+ `).single());
144
143
  }
145
-
146
- code.push((0, _gen.ForStatement)((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(iName, expr)), (0, _gen.Identifier)(iName), (0, _gen.UpdateExpression)("--", (0, _gen.Identifier)(iName), false), [// ${name}.unshift(${name}.pop());
144
+ code.push((0, _gen.ForStatement)((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(iName, expr)), (0, _gen.Identifier)(iName), (0, _gen.UpdateExpression)("--", (0, _gen.Identifier)(iName), false), [
145
+ // ${name}.unshift(${name}.pop());
147
146
  (0, _gen.ExpressionStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(name), (0, _gen.Identifier)("unshift"), false), [(0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(name), (0, _gen.Identifier)("pop"), false), [])]))]));
148
-
149
147
  if (inPlace) {
150
148
  var varDeclarator = parents[0];
151
149
  (0, _assert.ok)(i != -1);
152
150
  inPlaceBody.splice(inPlaceIndex + 1, 0, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, (0, _gen.Identifier)(varDeclarator.id.name))), ...code);
153
151
  }
154
-
155
152
  if (!inPlace) {
156
153
  this.replace(object, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([(0, _gen.Identifier)(name)], [...code, (0, _gen.ReturnStatement)((0, _gen.Identifier)(name))]), [(0, _insert.clone)(object)]));
157
154
  }
158
155
  }
159
156
  };
160
157
  }
161
-
162
158
  }
163
-
164
159
  exports.default = Shuffle;