js-confuser 2.0.0-alpha.4 → 2.0.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.
@@ -107,7 +107,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
107
107
  // Breaks any code formatter
108
108
  var namedFunction = function(){
109
109
  const test = function(){
110
- const regExp=new RegExp('\\n');
110
+ const regExp= new RegExp('\\n');
111
111
  return regExp['test'](namedFunction)
112
112
  };
113
113
 
@@ -116,13 +116,6 @@ export default ({ Plugin }: PluginArg): PluginObject => {
116
116
  }
117
117
  }
118
118
 
119
- // Prepack Breaker
120
- if(Math.random() > 1) {
121
- while(true) {
122
- console.log("Prepack Breaker");
123
- }
124
- }
125
-
126
119
  return namedFunction();
127
120
  }
128
121
  )();
@@ -60,6 +60,14 @@ export default function pack({ Plugin }: PluginArg): PluginObject {
60
60
  // Ensure bindings are removed -> variable becomes a global -> added to mappings object
61
61
  path.scope.crawl();
62
62
  },
63
+
64
+ // TODO: Add support for export statements
65
+ "ExportNamedDeclaration|ExportDefaultDeclaration|ExportAllDeclaration"(
66
+ path
67
+ ) {
68
+ me.error("Export statements are not supported in packed code.");
69
+ },
70
+
63
71
  Program(path) {
64
72
  path.scope.crawl();
65
73
  },
@@ -97,14 +97,24 @@ export class PluginInstance {
97
97
  );
98
98
  }
99
99
 
100
+ const createCallArguments = (node: t.Expression): t.Expression[] => {
101
+ var args = [node];
102
+
103
+ // 1 is the default value in the setFunction template, can exclude it
104
+ if (originalLength !== 1) {
105
+ args.push(numericLiteral(originalLength));
106
+ }
107
+ return args;
108
+ };
109
+
100
110
  if (t.isFunctionDeclaration(path.node)) {
101
111
  prepend(
102
112
  path.parentPath,
103
113
  t.expressionStatement(
104
- t.callExpression(t.identifier(this.setFunctionLengthName), [
105
- t.identifier(path.node.id.name),
106
- numericLiteral(originalLength),
107
- ])
114
+ t.callExpression(
115
+ t.identifier(this.setFunctionLengthName),
116
+ createCallArguments(t.identifier(path.node.id.name))
117
+ )
108
118
  )
109
119
  );
110
120
  } else if (
@@ -112,10 +122,10 @@ export class PluginInstance {
112
122
  t.isArrowFunctionExpression(path.node)
113
123
  ) {
114
124
  path.replaceWith(
115
- t.callExpression(t.identifier(this.setFunctionLengthName), [
116
- path.node,
117
- numericLiteral(originalLength),
118
- ])
125
+ t.callExpression(
126
+ t.identifier(this.setFunctionLengthName),
127
+ createCallArguments(path.node)
128
+ )
119
129
  );
120
130
  } else {
121
131
  // TODO
@@ -158,6 +168,6 @@ export class PluginInstance {
158
168
  * @param messages
159
169
  */
160
170
  error(...messages: any[]): never {
161
- throw new Error(`[${this.name}] ${messages.join(", ")}`);
171
+ throw new Error(`[${this.name}] ${messages.join(" ")}`);
162
172
  }
163
173
  }
@@ -45,6 +45,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
45
45
  const blocks: NodePath<t.Block>[] = [];
46
46
  const stringMap = new Map<string, number>();
47
47
  const stringArrayName = me.getPlaceholder() + "_array";
48
+ const stringArrayCacheName = me.getPlaceholder() + "_cache";
48
49
 
49
50
  let encodingImplementations: { [identity: string]: CustomStringEncoding } =
50
51
  Object.create(null);
@@ -263,6 +264,16 @@ export default ({ Plugin }: PluginArg): PluginObject => {
263
264
  ])
264
265
  );
265
266
 
267
+ // Create the string cache
268
+ prependProgram(
269
+ programPath,
270
+ new Template(`
271
+ var {stringArrayCacheName} = {};
272
+ `).single({
273
+ stringArrayCacheName,
274
+ })
275
+ );
276
+
266
277
  for (var block of blocks) {
267
278
  const { encodingImplementation, fnName } = (
268
279
  block.node as NodeStringConcealing
@@ -283,7 +294,10 @@ export default ({ Plugin }: PluginArg): PluginObject => {
283
294
  // The main function to get the string value
284
295
  const retrieveFunctionDeclaration = new Template(`
285
296
  function ${fnName}(index) {
286
- return ${decodeFnName}(${stringArrayName}[index]);
297
+ if (typeof ${stringArrayCacheName}[index] === 'undefined') {
298
+ return ${stringArrayCacheName}[index] = ${decodeFnName}(${stringArrayName}[index]);
299
+ }
300
+ return ${stringArrayCacheName}[index];
287
301
  }
288
302
  `)
289
303
  .addSymbols(NO_REMOVE)
@@ -215,17 +215,6 @@ export function getMemberExpressionPropertyAsString(
215
215
  return null; // If the property cannot be determined
216
216
  }
217
217
 
218
- function registerPaths(paths: NodePath[]) {
219
- for (var path of paths) {
220
- if (path.isVariableDeclaration() && path.node.kind === "var") {
221
- getParentFunctionOrProgram(path).scope.registerDeclaration(path);
222
- }
223
- path.scope.registerDeclaration(path);
224
- }
225
-
226
- return paths;
227
- }
228
-
229
218
  function nodeListToNodes(nodesIn: (t.Statement | t.Statement[])[]) {
230
219
  var nodes: t.Statement[] = [];
231
220
  if (Array.isArray(nodesIn[0])) {
@@ -257,12 +246,12 @@ export function append(
257
246
  if (listParent.isProgram()) {
258
247
  var lastExpression = listParent.get("body").at(-1);
259
248
  if (lastExpression.isExpressionStatement()) {
260
- return registerPaths(lastExpression.insertBefore(nodes));
249
+ return lastExpression.insertBefore(nodes);
261
250
  }
262
251
  }
263
252
 
264
253
  if (listParent.isSwitchCase()) {
265
- return registerPaths(listParent.pushContainer("consequent", nodes));
254
+ return listParent.pushContainer("consequent", nodes);
266
255
  }
267
256
 
268
257
  if (listParent.isFunction()) {
@@ -278,11 +267,11 @@ export function append(
278
267
 
279
268
  ok(body.isBlockStatement());
280
269
 
281
- return registerPaths(body.pushContainer("body", nodes));
270
+ return body.pushContainer("body", nodes);
282
271
  }
283
272
 
284
273
  ok(listParent.isBlock());
285
- return registerPaths(listParent.pushContainer("body", nodes));
274
+ return listParent.pushContainer("body", nodes);
286
275
  }
287
276
 
288
277
  /**
@@ -322,11 +311,11 @@ export function prepend(
322
311
 
323
312
  if (afterImport === 0) {
324
313
  // No import declarations, so we can safely unshift everything
325
- return registerPaths(listParent.unshiftContainer("body", nodes));
314
+ return listParent.unshiftContainer("body", nodes);
326
315
  }
327
316
 
328
317
  // Insert the nodes after the last import declaration
329
- return registerPaths(body[afterImport - 1].insertAfter(nodes));
318
+ return body[afterImport - 1].insertAfter(nodes);
330
319
  }
331
320
 
332
321
  if (listParent.isFunction()) {
@@ -342,15 +331,15 @@ export function prepend(
342
331
 
343
332
  ok(body.isBlockStatement());
344
333
 
345
- return registerPaths(body.unshiftContainer("body", nodes));
334
+ return body.unshiftContainer("body", nodes);
346
335
  }
347
336
 
348
337
  if (listParent.isBlock()) {
349
- return registerPaths(listParent.unshiftContainer("body", nodes));
338
+ return listParent.unshiftContainer("body", nodes);
350
339
  }
351
340
 
352
341
  if (listParent.isSwitchCase()) {
353
- return registerPaths(listParent.unshiftContainer("consequent", nodes));
342
+ return listParent.unshiftContainer("consequent", nodes);
354
343
  }
355
344
 
356
345
  ok(false);
@@ -564,7 +553,7 @@ export function isModifiedIdentifier(identifierPath: NodePath<t.Identifier>) {
564
553
 
565
554
  export function replaceDefiningIdentifierToMemberExpression(
566
555
  path: NodePath<t.Identifier>,
567
- memberExpression: t.MemberExpression
556
+ memberExpression: t.MemberExpression | t.Identifier
568
557
  ) {
569
558
  // function id(){} -> var id = function() {}
570
559
  if (path.key === "id" && path.parentPath.isFunctionDeclaration()) {