js-confuser 1.5.9 → 1.7.0

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 (143) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +346 -165
  4. package/dist/constants.js +6 -2
  5. package/dist/index.js +9 -21
  6. package/dist/obfuscator.js +19 -31
  7. package/dist/options.js +5 -5
  8. package/dist/order.js +1 -3
  9. package/dist/presets.js +6 -7
  10. package/dist/probability.js +2 -4
  11. package/dist/templates/bufferToString.js +13 -0
  12. package/dist/templates/crash.js +3 -3
  13. package/dist/templates/es5.js +18 -0
  14. package/dist/templates/functionLength.js +16 -0
  15. package/dist/transforms/calculator.js +77 -21
  16. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  17. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -1
  18. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  19. package/dist/transforms/deadCode.js +33 -25
  20. package/dist/transforms/dispatcher.js +8 -4
  21. package/dist/transforms/es5/antiDestructuring.js +2 -0
  22. package/dist/transforms/es5/es5.js +31 -34
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +92 -58
  24. package/dist/transforms/finalizer.js +82 -0
  25. package/dist/transforms/flatten.js +229 -148
  26. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  27. package/dist/transforms/identifier/globalConcealing.js +10 -83
  28. package/dist/transforms/identifier/movedDeclarations.js +35 -88
  29. package/dist/transforms/identifier/renameVariables.js +124 -59
  30. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  31. package/dist/transforms/lock/lock.js +0 -37
  32. package/dist/transforms/minify.js +60 -57
  33. package/dist/transforms/opaquePredicates.js +1 -1
  34. package/dist/transforms/preparation/preparation.js +2 -2
  35. package/dist/transforms/preparation.js +231 -0
  36. package/dist/transforms/renameLabels.js +1 -1
  37. package/dist/transforms/rgf.js +139 -247
  38. package/dist/transforms/stack.js +128 -26
  39. package/dist/transforms/string/encoding.js +150 -179
  40. package/dist/transforms/string/stringCompression.js +14 -15
  41. package/dist/transforms/string/stringConcealing.js +25 -8
  42. package/dist/transforms/string/stringEncoding.js +13 -24
  43. package/dist/transforms/transform.js +12 -19
  44. package/dist/traverse.js +24 -10
  45. package/dist/util/gen.js +17 -1
  46. package/dist/util/identifiers.js +37 -3
  47. package/dist/util/insert.js +35 -4
  48. package/dist/util/random.js +15 -0
  49. package/docs/ControlFlowFlattening.md +595 -0
  50. package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
  51. package/{Integrity.md → docs/Integrity.md} +2 -2
  52. package/docs/RGF.md +419 -0
  53. package/package.json +5 -5
  54. package/src/constants.ts +3 -0
  55. package/src/index.ts +2 -2
  56. package/src/obfuscator.ts +19 -31
  57. package/src/options.ts +14 -103
  58. package/src/order.ts +1 -5
  59. package/src/presets.ts +6 -7
  60. package/src/probability.ts +2 -3
  61. package/src/templates/bufferToString.ts +68 -0
  62. package/src/templates/crash.ts +15 -19
  63. package/src/templates/es5.ts +131 -0
  64. package/src/templates/functionLength.ts +14 -0
  65. package/src/transforms/calculator.ts +122 -59
  66. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  67. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +4 -1
  68. package/src/transforms/deadCode.ts +383 -26
  69. package/src/transforms/dispatcher.ts +9 -4
  70. package/src/transforms/es5/antiDestructuring.ts +2 -0
  71. package/src/transforms/es5/es5.ts +32 -77
  72. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +133 -129
  73. package/src/transforms/{hexadecimalNumbers.ts → finalizer.ts} +29 -13
  74. package/src/transforms/flatten.ts +357 -300
  75. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  76. package/src/transforms/identifier/globalConcealing.ts +14 -103
  77. package/src/transforms/identifier/movedDeclarations.ts +49 -102
  78. package/src/transforms/identifier/renameVariables.ts +149 -78
  79. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  80. package/src/transforms/lock/lock.ts +1 -42
  81. package/src/transforms/minify.ts +91 -75
  82. package/src/transforms/opaquePredicates.ts +2 -2
  83. package/src/transforms/preparation.ts +238 -0
  84. package/src/transforms/renameLabels.ts +2 -2
  85. package/src/transforms/rgf.ts +213 -405
  86. package/src/transforms/stack.ts +156 -36
  87. package/src/transforms/string/encoding.ts +115 -212
  88. package/src/transforms/string/stringCompression.ts +27 -18
  89. package/src/transforms/string/stringConcealing.ts +39 -9
  90. package/src/transforms/string/stringEncoding.ts +18 -18
  91. package/src/transforms/transform.ts +21 -23
  92. package/src/traverse.ts +23 -4
  93. package/src/types.ts +2 -1
  94. package/src/util/gen.ts +28 -3
  95. package/src/util/identifiers.ts +43 -2
  96. package/src/util/insert.ts +38 -3
  97. package/src/util/random.ts +13 -0
  98. package/test/code/Cash.test.ts +1 -1
  99. package/test/code/Dynamic.test.ts +12 -10
  100. package/test/code/ES6.src.js +146 -0
  101. package/test/code/ES6.test.ts +28 -2
  102. package/test/index.test.ts +2 -1
  103. package/test/probability.test.ts +44 -0
  104. package/test/templates/template.test.ts +1 -1
  105. package/test/transforms/antiTooling.test.ts +22 -0
  106. package/test/transforms/calculator.test.ts +40 -0
  107. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +702 -160
  108. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  109. package/test/transforms/deadCode.test.ts +66 -15
  110. package/test/transforms/dispatcher.test.ts +20 -1
  111. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  112. package/test/transforms/flatten.test.ts +399 -86
  113. package/test/transforms/identifier/movedDeclarations.test.ts +63 -8
  114. package/test/transforms/identifier/renameVariables.test.ts +119 -0
  115. package/test/transforms/lock/antiDebug.test.ts +2 -2
  116. package/test/transforms/lock/lock.test.ts +1 -48
  117. package/test/transforms/minify.test.ts +104 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +261 -381
  120. package/test/transforms/stack.test.ts +143 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +82 -0
  123. package/test/transforms/string/stringEncoding.test.ts +53 -2
  124. package/test/transforms/transform.test.ts +66 -0
  125. package/test/traverse.test.ts +139 -0
  126. package/test/util/identifiers.test.ts +113 -1
  127. package/test/util/insert.test.ts +57 -3
  128. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  129. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  130. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  131. package/src/transforms/eval.ts +0 -89
  132. package/src/transforms/hideInitializingCode.ts +0 -432
  133. package/src/transforms/identifier/nameRecycling.ts +0 -280
  134. package/src/transforms/label.ts +0 -64
  135. package/src/transforms/preparation/nameConflicts.ts +0 -102
  136. package/src/transforms/preparation/preparation.ts +0 -176
  137. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  138. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  139. package/test/transforms/eval.test.ts +0 -131
  140. package/test/transforms/hideInitializingCode.test.ts +0 -336
  141. package/test/transforms/identifier/nameRecycling.test.ts +0 -205
  142. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  143. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -1,64 +0,0 @@
1
- import Transform from "./transform";
2
- import { Identifier, LabeledStatement } from "../util/gen";
3
- import { walk } from "../traverse";
4
- import { clone } from "../util/insert";
5
- import { isLoop } from "../util/compare";
6
-
7
- /**
8
- * Ensures every break; statement has a label to point to.
9
- *
10
- * This is because Control Flow Flattening adds For Loops which label-less break statements point to the nearest,
11
- * when they actually need to point to the original statement.
12
- */
13
- export default class Label extends Transform {
14
- constructor(o) {
15
- super(o);
16
- }
17
-
18
- match(object, parents) {
19
- return (
20
- isLoop(object) ||
21
- (object.type == "BlockStatement" &&
22
- parents[0] &&
23
- parents[0].type == "LabeledStatement" &&
24
- parents[0].body === object)
25
- );
26
- }
27
-
28
- transform(object, parents) {
29
- return () => {
30
- var currentLabel =
31
- parents[0].type == "LabeledStatement" && parents[0].label.name;
32
-
33
- var label = currentLabel || this.getPlaceholder();
34
-
35
- walk(object, parents, (o, p) => {
36
- if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
37
- function isContinuableStatement(x) {
38
- return isLoop(x) && x.type !== "SwitchStatement";
39
- }
40
- function isBreakableStatement(x) {
41
- return isLoop(x) || (o.label && x.type == "BlockStatement");
42
- }
43
-
44
- var fn =
45
- o.type == "ContinueStatement"
46
- ? isContinuableStatement
47
- : isBreakableStatement;
48
-
49
- var loop = p.find(fn);
50
- if (object == loop) {
51
- if (!o.label) {
52
- o.label = Identifier(label);
53
- }
54
- }
55
- }
56
- });
57
-
58
- // Append label statement as this loop has none
59
- if (!currentLabel) {
60
- this.replace(object, LabeledStatement(label, { ...object }));
61
- }
62
- };
63
- }
64
- }
@@ -1,102 +0,0 @@
1
- import { reservedIdentifiers } from "../../constants";
2
- import { Node } from "../../util/gen";
3
- import {
4
- getDefiningIdentifier,
5
- getIdentifierInfo,
6
- } from "../../util/identifiers";
7
- import Transform from "../transform";
8
-
9
- export class NameMappingAnalysis extends Transform {
10
- names: Map<string, Set<Node>>;
11
-
12
- constructor(o) {
13
- super(o);
14
-
15
- this.names = new Map();
16
- }
17
-
18
- match(object, parents) {
19
- return object.type == "Identifier" && !reservedIdentifiers.has(object.name);
20
- }
21
-
22
- transform(object, parents) {
23
- var info = getIdentifierInfo(object, parents);
24
-
25
- if (info.spec.isReferenced && !info.spec.isDefined) {
26
- object.$definedAt = getDefiningIdentifier(object, parents);
27
- }
28
-
29
- if (info.spec.isDefined) {
30
- if (!this.names.has(object.name)) {
31
- this.names.set(object.name, new Set([object]));
32
- } else {
33
- this.names.get(object.name).add(object);
34
- }
35
- }
36
- }
37
- }
38
-
39
- /**
40
- * Renames variables & removes conflicts.
41
- *
42
- * - This helps transformations like `Dispatcher` not replace re-declared identifiers.
43
- */
44
- export default class NameConflicts extends Transform {
45
- nameMappingAnalysis: NameMappingAnalysis;
46
-
47
- changes: Map<Node, string>;
48
- references: Map<Node, Set<Node>>;
49
-
50
- constructor(o) {
51
- super(o);
52
-
53
- this.before.push((this.nameMappingAnalysis = new NameMappingAnalysis(o)));
54
- this.changes = new Map();
55
- this.references = new Map();
56
- }
57
-
58
- match(object, parents) {
59
- return (
60
- object.type == "Identifier" &&
61
- !reservedIdentifiers.has(object.name) &&
62
- !this.options.globalVariables.has(object.name)
63
- );
64
- }
65
-
66
- transform(object: Node, parents: Node[]) {
67
- var info = getIdentifierInfo(object, parents);
68
-
69
- if (info.isMethodDefinition) {
70
- return;
71
- }
72
-
73
- if (object.$definedAt) {
74
- object.name = this.changes.get(object.$definedAt[0]) || object.name;
75
-
76
- if (!this.references.has(object.$definedAt[0])) {
77
- this.references.set(object.$definedAt[0], new Set([object]));
78
- } else {
79
- this.references.get(object.$definedAt[0]).add(object);
80
- }
81
- } else if (info.spec.isDefined) {
82
- var set = this.nameMappingAnalysis.names.get(object.name);
83
- if (set && set.size > 1) {
84
- var index = Array.from(set).indexOf(object);
85
-
86
- var newName = "_".repeat(index) + object.name;
87
-
88
- if (index > 4 || this.nameMappingAnalysis.names.has(newName)) {
89
- newName = this.getPlaceholder() + "_" + object.name;
90
- }
91
-
92
- object.name = newName;
93
- this.changes.set(object, newName);
94
- if (this.references.has(object)) {
95
- this.references.get(object).forEach((ref) => {
96
- ref.name = newName;
97
- });
98
- }
99
- }
100
- }
101
- }
102
- }
@@ -1,176 +0,0 @@
1
- /**
2
- * The file contains all preparation transformations
3
- */
4
- import Transform from "../transform";
5
-
6
- import { BlockStatement, Literal, ReturnStatement } from "../../util/gen";
7
- import { ObfuscateOrder } from "../../order";
8
- import { clone, getFunction } from "../../util/insert";
9
- import { getIdentifierInfo } from "../../util/identifiers";
10
- import Label from "../label";
11
- import { isLoop } from "../../util/compare";
12
-
13
- /**
14
- * People use shortcuts and its harder to parse.
15
- *
16
- * - `if (a) b()` -> `if (a) { b() }`
17
- * - Ensures all bodies are `BlockStatement`, not individual expression statements
18
- */
19
- class Block extends Transform {
20
- constructor(o) {
21
- super(o);
22
- }
23
-
24
- match(object, parents) {
25
- return !Array.isArray(object);
26
- }
27
-
28
- transform(object, parents) {
29
- switch (object.type) {
30
- case "IfStatement":
31
- if (object.consequent.type != "BlockStatement") {
32
- object.consequent = BlockStatement([clone(object.consequent)]);
33
- }
34
- if (object.alternate && object.alternate.type != "BlockStatement") {
35
- object.alternate = BlockStatement([clone(object.alternate)]);
36
- }
37
- break;
38
-
39
- case "WhileStatement":
40
- case "WithStatement":
41
- case "ForStatement":
42
- case "ForOfStatement":
43
- case "ForInStatement":
44
- if (object.body.type != "BlockStatement") {
45
- object.body = BlockStatement([clone(object.body)]);
46
- }
47
- break;
48
-
49
- case "ArrowFunctionExpression":
50
- if (object.body.type !== "BlockStatement" && object.expression) {
51
- object.body = BlockStatement([ReturnStatement(clone(object.body))]);
52
- object.expression = false;
53
- }
54
- break;
55
- }
56
- }
57
- }
58
-
59
- class ExplicitIdentifiers extends Transform {
60
- constructor(o) {
61
- super(o);
62
- }
63
-
64
- match(object, parents) {
65
- return object.type == "Identifier";
66
- }
67
-
68
- transform(object, parents) {
69
- if (object.name === "eval") {
70
- var fn = getFunction(object, parents);
71
- if (fn) {
72
- fn.$requiresEval = true;
73
- }
74
- }
75
-
76
- var info = getIdentifierInfo(object, parents);
77
- if (info.isPropertyKey || info.isAccessor) {
78
- var propIndex = parents.findIndex(
79
- (x) => x.type == "MethodDefinition" || x.type == "Property"
80
- );
81
- if (propIndex !== -1) {
82
- if (
83
- parents[propIndex].type == "MethodDefinition" &&
84
- parents[propIndex].kind == "constructor"
85
- ) {
86
- return;
87
- }
88
- }
89
-
90
- this.log(object.name, "->", `'${object.name}'`);
91
-
92
- this.replace(object, Literal(object.name));
93
- parents[0].computed = true;
94
- parents[0].shorthand = false;
95
- }
96
- }
97
- }
98
-
99
- class ExplicitDeclarations extends Transform {
100
- constructor(o) {
101
- super(o);
102
- }
103
-
104
- match(object, parents) {
105
- return object.type == "VariableDeclaration";
106
- }
107
-
108
- transform(object, parents) {
109
- // for ( var x in ... ) {...}
110
- var forIndex = parents.findIndex(
111
- (x) => x.type == "ForInStatement" || x.type == "ForOfStatement"
112
- );
113
- if (
114
- forIndex != -1 &&
115
- parents[forIndex].left == (parents[forIndex - 1] || object)
116
- ) {
117
- object.declarations.forEach((x) => {
118
- x.init = null;
119
- });
120
- return;
121
- }
122
-
123
- var body = parents[0];
124
- if (isLoop(body) || body.type == "LabeledStatement") {
125
- return;
126
- }
127
-
128
- if (body.type == "ExportNamedDeclaration") {
129
- return;
130
- }
131
-
132
- if (!Array.isArray(body)) {
133
- this.error(new Error("body is " + body.type));
134
- }
135
-
136
- if (object.declarations.length > 1) {
137
- // Make singular
138
-
139
- var index = body.indexOf(object);
140
- if (index == -1) {
141
- this.error(new Error("index is -1"));
142
- }
143
-
144
- var after = object.declarations.slice(1);
145
-
146
- body.splice(
147
- index + 1,
148
- 0,
149
- ...after.map((x) => {
150
- return {
151
- type: "VariableDeclaration",
152
- declarations: [clone(x)],
153
- kind: object.kind,
154
- };
155
- })
156
- );
157
-
158
- object.declarations.length = 1;
159
- }
160
- }
161
- }
162
-
163
- export default class Preparation extends Transform {
164
- constructor(o) {
165
- super(o, ObfuscateOrder.Preparation);
166
-
167
- this.before.push(new Block(o));
168
- this.before.push(new Label(o));
169
- this.before.push(new ExplicitIdentifiers(o));
170
- this.before.push(new ExplicitDeclarations(o));
171
- }
172
-
173
- match() {
174
- return false;
175
- }
176
- }
@@ -1,101 +0,0 @@
1
- import JsConfuser from "../../../src/index";
2
-
3
- it("should obfuscate for loops (ControlFlowObfuscation)", async () => {
4
- var code = `
5
- var array = [];
6
-
7
- for ( var i = 1; i <= 10; i++ ) {
8
- array.push(i);
9
- }
10
-
11
- input(array);
12
- `;
13
-
14
- var output = await JsConfuser(code, {
15
- target: "browser",
16
- controlFlowFlattening: true,
17
- });
18
-
19
- expect(output).toContain("switch");
20
-
21
- function input(array) {
22
- expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
23
- }
24
-
25
- eval(output);
26
- });
27
-
28
- it("should obfuscate while loops (ControlFlowObfuscation)", async () => {
29
- var code = `
30
- var array = [];
31
- var i = 1;
32
-
33
- while ( i <= 10 ) {
34
- array.push(i);
35
- i++
36
- }
37
-
38
- input(array);
39
- `;
40
-
41
- var output = await JsConfuser(code, {
42
- target: "browser",
43
- controlFlowFlattening: true,
44
- });
45
-
46
- expect(output).toContain("switch");
47
-
48
- function input(array) {
49
- expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
50
- }
51
-
52
- eval(output);
53
- });
54
-
55
- it("should work with break statements (ControlFlowObfuscation)", async () => {
56
- var code = `
57
-
58
- var TEST_ARRAY = [];
59
-
60
- for ( var i =1; true; i++ ) {
61
- if ( i == 11 ) {
62
- break;
63
- }
64
- TEST_ARRAY.push(i);
65
- }
66
-
67
- input(TEST_ARRAY);
68
- `;
69
-
70
- var output = await JsConfuser(code, {
71
- target: "browser",
72
- controlFlowFlattening: true,
73
- });
74
-
75
- expect(output).toContain("switch");
76
- expect(output).toContain("while");
77
-
78
- function input(array) {
79
- expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
80
- }
81
-
82
- eval(output);
83
- });
84
-
85
- it("should not obfuscate code with `let` (Lexically bound variables, ControlFlowObfuscation)", async () => {
86
- var code = `
87
- var array=[];
88
- for ( let i =1; i <= 10; i++ ) {
89
- array.push(i);
90
- }
91
-
92
- input(array);
93
- `;
94
-
95
- var output = await JsConfuser(code, {
96
- target: "node",
97
- controlFlowFlattening: true,
98
- });
99
-
100
- expect(output).not.toContain("switch");
101
- });
@@ -1,120 +0,0 @@
1
- import JsConfuser from "../../../src/index";
2
-
3
- it("should obfuscate numbered switch statements (SwitchCaseObfuscation)", async () => {
4
- var code = `
5
- var array = [];
6
-
7
- function runOnce(stateParam){
8
- switch(stateParam){
9
- case 1: array.push(1, 2, 3); break;
10
- case 2: array.push(4, 5, 6); break;
11
- case 3: array.push(7, 8, 9); break;
12
- case 4: array.push(10); break;
13
- }
14
- }
15
-
16
- runOnce(1);
17
- runOnce(2);
18
- runOnce(3);
19
- runOnce(4);
20
-
21
- input(array);
22
- `;
23
-
24
- var output = await JsConfuser(code, {
25
- target: "browser",
26
- controlFlowFlattening: true,
27
- });
28
-
29
- expect(
30
- output.includes("case 1:") &&
31
- output.includes("case 2:") &&
32
- output.includes("case 3:") &&
33
- output.includes("case 4:")
34
- ).toStrictEqual(false);
35
-
36
- function input(array) {
37
- expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
38
- }
39
-
40
- eval(output);
41
- });
42
-
43
- it("should not obfuscate switch statements with complex discriminants (SwitchCaseObfuscation)", async () => {
44
- var code = `
45
- var array = [];
46
-
47
- function runOnce(stateParam){
48
- switch(stateParam || 0){
49
- case 1: array.push(1, 2, 3); break;
50
- case 2: array.push(4, 5, 6); break;
51
- case 3: array.push(7, 8, 9); break;
52
- case 4: array.push(10); break;
53
- }
54
- }
55
-
56
- runOnce(1);
57
- runOnce(2);
58
- runOnce(3);
59
- runOnce(4);
60
-
61
- input(array);
62
- `;
63
-
64
- var output = await JsConfuser(code, {
65
- target: "browser",
66
- controlFlowFlattening: true,
67
- });
68
-
69
- expect(output).toContain("stateParam||0");
70
-
71
- function input(array) {
72
- expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
73
- }
74
-
75
- eval(output);
76
- });
77
-
78
- // https://github.com/MichaelXF/js-confuser/issues/41
79
- it("Not apply to switch statements with default cases", async ()=>{
80
-
81
- var code = `
82
- var array = [];
83
-
84
- function runOnce(stateParam){
85
- switch(stateParam){
86
- case 1: array.push(1, 2, 3); break;
87
- case 2: array.push(4, 5, 6); break;
88
- case 3: array.push(7, 8, 9); break;
89
- default: array.push(10); break;
90
- }
91
- }
92
-
93
- runOnce(1);
94
- runOnce(2);
95
- runOnce(3);
96
- runOnce(-1); // default case
97
-
98
- input(array);
99
- `;
100
-
101
- var output = await JsConfuser(code, {
102
- target: "browser",
103
- controlFlowFlattening: true,
104
- });
105
-
106
- expect(
107
- output.includes("case 1:") &&
108
- output.includes("case 2:") &&
109
- output.includes("case 3:")
110
- ).toStrictEqual(true);
111
-
112
- function input(array) {
113
- expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
114
- }
115
-
116
- eval(output);
117
-
118
-
119
-
120
- });
@@ -1,131 +0,0 @@
1
- import JsConfuser from "../../src/index";
2
-
3
- it("should put functions into eval statements", async () => {
4
- var code = `
5
- function TEST_FUNCTION(){
6
- }
7
- `;
8
-
9
- var output = await JsConfuser(code, { target: "node", eval: true });
10
-
11
- expect(output).toContain("eval(");
12
- });
13
-
14
- it("should put functions into eval statements and have same result", async () => {
15
- var code = `
16
- function TEST_FUNCTION(){
17
- input(100)
18
- }
19
- TEST_FUNCTION();
20
- `;
21
-
22
- var output = await JsConfuser(code, { target: "node", eval: true });
23
-
24
- expect(output).toContain("eval(");
25
-
26
- var value = "never_called",
27
- input = (valueIn) => (value = valueIn);
28
- eval(output);
29
-
30
- expect(value).toStrictEqual(100);
31
- });
32
-
33
- it("should move function declarations to the top of the block", async () => {
34
- var code = `
35
- TEST_FUNCTION();
36
- function TEST_FUNCTION(){
37
- input(100)
38
- }
39
- `;
40
-
41
- var output = await JsConfuser(code, { target: "node", eval: true });
42
-
43
- expect(output).toContain("eval(");
44
-
45
- var value = "never_called",
46
- input = (valueIn) => (value = valueIn);
47
- eval(output);
48
-
49
- expect(value).toStrictEqual(100);
50
- });
51
-
52
- it("should work with Integrity also enabled", async () => {
53
- var code = `
54
- input("Hello World")
55
- `;
56
-
57
- var output = await JsConfuser(code, {
58
- target: "node",
59
- compact: false,
60
- eval: true,
61
- lock: {
62
- integrity: true,
63
- },
64
- });
65
-
66
- expect(output).toContain("eval(");
67
-
68
- var value = "never_called",
69
- input = (valueIn) => (value = valueIn);
70
-
71
- try {
72
- eval(output);
73
- } catch (e) {
74
- expect(e).toStrictEqual(undefined);
75
- }
76
-
77
- expect(value).toStrictEqual("Hello World");
78
- });
79
-
80
- it("should work on async functions", async () => {
81
- var output = await JsConfuser(
82
- `
83
- async function myFunction(){
84
- return "Correct Value";
85
- }
86
-
87
- (async ()=>{
88
- TEST_FUNCTION( await myFunction() );
89
- })();
90
- `,
91
- { target: "node", eval: true }
92
- );
93
-
94
- expect(output).toContain("eval");
95
-
96
- var wasCalled = false;
97
-
98
- function TEST_FUNCTION(value) {
99
- wasCalled = true;
100
- expect(value).toStrictEqual("Correct Value");
101
- }
102
-
103
- eval(output);
104
-
105
- setTimeout(() => {
106
- expect(wasCalled).toStrictEqual(true);
107
- }, 1000);
108
- });
109
-
110
- it("should work on generator functions", async () => {
111
- var output = await JsConfuser(
112
- `
113
- function* myFunction(){
114
- yield "Correct Value";
115
- }
116
-
117
- const gen = myFunction();
118
-
119
- TEST_OUTPUT = gen.next().value;
120
- `,
121
- { target: "node", eval: true }
122
- );
123
-
124
- expect(output).toContain("eval");
125
-
126
- var TEST_OUTPUT;
127
-
128
- eval(output);
129
-
130
- expect(TEST_OUTPUT).toStrictEqual("Correct Value");
131
- });