js-confuser 1.5.7 → 1.5.9

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 (73) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/index.js +45 -4
  3. package/dist/obfuscator.js +10 -5
  4. package/dist/options.js +6 -7
  5. package/dist/order.js +3 -3
  6. package/dist/transforms/antiTooling.js +1 -1
  7. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +16 -2
  8. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -2
  9. package/dist/transforms/dispatcher.js +3 -3
  10. package/dist/transforms/es5/antiClass.js +6 -2
  11. package/dist/transforms/es5/antiDestructuring.js +1 -1
  12. package/dist/transforms/eval.js +11 -0
  13. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +4 -4
  14. package/dist/transforms/extraction/objectExtraction.js +6 -1
  15. package/dist/transforms/flatten.js +73 -50
  16. package/dist/transforms/hexadecimalNumbers.js +34 -9
  17. package/dist/transforms/identifier/movedDeclarations.js +1 -1
  18. package/dist/transforms/identifier/nameRecycling.js +8 -2
  19. package/dist/transforms/identifier/renameVariables.js +9 -0
  20. package/dist/transforms/lock/antiDebug.js +1 -1
  21. package/dist/transforms/minify.js +22 -6
  22. package/dist/transforms/rgf.js +4 -4
  23. package/dist/transforms/stack.js +1 -1
  24. package/dist/transforms/string/stringConcealing.js +77 -40
  25. package/dist/transforms/transform.js +1 -1
  26. package/dist/traverse.js +0 -8
  27. package/dist/util/compare.js +2 -2
  28. package/dist/util/insert.js +20 -6
  29. package/package.json +2 -2
  30. package/src/index.ts +57 -19
  31. package/src/obfuscator.ts +6 -1
  32. package/src/options.ts +20 -6
  33. package/src/order.ts +3 -3
  34. package/src/transforms/antiTooling.ts +1 -1
  35. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +16 -1
  36. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +14 -2
  37. package/src/transforms/dispatcher.ts +4 -3
  38. package/src/transforms/es5/antiClass.ts +10 -1
  39. package/src/transforms/es5/antiDestructuring.ts +1 -1
  40. package/src/transforms/eval.ts +18 -0
  41. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +5 -5
  42. package/src/transforms/extraction/objectExtraction.ts +12 -5
  43. package/src/transforms/flatten.ts +181 -128
  44. package/src/transforms/hexadecimalNumbers.ts +37 -9
  45. package/src/transforms/identifier/movedDeclarations.ts +1 -1
  46. package/src/transforms/identifier/nameRecycling.ts +14 -3
  47. package/src/transforms/identifier/renameVariables.ts +19 -0
  48. package/src/transforms/lock/antiDebug.ts +1 -1
  49. package/src/transforms/minify.ts +37 -5
  50. package/src/transforms/rgf.ts +4 -3
  51. package/src/transforms/stack.ts +3 -1
  52. package/src/transforms/string/stringConcealing.ts +120 -56
  53. package/src/transforms/transform.ts +1 -1
  54. package/src/traverse.ts +1 -8
  55. package/src/types.ts +9 -1
  56. package/src/util/compare.ts +2 -2
  57. package/src/util/insert.ts +37 -8
  58. package/test/code/ES6.src.js +14 -0
  59. package/test/code/NewFeatures.test.ts +19 -0
  60. package/test/index.test.ts +13 -1
  61. package/test/transforms/antiTooling.test.ts +30 -0
  62. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +58 -0
  63. package/test/transforms/dispatcher.test.ts +24 -0
  64. package/test/transforms/es5/antiClass.test.ts +33 -0
  65. package/test/transforms/eval.test.ts +53 -0
  66. package/test/transforms/extraction/objectExtraction.test.ts +21 -0
  67. package/test/transforms/flatten.test.ts +146 -3
  68. package/test/transforms/identifier/nameRecycling.test.ts +39 -0
  69. package/test/transforms/identifier/renameVariables.test.ts +64 -0
  70. package/test/transforms/minify.test.ts +66 -0
  71. package/test/transforms/rgf.test.ts +56 -0
  72. package/test/transforms/string/stringConcealing.test.ts +33 -0
  73. package/test/util/compare.test.ts +23 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,54 @@
1
+ # `1.5.9`
2
+ Big update
3
+
4
+ This updates comes with many bug fixes:
5
+
6
+ - Fixed [#72](https://github.com/MichaelXF/js-confuser/issues/72)
7
+ - - ES5 to handle Class Fields
8
+
9
+ Note: The `ES5` option is not meant to replace Babel. It is only intended to undo ES6 features the obfuscator may have added to your code.
10
+
11
+ - Fixed [#74](https://github.com/MichaelXF/js-confuser/issues/74)
12
+ - - Anti Tooling to not break Symbols
13
+
14
+ - Fixed [#75](https://github.com/MichaelXF/js-confuser/issues/75)
15
+ - - Minify to properly handle Object constructors
16
+
17
+ - Fixed [#76](https://github.com/MichaelXF/js-confuser/issues/76)
18
+ - - Minify to not cause syntax errors when objects used `^`, `` ` ``, `[`, `]` as property keys
19
+
20
+ - Fixed [#77](https://github.com/MichaelXF/js-confuser/issues/77)
21
+ - - Dispatcher to not break code that uses generic names like `toString` and `hasOwnProperty`
22
+
23
+ - Fixed [#78](https://github.com/MichaelXF/js-confuser/issues/78)
24
+ - - Object Extraction to not error on objects with spread elements
25
+
26
+ - Fixed [#79](https://github.com/MichaelXF/js-confuser/issues/79)
27
+ - - JsConfuser now supports `BigInt` literals
28
+
29
+ - Fixed [#80](https://github.com/MichaelXF/js-confuser/issues/80)
30
+ - - Rename Variables to not break code that had `var` and `let` variables in the same scope
31
+
32
+ - Fixed [#81](https://github.com/MichaelXF/js-confuser/issues/81)
33
+ - - Control Flow Flattening to not break `typeof` expressions
34
+
35
+ - Fixed [#82](https://github.com/MichaelXF/js-confuser/issues/82)
36
+ - - String Concealing to not break class constructors
37
+
38
+ # `1.5.8`
39
+ Several fixes
40
+
41
+ - Fixed [#46](https://github.com/MichaelXF/js-confuser/issues/46)
42
+ - - Updated the validation on `lock` options
43
+
44
+ - Fixed [#68](https://github.com/MichaelXF/js-confuser/issues/68)
45
+ - - Name Recycling fixed to not break certain function declarations
46
+
47
+ - Fixed [#69](https://github.com/MichaelXF/js-confuser/issues/69), [#70](https://github.com/MichaelXF/js-confuser/issues/70) and [#71](https://github.com/MichaelXF/js-confuser/issues/71)
48
+ - - Import statements to be properly handled
49
+
50
+ - Slight improvements to String Concealing
51
+
1
52
  # `1.5.7`
2
53
  Countermeasures function fixes
3
54
 
package/dist/index.js CHANGED
@@ -37,6 +37,8 @@ var _object = require("./util/object");
37
37
 
38
38
  var _presets = _interopRequireDefault(require("./presets"));
39
39
 
40
+ var _perf_hooks = require("perf_hooks");
41
+
40
42
  var assert = _interopRequireWildcard(require("assert"));
41
43
 
42
44
  var _options = require("./options");
@@ -103,7 +105,7 @@ var JsConfuser = async function (code, options) {
103
105
  return result;
104
106
  };
105
107
 
106
- var debugTransformations = async function debugTransformations(code, options) {
108
+ const debugTransformations = async function (code, options) {
107
109
  (0, _options.validateOptions)(options);
108
110
  options = await (0, _options.correctOptions)(options);
109
111
  var frames = [];
@@ -121,21 +123,60 @@ var debugTransformations = async function debugTransformations(code, options) {
121
123
  await obfuscator.apply(tree, true);
122
124
  return frames;
123
125
  };
126
+ /**
127
+ * This method is used by the obfuscator website to display a progress bar and additional information
128
+ * about the obfuscation.
129
+ *
130
+ * @param code - Source code to obfuscate
131
+ * @param options - Options
132
+ * @param callback - Progress callback, called after each transformation
133
+ * @returns
134
+ */
135
+
124
136
 
125
137
  exports.debugTransformations = debugTransformations;
126
138
 
127
- var debugObfuscation = async function debugTransformations(code, options, callback) {
139
+ const debugObfuscation = async function (code, options, callback) {
140
+ const startTime = _perf_hooks.performance.now();
141
+
128
142
  (0, _options.validateOptions)(options);
129
143
  options = await (0, _options.correctOptions)(options);
144
+
145
+ const beforeParseTime = _perf_hooks.performance.now();
146
+
130
147
  var tree = (0, _parser.parseSync)(code);
148
+ const parseTime = _perf_hooks.performance.now() - beforeParseTime;
131
149
  var obfuscator = new _obfuscator.default(options);
132
150
  var totalTransforms = obfuscator.array.length;
151
+ var transformationTimes = Object.create(null);
152
+
153
+ var currentTransformTime = _perf_hooks.performance.now();
154
+
133
155
  obfuscator.on("debug", (name, tree, i) => {
156
+ var nowTime = _perf_hooks.performance.now();
157
+
158
+ transformationTimes[name] = nowTime - currentTransformTime;
159
+ currentTransformTime = nowTime;
134
160
  callback(name, i, totalTransforms);
135
161
  });
136
162
  await obfuscator.apply(tree, true);
137
- var output = (0, _compiler.default)(tree, options);
138
- return output;
163
+
164
+ const beforeCompileTime = _perf_hooks.performance.now();
165
+
166
+ var output = await (0, _compiler.default)(tree, options);
167
+ const compileTime = _perf_hooks.performance.now() - beforeCompileTime;
168
+
169
+ const endTime = _perf_hooks.performance.now();
170
+
171
+ return {
172
+ obfuscated: output,
173
+ transformationTimes: transformationTimes,
174
+ obfuscationTime: endTime - startTime,
175
+ parseTime: parseTime,
176
+ compileTime: compileTime,
177
+ totalTransforms: totalTransforms,
178
+ totalPossibleTransforms: obfuscator.totalPossibleTransforms
179
+ };
139
180
  };
140
181
 
141
182
  exports.debugObfuscation = debugObfuscation;
@@ -94,18 +94,23 @@ class Obfuscator extends _events.EventEmitter {
94
94
 
95
95
  _defineProperty(this, "generated", void 0);
96
96
 
97
+ _defineProperty(this, "totalPossibleTransforms", void 0);
98
+
97
99
  this.varCount = 0;
98
100
  this.transforms = Object.create(null);
99
101
  this.generated = new Set();
102
+ this.totalPossibleTransforms = 0;
100
103
  this.push(new _preparation.default(this));
101
104
  this.push(new _renameLabels.default(this));
102
105
 
103
106
  const test = function (map) {
104
- if ((0, _probability.isProbabilityMapProbable)(map)) {
105
- for (var _len = arguments.length, transformers = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
106
- transformers[_key - 1] = arguments[_key];
107
- }
107
+ for (var _len = arguments.length, transformers = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
108
+ transformers[_key - 1] = arguments[_key];
109
+ }
108
110
 
111
+ _this.totalPossibleTransforms += transformers.length;
112
+
113
+ if ((0, _probability.isProbabilityMapProbable)(map)) {
109
114
  // options.verbose && console.log("+ Added " + transformer.name);
110
115
  transformers.forEach(Transformer => _this.push(new Transformer(_this)));
111
116
  } else {// options.verbose && console.log("- Skipped adding " + transformer.name);
@@ -137,7 +142,7 @@ class Obfuscator extends _events.EventEmitter {
137
142
  test(options.stack, _stack.default);
138
143
  test(true, _antiTooling.default);
139
144
  test(options.hideInitializingCode, _hideInitializingCode.default);
140
- test(options.hexadecimalNumbers, _hexadecimalNumbers.default);
145
+ test(true, _hexadecimalNumbers.default); // BigInt support is included
141
146
 
142
147
  if (options.lock && Object.keys(options.lock).filter(x => x == "domainLock" ? options.lock.domainLock && options.lock.domainLock.length : options.lock[x]).length) {
143
148
  test(true, _lock.default);
package/dist/options.js CHANGED
@@ -40,24 +40,24 @@ function validateOptions(options) {
40
40
 
41
41
  if (options.lock) {
42
42
  // Validate browser-lock option
43
- if (typeof options.lock.browserLock !== "undefined") {
43
+ if (options.lock.browserLock && typeof options.lock.browserLock !== "undefined") {
44
44
  (0, _assert.ok)(Array.isArray(options.lock.browserLock), "browserLock must be an array");
45
45
  (0, _assert.ok)(!options.lock.browserLock.find(browserName => !validBrowsers.has(browserName)), 'Invalid browser name. Allowed: "firefox", "chrome", "iexplorer", "edge", "safari", "opera"');
46
46
  } // Validate os-lock option
47
47
 
48
48
 
49
- if (typeof options.lock.osLock !== "undefined") {
49
+ if (options.lock.osLock && typeof options.lock.osLock !== "undefined") {
50
50
  (0, _assert.ok)(Array.isArray(options.lock.osLock), "osLock must be an array");
51
51
  (0, _assert.ok)(!options.lock.osLock.find(osName => !validOses.has(osName)), 'Invalid OS name. Allowed: "windows", "linux", "osx", "ios", "android"');
52
52
  } // Validate domain-lock option
53
53
 
54
54
 
55
- if (typeof options.lock.domainLock !== "undefined") {
55
+ if (options.lock.domainLock && typeof options.lock.domainLock !== "undefined") {
56
56
  (0, _assert.ok)(Array.isArray(options.lock.domainLock), "domainLock must be an array");
57
57
  } // Validate context option
58
58
 
59
59
 
60
- if (typeof options.lock.context !== "undefined") {
60
+ if (options.lock.context && typeof options.lock.context !== "undefined") {
61
61
  (0, _assert.ok)(Array.isArray(options.lock.context), "context must be an array");
62
62
  } // Validate start-date option
63
63
 
@@ -109,8 +109,7 @@ async function correctOptions(options) {
109
109
 
110
110
  if (options.lock && options.lock.selfDefending) {
111
111
  options.compact = true; // self defending forcibly enables this
112
- } // options.globalVariables was never used.
113
- // GlobalConcealing implicitly determines a global to be a variable referenced but never defined or modified.
112
+ } // options.globalVariables outlines generic globals that should be present in the execution context
114
113
 
115
114
 
116
115
  if (!options.hasOwnProperty("globalVariables")) {
@@ -124,7 +123,7 @@ async function correctOptions(options) {
124
123
  ["global", "Buffer", "require", "process", "__dirname", "__filename"].forEach(x => options.globalVariables.add(x));
125
124
  }
126
125
 
127
- ["globalThis", "console", "parseInt", "parseFloat", "Math", "Promise", "String", "Boolean", "Function", "Object", "Array", "Proxy", "Error", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate", "queueMicrotask", "exports", "module", "isNaN", "isFinite"].forEach(x => options.globalVariables.add(x));
126
+ ["globalThis", "console", "parseInt", "parseFloat", "Math", "Promise", "String", "Boolean", "Function", "Object", "Array", "Proxy", "Error", "TypeError", "ReferenceError", "RangeError", "EvalError", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate", "queueMicrotask", "exports", "module", "isNaN", "isFinite", "Set", "Map", "WeakSet", "WeakMap", "Symbol"].forEach(x => options.globalVariables.add(x));
128
127
  }
129
128
 
130
129
  return options;
package/dist/order.js CHANGED
@@ -33,9 +33,9 @@ exports.ObfuscateOrder = ObfuscateOrder;
33
33
  ObfuscateOrder[ObfuscateOrder["Shuffle"] = 24] = "Shuffle";
34
34
  ObfuscateOrder[ObfuscateOrder["NameRecycling"] = 25] = "NameRecycling";
35
35
  ObfuscateOrder[ObfuscateOrder["MovedDeclarations"] = 26] = "MovedDeclarations";
36
- ObfuscateOrder[ObfuscateOrder["RenameVariables"] = 27] = "RenameVariables";
37
- ObfuscateOrder[ObfuscateOrder["RenameLabels"] = 28] = "RenameLabels";
38
- ObfuscateOrder[ObfuscateOrder["Minify"] = 30] = "Minify";
36
+ ObfuscateOrder[ObfuscateOrder["RenameLabels"] = 27] = "RenameLabels";
37
+ ObfuscateOrder[ObfuscateOrder["Minify"] = 28] = "Minify";
38
+ ObfuscateOrder[ObfuscateOrder["RenameVariables"] = 30] = "RenameVariables";
39
39
  ObfuscateOrder[ObfuscateOrder["ES5"] = 31] = "ES5";
40
40
  ObfuscateOrder[ObfuscateOrder["StringEncoding"] = 32] = "StringEncoding";
41
41
  ObfuscateOrder[ObfuscateOrder["AntiTooling"] = 34] = "AntiTooling";
@@ -50,7 +50,7 @@ class AntiTooling extends _transform.default {
50
50
  if (flattened.length > 1) {
51
51
  flattened[0] = { ...flattened[0]
52
52
  };
53
- this.replace(exprs[0], (0, _gen.ExpressionStatement)((0, _gen.UnaryExpression)((0, _random.choice)(["typeof", "void", "~", "!", "+"]), (0, _gen.SequenceExpression)(flattened))));
53
+ this.replace(exprs[0], (0, _gen.ExpressionStatement)((0, _gen.UnaryExpression)((0, _random.choice)(["typeof", "void", "!"]), (0, _gen.SequenceExpression)(flattened))));
54
54
  deleteExprs.push(...exprs.slice(1));
55
55
  }
56
56
 
@@ -31,6 +31,8 @@ var _expressionObfuscation = _interopRequireDefault(require("./expressionObfusca
31
31
 
32
32
  var _switchCaseObfuscation = _interopRequireDefault(require("./switchCaseObfuscation"));
33
33
 
34
+ var _stringConcealing = require("../string/stringConcealing");
35
+
34
36
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
37
 
36
38
  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; }
@@ -181,6 +183,14 @@ class ControlFlowFlattening extends _transform.default {
181
183
  illegalFnNames.forEach(illegal => {
182
184
  fnNames.delete(illegal);
183
185
  });
186
+ var importDeclarations = [];
187
+
188
+ for (var stmt of body) {
189
+ if (stmt.type === "ImportDeclaration") {
190
+ importDeclarations.push(stmt);
191
+ }
192
+ }
193
+
184
194
  var fraction = 0.9;
185
195
 
186
196
  if (body.length > 20) {
@@ -237,7 +247,7 @@ class ControlFlowFlattening extends _transform.default {
237
247
  body: [...currentBody]
238
248
  });
239
249
  (0, _traverse.walk)(currentBody, [], (o, p) => {
240
- if (o.type == "Literal" && typeof o.value == "string" && !o.regex && Math.random() / (Object.keys(stringBank).length / 2 + 1) > 0.5) {
250
+ if (o.type == "Literal" && typeof o.value == "string" && !(0, _stringConcealing.isModuleSource)(o, p) && !o.regex && Math.random() / (Object.keys(stringBank).length / 2 + 1) > 0.5) {
241
251
  needsStringBankVar = true;
242
252
 
243
253
  if (!stringBankByLabels[currentLabel]) {
@@ -260,7 +270,7 @@ class ControlFlowFlattening extends _transform.default {
260
270
  };
261
271
 
262
272
  body.forEach((stmt, i) => {
263
- if (functionDeclarations.has(stmt)) {
273
+ if (functionDeclarations.has(stmt) || stmt.type === "ImportDeclaration") {
264
274
  return;
265
275
  }
266
276
 
@@ -708,6 +718,10 @@ class ControlFlowFlattening extends _transform.default {
708
718
  var discriminant = (0, _template.default)("".concat(stateVars.join("+"))).single().expression;
709
719
  body.length = 0;
710
720
 
721
+ for (var importDeclaration of importDeclarations) {
722
+ body.push(importDeclaration);
723
+ }
724
+
711
725
  if (functionDeclarations.size) {
712
726
  functionDeclarations.forEach(x => {
713
727
  if (!x.id || illegalFnNames.has(x.id.name)) {
@@ -30,7 +30,8 @@ class ExpressionObfuscation extends _transform.default {
30
30
  if (stmt.type == "ExpressionStatement") {
31
31
  var expr = stmt.expression;
32
32
 
33
- if (expr.type == "UnaryExpression" && exprs.length) {
33
+ if (expr.type == "UnaryExpression" && !(expr.operator === "typeof" && expr.argument.type === "Identifier") && exprs.length // typeof is special
34
+ ) {
34
35
  expr.argument = (0, _gen.SequenceExpression)([...exprs, { ...expr.argument
35
36
  }]);
36
37
  deleteExprs.push(...exprs);
@@ -42,7 +43,8 @@ class ExpressionObfuscation extends _transform.default {
42
43
  if (exprs.length) {
43
44
  if (stmt.type == "IfStatement") {
44
45
  if (stmt.test.type == "BinaryExpression" && stmt.test.operator !== "**") {
45
- if (stmt.test.left.type == "UnaryExpression") {
46
+ if (stmt.test.left.type == "UnaryExpression" && !(stmt.test.left.operator === "typeof" && stmt.test.left.argument.type === "Identifier") // typeof is special
47
+ ) {
46
48
  stmt.test.left.argument = (0, _gen.SequenceExpression)([...exprs, { ...stmt.test.left.argument
47
49
  }]);
48
50
  } else {
@@ -80,12 +80,12 @@ class Dispatcher extends _transform.default {
80
80
  } // Map of FunctionDeclarations
81
81
 
82
82
 
83
- var functionDeclarations = {}; // Array of Identifier nodes
83
+ var functionDeclarations = Object.create(null); // Array of Identifier nodes
84
84
 
85
85
  var identifiers = [];
86
86
  var illegalFnNames = new Set(); // New Names for Functions
87
87
 
88
- var newFnNames = {}; // [old name]: randomized name
88
+ var newFnNames = Object.create(null); // [old name]: randomized name
89
89
 
90
90
  var context = (0, _insert.isVarContext)(object) ? object : (0, _insert.getVarContext)(object, parents);
91
91
  (0, _traverse.walk)(object, parents, (o, p) => {
@@ -264,7 +264,7 @@ class Dispatcher extends _transform.default {
264
264
 
265
265
  var newName = newFnNames[o.name];
266
266
 
267
- if (!newName) {
267
+ if (!newName || typeof newName !== "string") {
268
268
  return;
269
269
  }
270
270
 
@@ -85,9 +85,13 @@ class AntiClass extends _transform.default {
85
85
  this.replace(o, (0, _gen.Identifier)(superName));
86
86
  }
87
87
  });
88
- }
88
+ } // Support class fields
89
+
89
90
 
90
- if (methodDefinition.kind == "constructor" || methodDefinition.kind == "method") {
91
+ if (methodDefinition.type === "PropertyDefinition") {
92
+ var assignmentExpression = (0, _gen.AssignmentExpression)("=", key, value || (0, _gen.Identifier)("undefined"));
93
+ pushingTo.push((0, _gen.ExpressionStatement)(assignmentExpression));
94
+ } else if (methodDefinition.kind == "constructor" || methodDefinition.kind == "method") {
91
95
  pushingTo.push((0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", key, value)));
92
96
  } else if (methodDefinition.kind == "get" || methodDefinition.kind == "set") {
93
97
  var id = (0, _gen.Identifier)(methodDefinition.kind == "get" ? "getters" : "setters");
@@ -189,7 +189,7 @@ class AntiDestructuring extends _transform.default {
189
189
  var seq = (0, _gen.SequenceExpression)([(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(temp), (0, _insert.clone)(extracting) || (0, _gen.Identifier)("undefined")), ...exprs]);
190
190
 
191
191
  if (object.type == "VariableDeclarator") {
192
- var i = (0, _insert.getIndexDirect)(object, parents);
192
+ var i = (0, _insert.getIndexDirect)(object, parents[0]);
193
193
  var extra = Array.from(names).map(x => {
194
194
  return {
195
195
  type: "VariableDeclarator",
@@ -31,6 +31,17 @@ class Eval extends _transform.default {
31
31
  }
32
32
 
33
33
  transform(object, parents) {
34
+ // Don't apply to getter/setters or class methods
35
+ if (parents[0]) {
36
+ if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
37
+ return;
38
+ }
39
+
40
+ if (parents[0].type === "Property" && parents[0].value === object && (parents[0].kind !== "init" || parents[0].method)) {
41
+ return;
42
+ }
43
+ }
44
+
34
45
  if (!(0, _probability.ComputeProbabilityMap)(this.options.eval, x => x, object.id && object.id.name)) {
35
46
  return;
36
47
  }
@@ -113,7 +113,7 @@ class DuplicateLiteralsRemoval extends _transform.default {
113
113
  var body = [];
114
114
  var thisShift = (0, _random.getRandomInteger)(-250, 250); // the name of the getter
115
115
 
116
- getterName = this.getPlaceholder();
116
+ getterName = this.getPlaceholder() + "_dLR_" + this.fnGetters.size;
117
117
 
118
118
  if (basedOn) {
119
119
  var shift = this.fnShifts.get(basedOn);
@@ -179,17 +179,17 @@ class DuplicateLiteralsRemoval extends _transform.default {
179
179
  this.arrayExpression = (0, _gen.ArrayExpression)([]);
180
180
  }
181
181
 
182
- var first = this.first.get(value);
182
+ var firstLocation = this.first.get(value);
183
183
 
184
- if (first) {
184
+ if (firstLocation) {
185
185
  this.first.set(value, null);
186
186
  var index = this.map.size;
187
187
  (0, _assert.ok)(!this.map.has(value));
188
188
  this.map.set(value, index);
189
- this.toCaller(first[0], first[1], index);
190
189
  var pushing = (0, _insert.clone)(object);
191
190
  this.arrayExpression.elements.push(pushing);
192
191
  (0, _assert.ok)(this.arrayExpression.elements[index] === pushing);
192
+ this.toCaller(firstLocation[0], firstLocation[1], index);
193
193
  }
194
194
 
195
195
  var index = this.map.get(value);
@@ -97,7 +97,12 @@ class ObjectExtraction extends _transform.default {
97
97
  var nonInitOrComputed = object.properties.find(x => x.kind !== "init" || x.computed);
98
98
 
99
99
  if (nonInitOrComputed) {
100
- this.log(name + " has non-init/computed property: " + nonInitOrComputed.key.name || nonInitOrComputed.key.value);
100
+ if (nonInitOrComputed.key) {
101
+ this.log(name + " has non-init/computed property: " + nonInitOrComputed.key.name || nonInitOrComputed.key.value);
102
+ } else {
103
+ this.log(name + " has spread-element or other type of property");
104
+ }
105
+
101
106
  illegal.add(name);
102
107
  return;
103
108
  } else {