Jelajahi Sumber

Updated supported node versions. Added support for rename of property definitions

sanex 3 tahun lalu
induk
melakukan
744cd14f7f

+ 0 - 4
.github/workflows/ci.yml

@@ -20,14 +20,10 @@ jobs:
             node-version: 12.x
           - os: ubuntu-latest,
             node-version: 14.x
-          - os: ubuntu-latest,
-            node-version: 15.x
           - os: ubuntu-latest,
             node-version: 16.x
           - os: windows-latest,
             node-version: 14.x
-          - os: windows-latest,
-            node-version: 15.x
           - os: windows-latest,
             node-version: 16.x
 

+ 2 - 0
CHANGELOG.md

@@ -3,6 +3,8 @@ Change Log
 v2.18.0
 ---
 * Added support of `es2022` features: private identifiers and class properties
+* Dropped support for `node@15`. 
+* Increased minimum supported `node` versions: `^12.22.0 || ^14.17.0 || >=16.0.0`
 
 v2.17.0
 ---

File diff ditekan karena terlalu besar
+ 0 - 0
dist/index.browser.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/index.cli.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/index.js


+ 1 - 1
package.json

@@ -12,7 +12,7 @@
     "js obfuscator"
   ],
   "engines": {
-    "node": ">=12"
+    "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
   },
   "main": "dist/index.js",
   "browser": "dist/index.browser.js",

+ 1 - 0
src/enums/node/NodeType.ts

@@ -11,6 +11,7 @@ export enum NodeType {
     CallExpression = 'CallExpression',
     CatchClause = 'CatchClause',
     ChainExpression = 'ChainExpression',
+    ClassBody = 'ClassBody',
     ClassDeclaration = 'ClassDeclaration',
     ConditionalExpression = 'ConditionalExpression',
     ContinueStatement = 'ContinueStatement',

+ 24 - 1
src/node-transformers/rename-properties-transformers/RenamePropertiesTransformer.ts

@@ -43,7 +43,10 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
      * @returns {boolean}
      */
     private static isValidPropertyNode<
-        TNode extends ESTree.Property | ESTree.MemberExpression | ESTree.MethodDefinition
+        TNode extends ESTree.Property
+            | ESTree.PropertyDefinition
+            | ESTree.MemberExpression
+            | ESTree.MethodDefinition
     > (
         propertyNode: TNode,
         propertyKeyNode: ESTree.Expression | ESTree.PrivateIdentifier
@@ -107,6 +110,10 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
             return this.transformPropertyNode(node);
         }
 
+        if (NodeGuards.isPropertyDefinitionNode(node)) {
+            return this.transformPropertyDefinitionNode(node);
+        }
+
         if (NodeGuards.isMemberExpressionNode(node)) {
             return this.transformMemberExpressionNode(node);
         }
@@ -133,6 +140,20 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
         return propertyNode;
     }
 
+    /**
+     * @param {PropertyDefinition} propertyNode
+     * @returns {PropertyDefinition}
+     */
+    private transformPropertyDefinitionNode (propertyNode: ESTree.PropertyDefinition): ESTree.PropertyDefinition {
+        const propertyKeyNode: ESTree.Expression | ESTree.PrivateIdentifier = propertyNode.key;
+
+        if (RenamePropertiesTransformer.isValidPropertyNode(propertyNode, propertyKeyNode)) {
+            propertyNode.key = this.renamePropertiesReplacer.replace(propertyKeyNode);
+        }
+
+        return propertyNode;
+    }
+
     /**
      * @param {Property} memberExpressionNode
      * @returns {Property}
@@ -165,6 +186,7 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
      * @param {Node} node
      * @param {Node} parentNode
      */
+    // eslint-disable-next-line complexity
     private analyzeAutoExcludedPropertyNames (
         node: ESTree.Node,
         parentNode: ESTree.Node
@@ -177,6 +199,7 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
             (NodeGuards.isPropertyNode(parentNode) && parentNode.key === node)
             || NodeGuards.isMemberExpressionNode(parentNode) && parentNode.property === node
             || NodeGuards.isMethodDefinitionNode(parentNode) && parentNode.key === node
+            || NodeGuards.isPropertyDefinitionNode(parentNode) && parentNode.key === node
         ) {
             return;
         }

+ 10 - 0
src/node/NodeGuards.ts

@@ -91,6 +91,16 @@ export class NodeGuards {
         return node.type === NodeType.CallExpression;
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isClassBodyNode (
+        node: ESTree.Node
+    ): node is ESTree.ClassBody {
+        return node.type === NodeType.ClassBody;
+    }
+
     /**
      * @param {Node} node
      * @returns {boolean}

+ 8 - 6
test/dev/dev.ts

@@ -12,27 +12,29 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
                     let test = {}
                 }
                 
-                methodA = () => {
-                    console.log('methodA');
+                static methodA = () => {
+                    console.log('method_A');
                 }
                 
                 methodB () {
-                    console.log('methodB');
+                    console.log('method_B');
                     
-                    this.methodA();
+                    Test.methodA();
                 }
             }
             
             const instance = new Test();
             
-            instance.methodA();
+            Test.methodA();
             instance.methodB();
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
             stringArray: true,
-            stringArrayThreshold: 1
+            stringArrayThreshold: 1,
+            transformObjectKeys: true,
+            renameProperties: true
         }
     ).getObfuscatedCode();
 

+ 94 - 12
test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/RenamePropertiesTransformer.spec.ts

@@ -13,7 +13,7 @@ describe('RenamePropertiesTransformer', () => {
     describe('transformNode', () => {
         describe('Mode: `unsafe`', () => {
             describe('Variant #1: Hexadecimal identifier names generator', () => {
-                describe('Variant #1: base properties rename', () => {
+                describe('Variant #1: object properties rename', () => {
                     const property1RegExp: RegExp = /'(_0x[a-f0-9]{4,6})': *0x1/;
                     const property2RegExp: RegExp = /'(_0x[a-f0-9]{4,6})': *0x2/;
                     const property3RegExp: RegExp = /\['(_0x[a-f0-9]{4,6})']: *0x3/;
@@ -52,10 +52,49 @@ describe('RenamePropertiesTransformer', () => {
                         assert.match(obfuscatedCode, property4RegExp);
                     });
                 });
+
+                describe('Variant #2: class property definitions rename', () => {
+                    const propertyDefinition1RegExp: RegExp = /\['(_0x[a-f0-9]{4,6})'] *= *0x1;/;
+                    const propertyDefinition2RegExp: RegExp = /static \['(_0x[a-f0-9]{4,6})'] *= *0x2/;
+                    const propertyDefinition3RegExp: RegExp = /\['(_0x[a-f0-9]{4,6})'] *= *0x3/;
+                    const propertyDefinition4RegExp: RegExp = /\[hawk] *= *0x4/;
+
+                    let obfuscatedCode: string;
+
+                    before(() => {
+                        const code: string = readFileAsString(__dirname + '/fixtures/property-definition-1.js');
+
+                        obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                            code,
+                            {
+                                ...NO_ADDITIONAL_NODES_PRESET,
+                                renameProperties: true,
+                                renamePropertiesMode: RenamePropertiesMode.Unsafe,
+                                identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
+                            }
+                        ).getObfuscatedCode();
+                    });
+
+                    it('Match #1: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition1RegExp);
+                    });
+
+                    it('Match #2: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition2RegExp);
+                    });
+
+                    it('Match #3: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition3RegExp);
+                    });
+
+                    it('Match #4: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition4RegExp);
+                    });
+                });
             });
 
             describe('Variant #2: Mangled identifier names generator', () => {
-                describe('Variant #1: base properties mangle', () => {
+                describe('Variant #1: object properties mangle', () => {
                     const property1RegExp: RegExp = /'a': *0x1/;
                     const property2RegExp: RegExp = /'b': *0x2/;
                     const property3RegExp: RegExp = /\['c']: *0x3/;
@@ -95,7 +134,46 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #2: base properties rename with rename globals', () => {
+                describe('Variant #2: class property definitions rename', () => {
+                    const propertyDefinition1RegExp: RegExp = /\['a'] *= *0x1;/;
+                    const propertyDefinition2RegExp: RegExp = /static \['b'] *= *0x2/;
+                    const propertyDefinition3RegExp: RegExp = /\['c'] *= *0x3/;
+                    const propertyDefinition4RegExp: RegExp = /\[hawk] *= *0x4/;
+
+                    let obfuscatedCode: string;
+
+                    before(() => {
+                        const code: string = readFileAsString(__dirname + '/fixtures/property-definition-1.js');
+
+                        obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                            code,
+                            {
+                                ...NO_ADDITIONAL_NODES_PRESET,
+                                renameProperties: true,
+                                renamePropertiesMode: RenamePropertiesMode.Unsafe,
+                                identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
+                            }
+                        ).getObfuscatedCode();
+                    });
+
+                    it('Match #1: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition1RegExp);
+                    });
+
+                    it('Match #2: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition2RegExp);
+                    });
+
+                    it('Match #3: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition3RegExp);
+                    });
+
+                    it('Match #4: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition4RegExp);
+                    });
+                });
+
+                describe('Variant #3: base properties rename with rename globals', () => {
                     const variable1RegExp: RegExp = /const d *= *'hawk'/;
                     const variable2RegExp: RegExp = /const e *= *{/;
                     const property1RegExp: RegExp = /'a': *0x1/;
@@ -146,7 +224,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #3: properties rename of nested objects', () => {
+                describe('Variant #4: properties rename of nested objects', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *{' +
@@ -177,7 +255,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #4: properties rename of rest element', () => {
+                describe('Variant #5: properties rename of rest element', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *0x1' +
@@ -207,7 +285,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #5: reserved dom properties', () => {
+                describe('Variant #6: reserved dom properties', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *0x1,' +
@@ -239,7 +317,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #6: reserved names properties', () => {
+                describe('Variant #7: reserved names properties', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *0x1,' +
@@ -272,7 +350,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #7: class methods', () => {
+                describe('Variant #8: class methods', () => {
                     const regExp: RegExp = new RegExp('' +
                         'class Foo *{' +
                             '\\[\'a\'] *\\(\\) *{}' +
@@ -303,7 +381,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #8: integration with `splitStrings` option', () => {
+                describe('Variant #9: integration with `splitStrings` option', () => {
                     const propertyRegExp: RegExp = new RegExp(
                         'const foo *= *{' +
                             '\'a\': *\'long\' *\\+ *\'Prop\' *\\+ *\'erty\' *\\+ *\'Valu\' *\\+ *\'e\'' +
@@ -394,8 +472,10 @@ describe('RenamePropertiesTransformer', () => {
                         '\'a\': *0x2 *' +
                     '}; *' +
                     'class Class *{ *' +
-                        'static\\[\'baz\'] *\\(\\) *{} *' +
-                        'static\\[\'b\'] *\\(\\) *{} *' +
+                        '\\[\'baz\'] *= *0x1; *' +
+                        'static *\\[\'b\'] *= *0x2;*' +
+                        'static *\\[\'hawk\'] *\\(\\) *{} *' +
+                        'static *\\[\'c\'] *\\(\\) *{} *' +
                     '}' +
                 '');
                 const referencesRegExp: RegExp = new RegExp('' +
@@ -403,7 +483,9 @@ describe('RenamePropertiesTransformer', () => {
                         'object\\[\'foo\'], *' +
                         'object\\[\'a\'], *' +
                         'Class\\[\'baz\'], *' +
-                        'Class\\[\'b\'] *' +
+                        'Class\\[\'b\'], *' +
+                        'Class\\[\'hawk\'], *' +
+                        'Class\\[\'c\'] *' +
                     '\\);' +
                 '');
 

+ 7 - 0
test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/fixtures/property-definition-1.js

@@ -0,0 +1,7 @@
+const hawk = 'hawk';
+class Foo {
+    bar = 1;
+    static 'baz' = 2;
+    ['bark'] = 3;
+    [hawk] = 4;
+}

+ 6 - 3
test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/fixtures/safe-mode.js

@@ -3,11 +3,14 @@ const object = {
     bar: 2
 };
 class Class {
-    static baz () {}
-    static bark () {}
+    baz = 1;
+    static bark = 2;
+    static hawk () {}
+    static eagle () {}
 }
 
 var excluded1 = 'foo';
 var excluded2 = 'baz';
+var excluded3 = 'hawk';
 
-console.log(object.foo, object['bar'], Class.baz, Class['bark']);
+console.log(object.foo, object['bar'], Class.baz, Class['bark'], Class.hawk, Class['eagle']);

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini