Explorar o código

[Bug] Wrong Lexical Scope for let and const variables

%!s(int64=5) %!d(string=hai) anos
pai
achega
c1031ced07

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.browser.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.cli.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.js


+ 4 - 1
src/node-transformers/obfuscating-transformers/VariableDeclarationTransformer.ts

@@ -21,6 +21,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { NodeGuards } from '../../node/NodeGuards';
 import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
+import { NodeBlockLexicalScopeUtils } from '../../node/NodeBlockLexicalScopeUtils';
 import { NodeMetadata } from '../../node/NodeMetadata';
 
 /**
@@ -93,7 +94,9 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
      * @returns {NodeGuards}
      */
     public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): ESTree.Node {
-        const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(variableDeclarationNode);
+        const lexicalScopeNode: TNodeWithLexicalScope | undefined = variableDeclarationNode.kind === 'var'
+            ? NodeLexicalScopeUtils.getLexicalScope(variableDeclarationNode)
+            : NodeBlockLexicalScopeUtils.getLexicalScope(variableDeclarationNode);
 
         if (!lexicalScopeNode) {
             return variableDeclarationNode;

+ 57 - 0
src/node/NodeBlockLexicalScopeUtils.ts

@@ -0,0 +1,57 @@
+import * as ESTree from 'estree';
+
+import { TNodeWithLexicalScope } from '../types/node/TNodeWithLexicalScope';
+
+import { NodeGuards } from './NodeGuards';
+
+export class NodeBlockLexicalScopeUtils {
+    /**
+     * @param {Node} node
+     * @returns {TNodeWithLexicalScope}
+     */
+    public static getLexicalScope (node: ESTree.Node): TNodeWithLexicalScope | undefined {
+        return NodeBlockLexicalScopeUtils.getLexicalScopesRecursive(node, 1)[0];
+    }
+
+    /**
+     * @param {Node} node
+     * @returns {TNodeWithLexicalScope[]}
+     */
+    public static getLexicalScopes (node: ESTree.Node): TNodeWithLexicalScope[] {
+        return NodeBlockLexicalScopeUtils.getLexicalScopesRecursive(node);
+    }
+
+    /***
+     * @param {Node} node
+     * @param {number} maxSize
+     * @param {TNodeWithLexicalScope[]} nodesWithLexicalScope
+     * @param {number} depth
+     * @returns {TNodeWithLexicalScope[]}
+     */
+    private static getLexicalScopesRecursive (
+        node: ESTree.Node,
+        maxSize: number = Infinity,
+        nodesWithLexicalScope: TNodeWithLexicalScope[] = [],
+        depth: number = 0
+    ): TNodeWithLexicalScope[] {
+        if (nodesWithLexicalScope.length >= maxSize) {
+            return nodesWithLexicalScope;
+        }
+
+        const parentNode: ESTree.Node | undefined = node.parentNode;
+
+        if (!parentNode) {
+            throw new ReferenceError('`parentNode` property of given node is `undefined`');
+        }
+
+        if (NodeGuards.isNodeWithBlockLexicalScope(node)) {
+            nodesWithLexicalScope.push(node);
+        }
+
+        if (node !== parentNode) {
+            return NodeBlockLexicalScopeUtils.getLexicalScopesRecursive(parentNode, maxSize, nodesWithLexicalScope, ++depth);
+        }
+
+        return nodesWithLexicalScope;
+    }
+}

+ 8 - 0
src/node/NodeGuards.ts

@@ -223,6 +223,14 @@ export class NodeGuards {
         return NodeGuards.isProgramNode(node) || NodeGuards.isFunctionNode(node);
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isNodeWithBlockLexicalScope (node: ESTree.Node): node is TNodeWithLexicalScope {
+        return NodeGuards.isNodeWithLexicalScope(node) || NodeGuards.isBlockStatementNode(node);
+    }
+
     /**
      * @param {Node} node
      * @param {Node} parentNode

+ 9 - 0
test/functional-tests/issues/fixtures/issue424.js

@@ -0,0 +1,9 @@
+!function () {
+    {
+        let name;
+    }
+    {
+        let {name} = {name: "foo"};
+        console.log(name);
+    }
+}();

+ 31 - 0
test/functional-tests/issues/issue424.spec.ts

@@ -0,0 +1,31 @@
+import { assert } from 'chai';
+import { NO_ADDITIONAL_NODES_PRESET } from '../../../src/options/presets/NoCustomNodes';
+import { readFileAsString } from '../../helpers/readFileAsString';
+import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';
+
+//
+// https://github.com/javascript-obfuscator/javascript-obfuscator/issues/424
+//
+describe('Issue #424', () => {
+
+    describe('Fixture code should nor break', () => {
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/issue424.js');
+
+            obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    stringArray: false
+                }
+            ).getObfuscatedCode();
+
+        });
+
+        it('does not break on run', () => {
+            assert.doesNotThrow(() => eval(obfuscatedCode));
+        });
+    });
+});

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio