Browse Source

Fixed processing of `null` value in NodeUtils.clone() method

sanex3339 7 years ago
parent
commit
9c1a3822c0

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 ===
+v0.10.2
+---
+* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/78
+
 v0.10.1
 ---
 * Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/76

File diff suppressed because it is too large
+ 0 - 0
dist/index.js


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.10.1",
+  "version": "0.10.2",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",

+ 5 - 1
src/cli/utils/CLIUtils.ts

@@ -83,7 +83,11 @@ export class CLIUtils {
         try {
             config = require(configPath);
         } catch (e) {
-            config = __non_webpack_require__(configPath);
+            try {
+                config = __non_webpack_require__(configPath);
+            } catch (e) {
+                throw new ReferenceError('Given config path must be a valid file path');
+            }
         }
 
         return config;

+ 4 - 0
src/node/NodeUtils.ts

@@ -46,6 +46,10 @@ export class NodeUtils {
      */
     public static clone <T extends ESTree.Node> (astTree: T): T {
         const cloneRecursive: (node: T) => T = (node: T) => {
+            if (node === null) {
+                return node;
+            }
+
             const copy: {[key: string]: any} = {};
 
             Object

+ 48 - 18
test/unit-tests/cli/utils/CLIUtils.spec.ts

@@ -49,23 +49,41 @@ describe('CLIUtils', () => {
     });
 
     describe('getUserConfig (configPath: string): Object', () => {
-        const configDirName: string = 'test/fixtures';
-        const configFileName: string = 'config.js';
-        const configFilePath: string = `../../../${configDirName}/${configFileName}`;
-        const expectedResult: TInputOptions = {
-            compact: true,
-            selfDefending: false,
-            sourceMap: true
-        };
-
-        let result: Object;
-
-        before(() => {
-            result = CLIUtils.getUserConfig(configFilePath);
+        describe('variant #1: valid config file path', () => {
+            const configDirName: string = 'test/fixtures';
+            const configFileName: string = 'config.js';
+            const configFilePath: string = `../../../${configDirName}/${configFileName}`;
+            const expectedResult: TInputOptions = {
+                compact: true,
+                selfDefending: false,
+                sourceMap: true
+            };
+
+            let result: Object;
+
+            before(() => {
+                result = CLIUtils.getUserConfig(configFilePath);
+            });
+
+            it('should return object with user configuration', () => {
+                assert.deepEqual(result, expectedResult);
+            });
         });
 
-        it('should return object with user configuration', () => {
-            assert.deepEqual(result, expectedResult);
+        describe('variant #2: invalid config file path', () => {
+            const configDirName: string = 'test/fixtures';
+            const configFileName: string = 'configs.js';
+            const configFilePath: string = `../../../${configDirName}/${configFileName}`;
+
+            let testFunc: () => void;
+
+            before(() => {
+                testFunc = () => CLIUtils.getUserConfig(configFilePath);
+            });
+
+            it('should throw an error if `configFilePath` is not a valid path', () => {
+                assert.throws(testFunc, ReferenceError);
+            });
         });
     });
 
@@ -74,12 +92,15 @@ describe('CLIUtils', () => {
             const tmpFileName: string = 'test.js';
             const inputPath: string = `${tmpDir}/${tmpFileName}`;
 
+            let testFunc: () => void;
+
             before(() => {
                 fs.writeFileSync(inputPath, fileContent);
+                testFunc = () => CLIUtils.validateInputPath(inputPath);
             });
 
             it('shouldn\'t throw an error if `inputPath` is a valid path', () => {
-                assert.doesNotThrow(() => CLIUtils.validateInputPath(inputPath), ReferenceError);
+                assert.doesNotThrow(testFunc, ReferenceError);
             });
 
             after(() => {
@@ -91,8 +112,14 @@ describe('CLIUtils', () => {
             const tmpFileName: string = 'test.js';
             const inputPath: string = `${tmpDir}/${tmpFileName}`;
 
+            let testFunc: () => void;
+
+            before(() => {
+                testFunc = () => CLIUtils.validateInputPath(inputPath);
+            });
+
             it('should throw an error if `inputPath` is not a valid path', () => {
-                assert.throws(() => CLIUtils.validateInputPath(inputPath), ReferenceError);
+                assert.throws(testFunc, ReferenceError);
             });
         });
 
@@ -100,12 +127,15 @@ describe('CLIUtils', () => {
             const tmpFileName: string = 'test.ts';
             const inputPath: string = `${tmpDir}/${tmpFileName}`;
 
+            let testFunc: () => void;
+
             before(() => {
                 fs.writeFileSync(inputPath, fileContent);
+                testFunc = () => CLIUtils.validateInputPath(inputPath);
             });
 
             it('should throw an error if `inputPath` is a file name has invalid extension', () => {
-                assert.throws(() => CLIUtils.validateInputPath(inputPath), ReferenceError);
+                assert.throws(testFunc, ReferenceError);
             });
 
             after(() => {

+ 84 - 38
test/unit-tests/node/node-utils/NodeUtils.spec.ts

@@ -27,52 +27,98 @@ describe('NodeUtils', () => {
     });
 
     describe('clone <T extends ESTree.Node> (astTree: T): T', () => {
-        let programNode: ESTree.Program,
-            expectedProgramNode: ESTree.Program;
+        describe('variant #1: simple AST-tree', () => {
+            let programNode: ESTree.Program,
+                expectedProgramNode: ESTree.Program;
+
+            before(() => {
+                // actual AST tree
+                const expressionStatementNode1: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
+                const expressionStatementNode2: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
+
+                const ifStatementBlockStatementNode1: ESTree.BlockStatement = Nodes.getBlockStatementNode([
+                    expressionStatementNode1,
+                    expressionStatementNode2
+                ]);
 
-        before(() => {
-            // actual AST tree
-            const expressionStatementNode1: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
-            const expressionStatementNode2: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
+                const ifStatementNode1: ESTree.IfStatement = Nodes.getIfStatementNode(
+                    Nodes.getLiteralNode(true),
+                    ifStatementBlockStatementNode1
+                );
 
-            const ifStatementBlockStatementNode1: ESTree.BlockStatement = Nodes.getBlockStatementNode([
-                expressionStatementNode1,
-                expressionStatementNode2
-            ]);
-
-            const ifStatementNode1: ESTree.IfStatement = Nodes.getIfStatementNode(
-                Nodes.getLiteralNode(true),
-                ifStatementBlockStatementNode1
-            );
+                // expected AST tree
+                const expressionStatementNode3: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
+                const expressionStatementNode4: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
 
-            // expected AST tree
-            const expressionStatementNode3: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
-            const expressionStatementNode4: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(Nodes.getIdentifierNode('identifier'));
+                const ifStatementBlockStatementNode2: ESTree.BlockStatement = Nodes.getBlockStatementNode([
+                    expressionStatementNode3,
+                    expressionStatementNode4
+                ]);
 
-            const ifStatementBlockStatementNode2: ESTree.BlockStatement = Nodes.getBlockStatementNode([
-                expressionStatementNode3,
-                expressionStatementNode4
-            ]);
+                const ifStatementNode2: ESTree.IfStatement = Nodes.getIfStatementNode(
+                    Nodes.getLiteralNode(true),
+                    ifStatementBlockStatementNode2
+                );
 
-            const ifStatementNode2: ESTree.IfStatement = Nodes.getIfStatementNode(
-                Nodes.getLiteralNode(true),
-                ifStatementBlockStatementNode2
-            );
+                programNode = NodeUtils.clone(
+                    Nodes.getProgramNode([
+                        ifStatementNode1
+                    ])
+                );
+                expectedProgramNode = NodeUtils.parentize(
+                    Nodes.getProgramNode([
+                        ifStatementNode2
+                    ])
+                );
+            });
 
-            programNode = NodeUtils.clone(
-                Nodes.getProgramNode([
-                    ifStatementNode1
-                ])
-            );
-            expectedProgramNode = NodeUtils.parentize(
-                Nodes.getProgramNode([
-                    ifStatementNode2
-                ])
-            );
+            it('should clone given AST-tree', () => {
+                assert.deepEqual(programNode, expectedProgramNode);
+            });
         });
 
-        it('should clone given AST-tree', () => {
-            assert.deepEqual(programNode, expectedProgramNode);
+        describe('variant #2: array expression with `null` element', () => {
+            let programNode: ESTree.Program,
+                expectedProgramNode: ESTree.Program;
+
+            before(() => {
+                // actual AST tree
+                const arrayExpressionNode: ESTree.ArrayExpression = Nodes.getArrayExpressionNode([
+                    Nodes.getLiteralNode(1),
+                    Nodes.getLiteralNode(2),
+                    <any>null,
+                    Nodes.getLiteralNode(4)
+                ]);
+                const expressionStatementNode: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(
+                    arrayExpressionNode
+                );
+
+                // expected AST tree
+                const expectedArrayExpressionNode: ESTree.ArrayExpression = Nodes.getArrayExpressionNode([
+                    Nodes.getLiteralNode(1),
+                    Nodes.getLiteralNode(2),
+                    <any>null,
+                    Nodes.getLiteralNode(4)
+                ]);
+                const expectedExpressionStatementNode: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(
+                    expectedArrayExpressionNode
+                );
+
+                programNode = NodeUtils.clone(
+                    Nodes.getProgramNode([
+                        expressionStatementNode
+                    ])
+                );
+                expectedProgramNode = NodeUtils.parentize(
+                    Nodes.getProgramNode([
+                        expectedExpressionStatementNode
+                    ])
+                );
+            });
+
+            it('should clone given AST-tree', () => {
+                assert.deepEqual(programNode, expectedProgramNode);
+            });
         });
     });
 

Some files were not shown because too many files changed in this diff