Ver código fonte

Fixed invalid behaviour of `numbersToExpressions` option for float numbers
Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/882

sanex 4 anos atrás
pai
commit
61d98966b1

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 
+v2.10.4
+---
+* Fixed invalid behaviour of `numbersToExpressions` option for float numbers. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/882
+
 v2.10.3
 ---
 * Fixed `simplify` option regression after `2.10.2`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/864

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/index.browser.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/index.cli.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/index.js


+ 9 - 9
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "2.10.3",
+  "version": "2.10.4",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -28,7 +28,7 @@
     "chalk": "4.1.0",
     "chance": "1.1.7",
     "class-validator": "0.13.1",
-    "commander": "7.0.0",
+    "commander": "7.1.0",
     "eslint-scope": "5.1.1",
     "estraverse": "5.2.0",
     "fast-deep-equal": "3.1.3",
@@ -55,24 +55,24 @@
     "@types/js-string-escape": "1.0.0",
     "@types/md5": "2.3.0",
     "@types/mkdirp": "1.0.1",
-    "@types/mocha": "8.2.0",
+    "@types/mocha": "8.2.1",
     "@types/multimatch": "4.0.0",
-    "@types/node": "14.14.27",
+    "@types/node": "14.14.31",
     "@types/rimraf": "3.0.0",
     "@types/sinon": "9.0.10",
     "@types/string-template": "1.0.2",
     "@types/webpack-env": "1.16.0",
-    "@typescript-eslint/eslint-plugin": "4.15.0",
-    "@typescript-eslint/parser": "4.15.0",
+    "@typescript-eslint/eslint-plugin": "4.15.1",
+    "@typescript-eslint/parser": "4.15.1",
     "chai": "4.3.0",
     "chai-exclude": "2.0.2",
     "cross-env": "7.0.3",
     "eslint": "7.20.0",
     "eslint-plugin-import": "2.22.1",
-    "eslint-plugin-jsdoc": "31.6.1",
+    "eslint-plugin-jsdoc": "32.1.0",
     "eslint-plugin-no-null": "1.0.2",
     "eslint-plugin-prefer-arrow": "1.2.3",
-    "eslint-plugin-unicorn": "28.0.0",
+    "eslint-plugin-unicorn": "28.0.2",
     "fork-ts-checker-notifier-webpack-plugin": "3.0.0",
     "fork-ts-checker-webpack-plugin": "6.1.0",
     "mocha": "8.3.0",
@@ -85,7 +85,7 @@
     "ts-loader": "8.0.17",
     "ts-node": "9.1.1",
     "typescript": "4.1.5",
-    "webpack": "5.21.2",
+    "webpack": "5.23.0",
     "webpack-cli": "4.5.0",
     "webpack-node-externals": "2.5.2"
   },

+ 7 - 2
src/analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer.ts

@@ -19,6 +19,11 @@ export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpres
      */
     public static readonly defaultAdditionalPartsCount: number = 3;
 
+    /**
+     * @type {number}
+     */
+    private static readonly delta: number = 10000;
+
     /**
      * @type {Map<number, number[]>}
      */
@@ -70,8 +75,8 @@ export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpres
 
         const upperNumberLimit: number = Math.min(Math.abs(number * 2), Number.MAX_SAFE_INTEGER);
 
-        const from: number = Math.min(-10000, -upperNumberLimit);
-        const to: number = Math.max(10000, upperNumberLimit);
+        const from: number = Math.min(-NumberNumericalExpressionAnalyzer.delta, -upperNumberLimit);
+        const to: number = Math.max(NumberNumericalExpressionAnalyzer.delta, upperNumberLimit);
 
         let temporarySum = 0;
 

+ 37 - 18
src/node-transformers/converting-transformers/NumberToNumericalExpressionTransformer.ts

@@ -16,6 +16,7 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { NodeGuards } from '../../node/NodeGuards';
 import { NodeFactory } from '../../node/NodeFactory';
 import { NumberNumericalExpressionAnalyzer } from '../../analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer';
+import { NumberUtils } from '../../utils/NumberUtils';
 import { NumericalExpressionDataToNodeConverter } from '../../node/NumericalExpressionDataToNodeConverter';
 
 /**
@@ -86,23 +87,41 @@ export class NumberToNumericalExpressionTransformer extends AbstractNodeTransfor
             return literalNode;
         }
 
-        const numberNumericalExpressionData: TNumberNumericalExpressionData = this.numberNumericalExpressionAnalyzer.analyze(
-            literalNode.value,
-            NumberNumericalExpressionAnalyzer.defaultAdditionalPartsCount
-        );
-
-        return NumericalExpressionDataToNodeConverter.convert(
-            numberNumericalExpressionData,
-            (number: number, isPositiveNumber: boolean) => {
-                const numberLiteralNode: ESTree.Literal = NodeFactory.literalNode(number);
-
-                return isPositiveNumber
-                    ? numberLiteralNode
-                    : NodeFactory.unaryExpressionNode(
-                        '-',
-                        numberLiteralNode
-                    );
-            }
-        );
+        const baseNumber: number = literalNode.value;
+        const [integerPart, decimalPart] = NumberUtils.extractIntegerAndDecimalParts(baseNumber);
+        const integerNumberNumericalExpressionData: TNumberNumericalExpressionData = this.numberNumericalExpressionAnalyzer
+            .analyze(
+                integerPart,
+                NumberNumericalExpressionAnalyzer.defaultAdditionalPartsCount
+            );
+
+        if (decimalPart) {
+            return NumericalExpressionDataToNodeConverter.convertFloatNumberData(
+                integerNumberNumericalExpressionData,
+                decimalPart,
+                this.getNumberNumericalExpressionLiteralNode
+            );
+        } else {
+            return NumericalExpressionDataToNodeConverter.convertIntegerNumberData(
+                integerNumberNumericalExpressionData,
+                this.getNumberNumericalExpressionLiteralNode
+            );
+        }
+    }
+
+    /**
+     * @param {number} number
+     * @param {boolean} isPositiveNumber
+     * @returns {Expression}
+     */
+    private getNumberNumericalExpressionLiteralNode (number: number, isPositiveNumber: boolean): ESTree.Expression {
+        const numberLiteralNode: ESTree.Literal = NodeFactory.literalNode(number);
+
+        return isPositiveNumber
+            ? numberLiteralNode
+            : NodeFactory.unaryExpressionNode(
+                '-',
+                numberLiteralNode
+            );
     }
 }

+ 1 - 1
src/node-transformers/string-array-transformers/StringArrayRotateFunctionTransformer.ts

@@ -225,7 +225,7 @@ export class StringArrayRotateFunctionTransformer extends AbstractNodeTransforme
                 StringArrayRotateFunctionTransformer.comparisonExpressionAdditionalPartsCount
             );
 
-        const comparisonExpressionNode: ESTree.Expression = NumericalExpressionDataToNodeConverter.convert(
+        const comparisonExpressionNode: ESTree.Expression = NumericalExpressionDataToNodeConverter.convertIntegerNumberData(
             comparisonExpressionNumberNumericalExpressionData,
             ((number: number, isPositiveNumber) => {
                 const literalNode: ESTree.Literal = NodeFactory.literalNode(

+ 25 - 1
src/node/NumericalExpressionDataToNodeConverter.ts

@@ -15,7 +15,7 @@ export class NumericalExpressionDataToNodeConverter {
      * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter
      * @returns {Expression}
      */
-    public static convert (
+    public static convertIntegerNumberData (
         numberNumericalExpressionData: TNumberNumericalExpressionData,
         literalNodeGetter: TNumericalExpressionDataToNodeConverterLiteralNodeGetter
     ): ESTree.Expression {
@@ -25,6 +25,30 @@ export class NumericalExpressionDataToNodeConverter {
        );
     }
 
+    /**
+     * @param {TNumberNumericalExpressionData} integerNumberNumericalExpressionData
+     * @param {number} decimalPart
+     * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter
+     * @returns {Expression}
+     */
+    public static convertFloatNumberData (
+        integerNumberNumericalExpressionData: TNumberNumericalExpressionData,
+        decimalPart: number,
+        literalNodeGetter: TNumericalExpressionDataToNodeConverterLiteralNodeGetter
+    ): ESTree.Expression {
+        const integerNumberNumericalExpressionNode: ESTree.Expression = NumericalExpressionDataToNodeConverter
+            .convertNumericalExpressionDataToNode(
+                integerNumberNumericalExpressionData,
+                literalNodeGetter
+            );
+
+        return NodeFactory.binaryExpressionNode(
+            '+',
+            integerNumberNumericalExpressionNode,
+            NodeFactory.literalNode(decimalPart)
+        );
+    }
+
     /**
      * @param {TNumberNumericalExpressionData} numberNumericalExpressionData
      * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter

+ 25 - 0
src/utils/NumberUtils.ts

@@ -15,6 +15,19 @@ export class NumberUtils {
         return `${Utils.hexadecimalPrefix}${basePart}`;
     }
 
+    /**
+     * @param {number} number
+     * @returns {[number, (number | null)]}
+     */
+    public static extractIntegerAndDecimalParts (number: number): [number, number | null] {
+        const integerPart: number = Math.floor(number);
+        const decimalPart: number | null = number !== integerPart
+            ? number % 1
+            : null;
+
+        return [integerPart, decimalPart];
+    }
+
     /**
      * @param {number} number
      * @returns {boolean}
@@ -61,6 +74,18 @@ export class NumberUtils {
         return number < Number.MIN_SAFE_INTEGER || number > Number.MAX_SAFE_INTEGER;
     }
 
+    /**
+     * @param {number} number
+     * @param {number} delta
+     * @returns {boolean}
+     */
+    public static isUnsafePrecisionNumber (number: number, delta: number): boolean {
+        const x: number = number + delta;
+        const x2: number = x - delta;
+
+        return number !== x2;
+    }
+
     /**
      * Returns all factors of a number
      * Based on https://stackoverflow.com/a/43204663

+ 8 - 11
test/dev/dev.ts

@@ -7,20 +7,17 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-           function foo () {
-              if (bar) {
-                if (baz) {
-                  const a = aa()
-                }
-              } else {
-                bb()
-              }
-            }
+            const epsilon = 500;
+            const number = 500000.0000001;
+             
+            if(epsilon > 0 && number > 500000.0000000 && number < 500000.0000002) {
+                console.log("math works!");
+            };
+
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
-            compact: false,
-            simplify: true
+            numbersToExpressions: true
         }
     ).getObfuscatedCode();
 

+ 51 - 19
test/functional-tests/node-transformers/converting-transformers/numbers-to-numerical-expressions-transformer/NumbersToNumericalExpressionsTransformer.spec.ts

@@ -40,32 +40,64 @@ describe('NumbersToNumericalExpressionsTransformer', function () {
     });
 
     describe('Variant #2: float number', () => {
-        const number: number = 50.5;
-        const samplesCount: number = 15;
+        describe('Variant #1: Number `50.5`', () => {
+            const number: number = 50.5;
+            const samplesCount: number = 15;
 
-        let areValidExpressions: boolean = true;
+            let areValidExpressions: boolean = true;
 
-        before(() => {
-            for (let i = 0; i < samplesCount; i++) {
-                const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
-                    `${number};`,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET,
-                        numbersToExpressions: true
-                    }
-                ).getObfuscatedCode();
+            before(() => {
+                for (let i = 0; i < samplesCount; i++) {
+                    const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
+                        `${number};`,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            numbersToExpressions: true
+                        }
+                    ).getObfuscatedCode();
 
-                const result: number = eval(obfuscatedCode);
+                    const result: number = eval(obfuscatedCode);
 
-                if (result !== number) {
-                    areValidExpressions = false;
-                    break;
+                    if (result !== number) {
+                        areValidExpressions = false;
+                        break;
+                    }
                 }
-            }
+            });
+
+            it('should correctly transform numbers to expressions', () => {
+                assert.isTrue(areValidExpressions);
+            });
         });
 
-        it('should correctly transform numbers to expressions', () => {
-            assert.isTrue(areValidExpressions);
+        describe('Variant #2: Number `1e-13`', () => {
+            const number: number = 1e-13;
+            const samplesCount: number = 15;
+
+            let areValidExpressions: boolean = true;
+
+            before(() => {
+                for (let i = 0; i < samplesCount; i++) {
+                    const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
+                        `${number};`,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            numbersToExpressions: true
+                        }
+                    ).getObfuscatedCode();
+
+                    const result: number = eval(obfuscatedCode);
+
+                    if (result !== number) {
+                        areValidExpressions = false;
+                        break;
+                    }
+                }
+            });
+
+            it('should correctly transform numbers to expressions', () => {
+                assert.isTrue(areValidExpressions);
+            });
         });
     });
 

+ 90 - 34
test/unit-tests/node/numerical-expression-data-to-node-converter/NumericalExpressionDataToNodeConverter.spec.ts

@@ -10,47 +10,103 @@ import { NodeFactory } from '../../../../src/node/NodeFactory';
 import { NumericalExpressionDataToNodeConverter } from '../../../../src/node/NumericalExpressionDataToNodeConverter';
 
 describe('NumericalExpressionDataToNodeConverter', () => {
-    describe('Variant #1: base', () => {
-        const expectedExpressionNode: ESTree.Expression = NodeFactory.binaryExpressionNode(
-            '+',
-            NodeFactory.binaryExpressionNode(
+    describe('convertIntegerNumberData', () => {
+        describe('Variant #1: base', () => {
+            const numberNumericalExpressionData: TNumberNumericalExpressionData = [
+                1, [-2, 3], 4
+            ];
+
+            const expectedExpressionNode: ESTree.Expression = NodeFactory.binaryExpressionNode(
                 '+',
-                NodeFactory.literalNode(1),
                 NodeFactory.binaryExpressionNode(
-                    '*',
-                    NodeFactory.unaryExpressionNode(
-                        '-',
-                        NodeFactory.literalNode(2),
+                    '+',
+                    NodeFactory.literalNode(1),
+                    NodeFactory.binaryExpressionNode(
+                        '*',
+                        NodeFactory.unaryExpressionNode(
+                            '-',
+                            NodeFactory.literalNode(2),
+                        ),
+                        NodeFactory.literalNode(3)
                     ),
-                    NodeFactory.literalNode(3)
                 ),
-            ),
-            NodeFactory.literalNode(4)
-        );
-        const numberNumericalExpressionData: TNumberNumericalExpressionData = [
-            1, [-2, 3], 4
-        ];
-
-        let expressionNode: ESTree.Expression;
-
-        before(() => {
-            expressionNode = NumericalExpressionDataToNodeConverter.convert(
-                numberNumericalExpressionData,
-                (number: number, isPositiveNumber: boolean): ESTree.Expression => {
-                    const numberLiteralNode: ESTree.Literal = NodeFactory.literalNode(number);
-
-                    return isPositiveNumber
-                        ? numberLiteralNode
-                        : NodeFactory.unaryExpressionNode(
-                            '-',
-                            numberLiteralNode
-                        );
-                }
+                NodeFactory.literalNode(4)
             );
+
+            let expressionNode: ESTree.Expression;
+
+            before(() => {
+                expressionNode = NumericalExpressionDataToNodeConverter.convertIntegerNumberData(
+                    numberNumericalExpressionData,
+                    (number: number, isPositiveNumber: boolean): ESTree.Expression => {
+                        const numberLiteralNode: ESTree.Literal = NodeFactory.literalNode(number);
+
+                        return isPositiveNumber
+                            ? numberLiteralNode
+                            : NodeFactory.unaryExpressionNode(
+                                '-',
+                                numberLiteralNode
+                            );
+                    }
+                );
+            });
+
+            it('should convert number numerical expression data to expression node', () => {
+                assert.deepEqual(expressionNode, expectedExpressionNode);
+            });
         });
+    });
+
+    describe('convertFloatNumberData', () => {
+        describe('Variant #1: base', () => {
+            const integerNumberNumericalExpressionData: TNumberNumericalExpressionData = [
+                1, [-2, 3], 4
+            ];
+            const decimalPart: number = 0.000000001;
+
+            const expectedExpressionNode: ESTree.Expression = NodeFactory.binaryExpressionNode(
+                '+',
+                NodeFactory.binaryExpressionNode(
+                    '+',
+                    NodeFactory.binaryExpressionNode(
+                        '+',
+                        NodeFactory.literalNode(1),
+                        NodeFactory.binaryExpressionNode(
+                            '*',
+                            NodeFactory.unaryExpressionNode(
+                                '-',
+                                NodeFactory.literalNode(2),
+                            ),
+                            NodeFactory.literalNode(3)
+                        ),
+                    ),
+                    NodeFactory.literalNode(4)
+                ),
+                NodeFactory.literalNode(decimalPart)
+            );
+
+            let expressionNode: ESTree.Expression;
+
+            before(() => {
+                expressionNode = NumericalExpressionDataToNodeConverter.convertFloatNumberData(
+                    integerNumberNumericalExpressionData,
+                    decimalPart,
+                    (number: number, isPositiveNumber: boolean): ESTree.Expression => {
+                        const numberLiteralNode: ESTree.Literal = NodeFactory.literalNode(number);
+
+                        return isPositiveNumber
+                            ? numberLiteralNode
+                            : NodeFactory.unaryExpressionNode(
+                                '-',
+                                numberLiteralNode
+                            );
+                    }
+                );
+            });
 
-        it('should convert number numerical expression data to expression node', () => {
-            assert.deepEqual(expressionNode, expectedExpressionNode);
+            it('should convert number numerical expression data to expression node', () => {
+                assert.deepEqual(expressionNode, expectedExpressionNode);
+            });
         });
     });
 });

+ 104 - 0
test/unit-tests/utils/NumberUtils.spec.ts

@@ -83,6 +83,110 @@ describe('NumberUtils', function () {
         });
     });
 
+    describe('extractIntegerAndDecimalParts', () => {
+        describe('Variant #1: number `0`', () => {
+            const number: number = 0;
+            const expectedParts: [number, number | null] = [0, null];
+
+            let parts: [number, number | null];
+
+            before(() => {
+                parts = NumberUtils.extractIntegerAndDecimalParts(number);
+            });
+
+            it('should extract integer and decimal parts', () => {
+                assert.deepEqual(parts, expectedParts);
+            });
+        });
+
+        describe('Variant #2: number `10`', () => {
+            const number: number = 10;
+            const expectedParts: [number, number | null] = [10, null];
+
+            let parts: [number, number | null];
+
+            before(() => {
+                parts = NumberUtils.extractIntegerAndDecimalParts(number);
+            });
+
+            it('should extract integer and decimal parts', () => {
+                assert.deepEqual(parts, expectedParts);
+            });
+        });
+
+        describe('Variant #3: number `-17`', () => {
+            const number: number = -17;
+            const expectedParts: [number, number | null] = [-17, null];
+
+            let parts: [number, number | null];
+
+            before(() => {
+                parts = NumberUtils.extractIntegerAndDecimalParts(number);
+            });
+
+            it('should extract integer and decimal parts', () => {
+                assert.deepEqual(parts, expectedParts);
+            });
+        });
+
+        describe('Variant #4: number `0.0000000001`', () => {
+            const number: number = 0.0000000001;
+            const expectedParts: [number, number | null] = [0, 0.0000000001];
+
+            let parts: [number, number | null];
+
+            before(() => {
+                parts = NumberUtils.extractIntegerAndDecimalParts(number);
+            });
+
+            it('should extract integer and decimal parts', () => {
+                assert.deepEqual(parts, expectedParts);
+            });
+
+            it('should return an initial number after sum of extracted parts', () => {
+                assert.equal(number, parts[0] + parts[1]!);
+            });
+        });
+
+        describe('Variant #5: number `10.0002`', () => {
+            const number: number = 10.0002;
+            const expectedParts: [number, number | null] = [10, 0.00019999999999953388];
+
+            let parts: [number, number | null];
+
+            before(() => {
+                parts = NumberUtils.extractIntegerAndDecimalParts(number);
+            });
+
+            it('should extract integer and decimal parts (with inaccuracy of float numbers)', () => {
+                assert.deepEqual(parts, expectedParts);
+            });
+
+            it('should return an initial number after sum of extracted parts', () => {
+                assert.equal(number, parts[0] + parts[1]!);
+            });
+        });
+
+        describe('Variant #5: number `1e-13`', () => {
+            const number: number = 1e-13;
+            const expectedParts: [number, number | null] = [0, 1e-13];
+
+            let parts: [number, number | null];
+
+            before(() => {
+                parts = NumberUtils.extractIntegerAndDecimalParts(number);
+            });
+
+            it('should extract integer and decimal parts', () => {
+                assert.deepEqual(parts, expectedParts);
+            });
+
+            it('should return an initial number after sum of extracted parts', () => {
+                assert.equal(number, parts[0] + parts[1]!);
+            });
+        });
+    });
+
     describe('isCeil', () => {
         describe('given number is a ceil', () => {
             const number: number = 4;

+ 71 - 65
yarn.lock

@@ -513,10 +513,10 @@
   dependencies:
     "@types/node" "*"
 
-"@types/[email protected].0":
-  version "8.2.0"
-  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.0.tgz#3eb56d13a1de1d347ecb1957c6860c911704bc44"
-  integrity sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==
+"@types/[email protected].1":
+  version "8.2.1"
+  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.1.tgz#f3f3ae4590c5386fc7c543aae9b78d4cf30ffee9"
+  integrity sha512-NysN+bNqj6E0Hv4CTGWSlPzMW6vTKjDpOteycDkV4IWBsO+PU48JonrPzV9ODjiI2XrjmA05KInLgF5ivZ/YGQ==
 
 "@types/[email protected]":
   version "4.0.0"
@@ -530,10 +530,10 @@
   resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.3.tgz#6356df2647de9eac569f9a52eda3480fa9e70b4d"
   integrity sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==
 
-"@types/[email protected].27":
-  version "14.14.27"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.27.tgz#c7127f8da0498993e13b1a42faf1303d3110d2f2"
-  integrity sha512-Ecfmo4YDQPwuqTCl1yBxLV5ihKfRlkBmzUEDcfIRvDxOTGQEeikr317Ln7Gcv0tjA8dVgKI3rniqW2G1OyKDng==
+"@types/[email protected].31":
+  version "14.14.31"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
+  integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
 
 "@types/normalize-package-data@^2.4.0":
   version "2.4.0"
@@ -580,13 +580,13 @@
   resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.0.tgz#8c0a9435dfa7b3b1be76562f3070efb3f92637b4"
   integrity sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==
 
-"@typescript-eslint/[email protected].0":
-  version "4.15.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.0.tgz#13a5a07cf30d0d5781e43480aa2a8d38d308b084"
-  integrity sha512-DJgdGZW+8CFUTz5C/dnn4ONcUm2h2T0itWD85Ob5/V27Ndie8hUoX5HKyGssvR8sUMkAIlUc/AMK67Lqa3kBIQ==
+"@typescript-eslint/[email protected].1":
+  version "4.15.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.1.tgz#835f64aa0a403e5e9e64c10ceaf8d05c3f015180"
+  integrity sha512-yW2epMYZSpNJXZy22Biu+fLdTG8Mn6b22kR3TqblVk50HGNV8Zya15WAXuQCr8tKw4Qf1BL4QtI6kv6PCkLoJw==
   dependencies:
-    "@typescript-eslint/experimental-utils" "4.15.0"
-    "@typescript-eslint/scope-manager" "4.15.0"
+    "@typescript-eslint/experimental-utils" "4.15.1"
+    "@typescript-eslint/scope-manager" "4.15.1"
     debug "^4.1.1"
     functional-red-black-tree "^1.0.1"
     lodash "^4.17.15"
@@ -594,60 +594,60 @@
     semver "^7.3.2"
     tsutils "^3.17.1"
 
-"@typescript-eslint/[email protected].0":
-  version "4.15.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.0.tgz#b87c36410a9b23f637689427be85007a2ec1a9c6"
-  integrity sha512-V4vaDWvxA2zgesg4KPgEGiomWEBpJXvY4ZX34Y3qxK8LUm5I87L+qGIOTd9tHZOARXNRt9pLbblSKiYBlGMawg==
+"@typescript-eslint/[email protected].1":
+  version "4.15.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.1.tgz#d744d1ac40570a84b447f7aa1b526368afd17eec"
+  integrity sha512-9LQRmOzBRI1iOdJorr4jEnQhadxK4c9R2aEAsm7WE/7dq8wkKD1suaV0S/JucTL8QlYUPU1y2yjqg+aGC0IQBQ==
   dependencies:
     "@types/json-schema" "^7.0.3"
-    "@typescript-eslint/scope-manager" "4.15.0"
-    "@typescript-eslint/types" "4.15.0"
-    "@typescript-eslint/typescript-estree" "4.15.0"
+    "@typescript-eslint/scope-manager" "4.15.1"
+    "@typescript-eslint/types" "4.15.1"
+    "@typescript-eslint/typescript-estree" "4.15.1"
     eslint-scope "^5.0.0"
     eslint-utils "^2.0.0"
 
-"@typescript-eslint/[email protected].0":
-  version "4.15.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.15.0.tgz#8df94365b4b7161f9e8514fe28aef19954810b6b"
-  integrity sha512-L6Dtbq8Bc7g2aZwnIBETpmUa9XDKCMzKVwAArnGp5Mn7PRNFjf3mUzq8UeBjL3K8t311hvevnyqXAMSmxO8Gpg==
+"@typescript-eslint/[email protected].1":
+  version "4.15.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.15.1.tgz#4c91a0602733db63507e1dbf13187d6c71a153c4"
+  integrity sha512-V8eXYxNJ9QmXi5ETDguB7O9diAXlIyS+e3xzLoP/oVE4WCAjssxLIa0mqCLsCGXulYJUfT+GV70Jv1vHsdKwtA==
   dependencies:
-    "@typescript-eslint/scope-manager" "4.15.0"
-    "@typescript-eslint/types" "4.15.0"
-    "@typescript-eslint/typescript-estree" "4.15.0"
+    "@typescript-eslint/scope-manager" "4.15.1"
+    "@typescript-eslint/types" "4.15.1"
+    "@typescript-eslint/typescript-estree" "4.15.1"
     debug "^4.1.1"
 
-"@typescript-eslint/[email protected].0":
-  version "4.15.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.15.0.tgz#c42703558ea6daaaba51a9c3a86f2902dbab9432"
-  integrity sha512-CSNBZnCC2jEA/a+pR9Ljh8Y+5TY5qgbPz7ICEk9WCpSEgT6Pi7H2RIjxfrrbUXvotd6ta+i27sssKEH8Azm75g==
+"@typescript-eslint/[email protected].1":
+  version "4.15.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.15.1.tgz#f6511eb38def2a8a6be600c530c243bbb56ac135"
+  integrity sha512-ibQrTFcAm7yG4C1iwpIYK7vDnFg+fKaZVfvyOm3sNsGAerKfwPVFtYft5EbjzByDJ4dj1WD8/34REJfw/9wdVA==
   dependencies:
-    "@typescript-eslint/types" "4.15.0"
-    "@typescript-eslint/visitor-keys" "4.15.0"
+    "@typescript-eslint/types" "4.15.1"
+    "@typescript-eslint/visitor-keys" "4.15.1"
 
-"@typescript-eslint/[email protected].0":
-  version "4.15.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.15.0.tgz#3011ae1ac3299bb9a5ac56bdd297cccf679d3662"
-  integrity sha512-su4RHkJhS+iFwyqyXHcS8EGPlUVoC+XREfy5daivjLur9JP8GhvTmDipuRpcujtGC4M+GYhUOJCPDE3rC5NJrg==
+"@typescript-eslint/[email protected].1":
+  version "4.15.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.15.1.tgz#da702f544ef1afae4bc98da699eaecd49cf31c8c"
+  integrity sha512-iGsaUyWFyLz0mHfXhX4zO6P7O3sExQpBJ2dgXB0G5g/8PRVfBBsmQIc3r83ranEQTALLR3Vko/fnCIVqmH+mPw==
 
-"@typescript-eslint/[email protected].0":
-  version "4.15.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.0.tgz#402c86a7d2111c1f7a2513022f22a38a395b7f93"
-  integrity sha512-jG6xTmcNbi6xzZq0SdWh7wQ9cMb2pqXaUp6bUZOMsIlu5aOlxGxgE/t6L/gPybybQGvdguajXGkZKSndZJpksA==
+"@typescript-eslint/[email protected].1":
+  version "4.15.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.1.tgz#fa9a9ff88b4a04d901ddbe5b248bc0a00cd610be"
+  integrity sha512-z8MN3CicTEumrWAEB2e2CcoZa3KP9+SMYLIA2aM49XW3cWIaiVSOAGq30ffR5XHxRirqE90fgLw3e6WmNx5uNw==
   dependencies:
-    "@typescript-eslint/types" "4.15.0"
-    "@typescript-eslint/visitor-keys" "4.15.0"
+    "@typescript-eslint/types" "4.15.1"
+    "@typescript-eslint/visitor-keys" "4.15.1"
     debug "^4.1.1"
     globby "^11.0.1"
     is-glob "^4.0.1"
     semver "^7.3.2"
     tsutils "^3.17.1"
 
-"@typescript-eslint/[email protected].0":
-  version "4.15.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.0.tgz#2a07768df30c8a5673f1bce406338a07fdec38ca"
-  integrity sha512-RnDtJwOwFucWFAMjG3ghCG/ikImFJFEg20DI7mn4pHEx3vC48lIAoyjhffvfHmErRDboUPC7p9Z2il4CLb7qxA==
+"@typescript-eslint/[email protected].1":
+  version "4.15.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.1.tgz#c76abbf2a3be8a70ed760f0e5756bf62de5865dd"
+  integrity sha512-tYzaTP9plooRJY8eNlpAewTOqtWW/4ff/5wBjNVaJ0S0wC4Gpq/zDVRTJa5bq2v1pCNQ08xxMCndcvR+h7lMww==
   dependencies:
-    "@typescript-eslint/types" "4.15.0"
+    "@typescript-eslint/types" "4.15.1"
     eslint-visitor-keys "^2.0.0"
 
 "@ungap/[email protected]":
@@ -1302,16 +1302,21 @@ colorette@^1.2.1:
   resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
   integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
 
-commander@7.0.0, commander@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-7.0.0.tgz#3e2bbfd8bb6724760980988fb5b22b7ee6b71ab2"
-  integrity sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA==
+commander@7.1.0:
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-7.1.0.tgz#f2eaecf131f10e36e07d894698226e36ae0eb5ff"
+  integrity sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==
 
 commander@^2.20.0:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
 
+commander@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-7.0.0.tgz#3e2bbfd8bb6724760980988fb5b22b7ee6b71ab2"
+  integrity sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA==
+
 [email protected]:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.1.2.tgz#e5317d7a2ec22b470dcb54a29b25426c30bf39d8"
@@ -1730,10 +1735,10 @@ [email protected]:
     resolve "^1.17.0"
     tsconfig-paths "^3.9.0"
 
-eslint-plugin-jsdoc@31.6.1:
-  version "31.6.1"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-31.6.1.tgz#98040c801500572fff71c984a097d89946f1e450"
-  integrity sha512-5hCV3u+1VSEUMyfdTl+dpWsioD7tqQr2ILQw+KbXrF42AVxCLO8gnNLR6zDCDjqGGpt79V1sgY0RRchCWuCigg==
+eslint-plugin-jsdoc@32.1.0:
+  version "32.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.1.0.tgz#30ba4d7b7e5fa00ebb3b980c66d6478f68ccc226"
+  integrity sha512-nCdKF8QQvAZ6RsnNoEK4kPF0aD9E6XURdjLx88oIqF+txmPNXAo2rNvu2WwV77R78vnhAGJkeOgmxmYdRRpgaQ==
   dependencies:
     comment-parser "1.1.2"
     debug "^4.3.1"
@@ -1753,15 +1758,16 @@ [email protected]:
   resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz#e7fbb3fa4cd84ff1015b9c51ad86550e55041041"
   integrity sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==
 
[email protected].0:
-  version "28.0.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-28.0.0.tgz#41bbc9a62119a9d19466942f9ad059c57d54532f"
-  integrity sha512-+VTwBbHsJk/jACDxeWhtLfLxru+9cV+jt/mX7a/WjHa/5xrS0S4ZFYJSg4z54s0waeAAO9D+CPB39Pch40qABg==
[email protected].2:
+  version "28.0.2"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-28.0.2.tgz#ab9884ebae04590ecd9c1c294330d889a74b7c37"
+  integrity sha512-k4AoFP7n8/oq6lBXkdc9Flid6vw2B8j7aXFCxgzJCyKvmaKrCUFb1TFPhG9eSJQFZowqmymMPRtl8oo9NKLUbw==
   dependencies:
     ci-info "^2.0.0"
     clean-regexp "^1.0.0"
     eslint-template-visitor "^2.2.2"
     eslint-utils "^2.1.0"
+    eslint-visitor-keys "^2.0.0"
     import-modules "^2.1.0"
     lodash "^4.17.20"
     pluralize "^8.0.0"
@@ -4248,10 +4254,10 @@ webpack-sources@^2.1.1:
     source-list-map "^2.0.1"
     source-map "^0.6.1"
 
[email protected]1.2:
-  version "5.21.2"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.21.2.tgz#647507e50d3637695be28af58a6a8246050394e7"
-  integrity sha512-xHflCenx+AM4uWKX71SWHhxml5aMXdy2tu/vdi4lClm7PADKxlyDAFFN1rEFzNV0MAoPpHtBeJnl/+K6F4QBPg==
[email protected]3.0:
+  version "5.23.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.23.0.tgz#9ed57e9a54b267b3549899271ad780cddc6ee316"
+  integrity sha512-RC6dwDuRxiU75F8XC4H08NtzUrMfufw5LDnO8dTtaKU2+fszEdySCgZhNwSBBn516iNaJbQI7T7OPHIgCwcJmg==
   dependencies:
     "@types/eslint-scope" "^3.7.0"
     "@types/estree" "^0.0.46"

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff