Browse Source

Fixed runtime error when `IfStatement` contains only single `let` or `const` variable declaration when `simlify` option enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/661

sanex3339 4 years ago
parent
commit
728210039c
15 changed files with 96 additions and 21 deletions
  1. 1 0
      CHANGELOG.md
  2. 0 0
      dist/index.browser.js
  3. 0 0
      dist/index.cli.js
  4. 0 0
      dist/index.js
  5. 17 3
      src/node-transformers/simplifying-transformers/IfStatementSimplifyTransformer.ts
  6. 62 8
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/IfStatementSimplifyTransformer.spec.ts
  7. 3 0
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/const-variable-declaration-as-prohibited-single-statement.js
  8. 3 0
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/let-variable-declaration-as-prohibited-single-statement.js
  9. 1 1
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-alternate-return-single-statement.js
  10. 1 1
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-consequent-return-single-statement.js
  11. 1 1
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-no-return-mixed-statements-1.js
  12. 1 1
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-no-return-mixed-statements-2.js
  13. 2 2
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-no-return-single-statement.js
  14. 1 1
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-only-no-return-single-statement.js
  15. 3 3
      test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/variable-declarations-merge-transformer-integration-1.js

+ 1 - 0
CHANGELOG.md

@@ -2,6 +2,7 @@ Change Log
 
 v1.5.1
 ---
+* Fixed runtime error when `IfStatement` contains only single `let` or `const` variable declaration when `simlify` option enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/661
 * Fixed wrong `source-map: 'inline'` encoding after `1.3.0`
 
 v1.5.0

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


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


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


+ 17 - 3
src/node-transformers/simplifying-transformers/IfStatementSimplifyTransformer.ts

@@ -422,8 +422,9 @@ export class IfStatementSimplifyTransformer extends AbstractNodeTransformer {
      * @returns {boolean}
      */
     private isProhibitedSingleStatementForIfStatementBranch (statement: ESTree.Statement): boolean {
-        // TODO: write tests
-        // function declaration is not allowed outside of block in `strict` mode
+        /**
+         * Function declaration is not allowed outside of block in `strict` mode
+         */
         return NodeGuards.isFunctionDeclarationNode(statement)
             /**
              * Without ignore it can break following code:
@@ -443,6 +444,19 @@ export class IfStatementSimplifyTransformer extends AbstractNodeTransformer {
              *     else
              *         var baz = bark();
              */
-            || NodeGuards.isIfStatementNode(statement);
+            || NodeGuards.isIfStatementNode(statement)
+
+            /**
+             * `let` and `const` variable declarations are not allowed outside of `IfStatement` block statement
+             * Input:
+             * if (condition1) {
+             *     const foo = 1;
+             * }
+             *
+             * Invalid output with runtime error:
+             * if (condition1)
+             *     const foo = 1;
+             */
+            || (NodeGuards.isVariableDeclarationNode(statement) && statement.kind !== 'var');
     }
 }

+ 62 - 8
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/IfStatementSimplifyTransformer.spec.ts

@@ -353,7 +353,7 @@ describe('IfStatementSimplifyTransformer', () => {
                 describe('Variant #1: single statement', () => {
                     const regExp: RegExp = new RegExp(
                         'if *\\(!!\\[]\\) *' +
-                            'const _0x([a-f0-9]){4,6} *= *baz\\(\\);'
+                            'var _0x([a-f0-9]){4,6} *= *baz\\(\\);'
                     );
 
 
@@ -441,9 +441,9 @@ describe('IfStatementSimplifyTransformer', () => {
                 describe('Variant #1: single statement', () => {
                     const regExp: RegExp = new RegExp(
                         'if *\\(!!\\[]\\) *' +
-                            'const *_0x([a-f0-9]){4,6} *= *baz\\(\\); *' +
+                            'var *_0x([a-f0-9]){4,6} *= *baz\\(\\); *' +
                         'else *' +
-                            'const *_0x([a-f0-9]){4,6} *= *hawk\\(\\);'
+                            'var *_0x([a-f0-9]){4,6} *= *hawk\\(\\);'
                     );
 
 
@@ -501,7 +501,7 @@ describe('IfStatementSimplifyTransformer', () => {
                 describe('Variant #3: mixed statements #1', () => {
                     const regExp: RegExp = new RegExp(
                         'if *\\(!!\\[]\\) *' +
-                            'const *_0x([a-f0-9]){4,6} *= *baz\\(\\); *' +
+                            'var *_0x([a-f0-9]){4,6} *= *baz\\(\\); *' +
                         'else *{ *' +
                             'const *_0x([a-f0-9]){4,6} *= *hawk\\(\\); *' +
                             'eagle\\(\\), *dog\\(\\);' +
@@ -535,7 +535,7 @@ describe('IfStatementSimplifyTransformer', () => {
                                 '_0x([a-f0-9]){4,6} *= *hawk\\(\\); *' +
                             'eagle\\(\\), *pork\\(\\);' +
                         '} *else *' +
-                            'const *_0x([a-f0-9]){4,6} *= *cow\\(\\);'
+                            'var *_0x([a-f0-9]){4,6} *= *cow\\(\\);'
                     );
 
 
@@ -565,7 +565,7 @@ describe('IfStatementSimplifyTransformer', () => {
                         'if *\\(!!\\[]\\) *' +
                             'return *bar\\(\\); *' +
                         'else *' +
-                            'const *_0x([a-f0-9]){4,6} *= *bark\\(\\);'
+                            'var *_0x([a-f0-9]){4,6} *= *bark\\(\\);'
                     );
 
 
@@ -625,7 +625,7 @@ describe('IfStatementSimplifyTransformer', () => {
                 describe('Variant #1: single statement', () => {
                     const regExp: RegExp = new RegExp(
                         'if *\\(!!\\[]\\) *' +
-                            'const *_0x([a-f0-9]){4,6} *= *baz\\(\\); *' +
+                            'var *_0x([a-f0-9]){4,6} *= *baz\\(\\); *' +
                         'else *' +
                             'return *bark\\(\\);'
                     );
@@ -725,7 +725,7 @@ describe('IfStatementSimplifyTransformer', () => {
             describe('Variant #1: three statements', () => {
                 const regExp: RegExp = new RegExp(
                     'if *\\(!!\\[]\\) *' +
-                        'const _0x([a-f0-9]){4,6} *= *function *\\(\\) *{}, *' +
+                        'var _0x([a-f0-9]){4,6} *= *function *\\(\\) *{}, *' +
                             '_0x([a-f0-9]){4,6} *= *function *\\(\\) *{}, *' +
                             '_0x([a-f0-9]){4,6} *= *function *\\(\\) *{};'
                 );
@@ -809,6 +809,60 @@ describe('IfStatementSimplifyTransformer', () => {
                     assert.match(obfuscatedCode, regExp);
                 });
             });
+
+            describe('Variant #3: `let` `VariableDeclaration` as prohibited single statement', () => {
+                const regExp: RegExp = new RegExp(
+                    'if *\\(!!\\[]\\) *{ *' +
+                        'let foo *= *0x1; *' +
+                    '}'
+                );
+
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/let-variable-declaration-as-prohibited-single-statement.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            simplify: true
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should not simplify if statement', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('Variant #4: `const` `VariableDeclaration` as prohibited single statement', () => {
+                const regExp: RegExp = new RegExp(
+                    'if *\\(!!\\[]\\) *{ *' +
+                        'const foo *= *0x1; *' +
+                    '}'
+                );
+
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/const-variable-declaration-as-prohibited-single-statement.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            simplify: true
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should not simplify if statement', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
         });
     });
 });

+ 3 - 0
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/const-variable-declaration-as-prohibited-single-statement.js

@@ -0,0 +1,3 @@
+if (true) {
+    const foo = 1;
+}

+ 3 - 0
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/let-variable-declaration-as-prohibited-single-statement.js

@@ -0,0 +1,3 @@
+if (true) {
+    let foo = 1;
+}

+ 1 - 1
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-alternate-return-single-statement.js

@@ -1,6 +1,6 @@
 function foo () {
     if (true) {
-        const bar = baz();
+        var bar = baz();
     } else {
         return bark();
     }

+ 1 - 1
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-consequent-return-single-statement.js

@@ -2,6 +2,6 @@ function foo () {
     if (true) {
         return bar();
     } else {
-        const baz = bark();
+        var baz = bark();
     }
 }

+ 1 - 1
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-no-return-mixed-statements-1.js

@@ -1,6 +1,6 @@
 function foo () {
     if (true) {
-        const bar = baz();
+        var bar = baz();
     } else {
         const bark = hawk();
 

+ 1 - 1
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-no-return-mixed-statements-2.js

@@ -6,6 +6,6 @@ function foo () {
         eagle()
         pork();
     } else {
-        const horse = cow();
+        var horse = cow();
     }
 }

+ 2 - 2
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-and-alternate-no-return-single-statement.js

@@ -1,7 +1,7 @@
 function foo () {
     if (true) {
-        const bar = baz();
+        var bar = baz();
     } else {
-        const bark = hawk();
+        var bark = hawk();
     }
 }

+ 1 - 1
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/partial-consequent-only-no-return-single-statement.js

@@ -1,5 +1,5 @@
 function foo () {
     if (true) {
-        const bar = baz();
+        var bar = baz();
     }
 }

+ 3 - 3
test/functional-tests/node-transformers/simplifying-transformers/if-statement-simplify-transformer/fixtures/variable-declarations-merge-transformer-integration-1.js

@@ -1,7 +1,7 @@
 function foo() {
     if (true) {
-        const bar = function () {};
-        const baz = function () {};
-        const bark = function () {};
+        var bar = function () {};
+        var baz = function () {};
+        var bark = function () {};
     }
 }

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