Преглед на файлове

Merge pull request #192 from javascript-obfuscator/esprima-template-literal-fix

Esprima template literal fix
Timofey Kachalov преди 7 години
родител
ревизия
ccc2325d56

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 ===
+v0.14.1
+---
+* Temporary fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/181
+    
 v0.14.0
 ---
 * **New option:** `identifiersPrefix` sets prefix for all generated identifiers.

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
dist/index.js


+ 6 - 6
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.14.0",
+  "version": "0.14.1",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -19,10 +19,10 @@
     "javascript-obfuscator": "./bin/javascript-obfuscator"
   },
   "dependencies": {
-    "chalk": "2.3.0",
+    "chalk": "2.3.1",
     "chance": "1.0.13",
     "class-validator": "0.8.1",
-    "commander": "2.14.0",
+    "commander": "2.14.1",
     "escodegen-wallaby": "1.6.17",
     "esprima": "4.0.0",
     "estraverse": "4.2.0",
@@ -47,7 +47,7 @@
     "@types/md5": "2.1.32",
     "@types/mkdirp": "0.5.2",
     "@types/mocha": "2.2.48",
-    "@types/node": "9.4.1",
+    "@types/node": "9.4.5",
     "@types/rimraf": "2.0.2",
     "@types/sinon": "4.1.3",
     "@types/string-template": "1.0.2",
@@ -63,7 +63,7 @@
     "mocha": "5.0.0",
     "pre-commit": "1.2.2",
     "rimraf": "2.6.2",
-    "sinon": "4.2.2",
+    "sinon": "4.3.0",
     "threads": "0.10.1",
     "ts-node": "4.1.0",
     "tslint": "5.9.1",
@@ -71,7 +71,7 @@
     "tslint-language-service": "0.9.8",
     "tslint-webpack-plugin": "1.1.1",
     "typescript": "2.7.1",
-    "webpack": "3.10.0",
+    "webpack": "3.11.0",
     "webpack-node-externals": "1.6.0"
   },
   "repository": {

+ 42 - 0
src/node-transformers/converting-transformers/TemplateLiteralTransformer.ts

@@ -1,8 +1,11 @@
 import { inject, injectable, } from 'inversify';
 import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
 
+import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
+import { TStatement } from '../../types/node/TStatement';
+
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
@@ -12,6 +15,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { NodeGuards } from '../../node/NodeGuards';
 import { Nodes } from '../../node/Nodes';
+import { NodeUtils } from '../../node/NodeUtils';
 
 /**
  * Transform ES2015 template literals to ES5
@@ -47,6 +51,13 @@ export class TemplateLiteralTransformer extends AbstractNodeTransformer {
             case TransformationStage.Converting:
                 return {
                     enter: (node: ESTree.Node, parentNode: ESTree.Node | null) => {
+                        if (parentNode
+                            && NodeGuards.isExpressionStatementNode(node)
+                            && NodeGuards.isTemplateLiteralNode(node.expression)
+                        ) {
+                            return this.fixEsprimaReturnStatementTemplateLiteralNode(node, node.expression);
+                        }
+
                         if (parentNode && NodeGuards.isTemplateLiteralNode(node)) {
                             return this.transformNode(node, parentNode);
                         }
@@ -109,4 +120,35 @@ export class TemplateLiteralTransformer extends AbstractNodeTransformer {
 
         return nodes[0];
     }
+
+    /**
+     * @param {ExpressionStatement} expressionStatementNode
+     * @param {TemplateLiteral} templateLiteralNode
+     * @returns {Node | VisitorOption}
+     */
+    private fixEsprimaReturnStatementTemplateLiteralNode (
+        expressionStatementNode: ESTree.ExpressionStatement,
+        templateLiteralNode: ESTree.TemplateLiteral
+    ): ESTree.Node | estraverse.VisitorOption {
+        const previousSiblingStatementNode: TStatement | null = NodeUtils
+            .getPreviousSiblingStatementNode(expressionStatementNode);
+
+        if (
+            !previousSiblingStatementNode
+            || !templateLiteralNode.parentNode
+            || !NodeGuards.isReturnStatementNode(previousSiblingStatementNode)
+            || previousSiblingStatementNode.argument !== null
+        ) {
+            return expressionStatementNode;
+        }
+
+        previousSiblingStatementNode.argument = <ESTree.Expression>this.transformNode(
+            templateLiteralNode,
+            templateLiteralNode.parentNode
+        );
+
+        NodeUtils.parentizeNode(templateLiteralNode, previousSiblingStatementNode);
+
+        return estraverse.VisitorOption.Remove;
+    }
 }

+ 31 - 0
src/node/NodeUtils.ts

@@ -71,6 +71,22 @@ export class NodeUtils {
         return NodeUtils.getBlockScopesOfNodeRecursive(targetNode);
     }
 
+    /**
+     * @param {Statement} node
+     * @returns {TStatement | null}
+     */
+    public static getNextSiblingStatementNode (node: ESTree.Statement): TStatement | null {
+        return NodeUtils.getSiblingStatementNodeByOffset(node, 1);
+    }
+
+    /**
+     * @param {Statement} node
+     * @returns {TStatement | null}
+     */
+    public static getPreviousSiblingStatementNode (node: ESTree.Statement): TStatement | null {
+        return NodeUtils.getSiblingStatementNodeByOffset(node, -1);
+    }
+
     /**
      * @param {NodeGuards} node
      * @returns {TNodeWithScope}
@@ -208,4 +224,19 @@ export class NodeUtils {
 
         return blockScopes;
     }
+
+    /**
+     * @param {Statement} node
+     * @param {number} offset
+     * @returns {TStatement | null}
+     */
+    private static getSiblingStatementNodeByOffset (node: ESTree.Statement, offset: number): TStatement | null {
+        const scopeNode: TNodeWithScope = NodeUtils.getScopeOfNode(node);
+        const scopeBody: TStatement[] = !NodeGuards.isSwitchCaseNode(scopeNode)
+            ? scopeNode.body
+            : scopeNode.consequent;
+        const indexInScope: number = scopeBody.indexOf(node);
+
+        return scopeBody[indexInScope + offset] || null;
+    }
 }

+ 44 - 3
test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/TemplateLiteralTransformer.spec.ts

@@ -24,7 +24,48 @@ describe('TemplateLiteralTransformer', () => {
         });
     });
 
-    describe('variant #1: simple template literal with expression only', () => {
+    describe('variant #2: multiline template literals', () => {
+        it('variant #1: should transform es6 multiline template literal to es5', () => {
+            const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    unicodeEscapeSequence: false
+                }
+            );
+
+            assert.match(obfuscationResult.getObfuscatedCode(),  /^var *test *= *'foo\\x0abar';$/);
+        });
+
+        it('variant #2: should transform es6 multiline template literal inside return statement', () => {
+            const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-return-statement-1.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    unicodeEscapeSequence: false
+                }
+            );
+
+            assert.match(obfuscationResult.getObfuscatedCode(),  /{ *return *'foo\\x0abar'; *}$/);
+        });
+
+        it('variant #3: should transform es6 multiline template literal inside return statement', () => {
+            const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-return-statement-2.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    unicodeEscapeSequence: false
+                }
+            );
+
+            assert.match(obfuscationResult.getObfuscatedCode(),  /case *!!\[] *: *return *'foo\\x0abar'; *} *}$/);
+        });
+    });
+
+    describe('variant #3: simple template literal with expression only', () => {
         it('should transform es6 template literal to es5 and add empty literal node before expression node', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/expression-only.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
@@ -39,7 +80,7 @@ describe('TemplateLiteralTransformer', () => {
         });
     });
 
-    describe('variant #3: literal node inside expression', () => {
+    describe('variant #4: literal node inside expression', () => {
         it('should transform es6 template literal to es5', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/literal-inside-expression.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
@@ -54,7 +95,7 @@ describe('TemplateLiteralTransformer', () => {
         });
     });
 
-    describe('variant #4: multiple expressions', () => {
+    describe('variant #5: multiple expressions', () => {
         it('should transform es6 template literal to es5', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiple-expressions.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(

+ 4 - 0
test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/fixtures/multiline-template-literal-return-statement-1.js

@@ -0,0 +1,4 @@
+function foo() {
+    return `foo
+bar`;
+}

+ 7 - 0
test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/fixtures/multiline-template-literal-return-statement-2.js

@@ -0,0 +1,7 @@
+function hi() {
+    switch (true) {
+        case true:
+            return `foo
+bar`;
+    }
+}

+ 2 - 0
test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/fixtures/multiline-template-literal.js

@@ -0,0 +1,2 @@
+var test = `foo
+bar`;

+ 170 - 0
test/unit-tests/node/node-utils/NodeUtils.spec.ts

@@ -294,6 +294,176 @@ describe('NodeUtils', () => {
         });
     });
 
+    describe('getNextSiblingStatementNode (node: ESTree.Statement): TStatement | null', () => {
+        describe('variant #1: block statement node as scope node', () => {
+                let statementNode1: ESTree.Statement,
+                statementNode2: ESTree.Statement,
+                statementNode3: ESTree.Statement;
+
+            before(() => {
+                statementNode1 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('a')
+                );
+                statementNode2 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('b')
+                );
+                statementNode3 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('c')
+                );
+
+                const blockStatementNode: ESTree.BlockStatement = Nodes.getBlockStatementNode([
+                    statementNode1,
+                    statementNode2,
+                    statementNode3
+                ]);
+
+                statementNode1.parentNode = blockStatementNode;
+                statementNode2.parentNode = blockStatementNode;
+                statementNode3.parentNode = blockStatementNode;
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getNextSiblingStatementNode(statementNode1), statementNode2);
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getNextSiblingStatementNode(statementNode2), statementNode3);
+            });
+
+            it('should return `null` if given statement node is last node in the scope', () => {
+                assert.deepEqual(NodeUtils.getNextSiblingStatementNode(statementNode3), null);
+            });
+        });
+
+        describe('variant #2: switch case node as scope node', () => {
+            let statementNode1: ESTree.Statement,
+                statementNode2: ESTree.Statement,
+                statementNode3: ESTree.Statement;
+
+            before(() => {
+                statementNode1 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('a')
+                );
+                statementNode2 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('b')
+                );
+                statementNode3 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('c')
+                );
+
+                const switchCaseNode: ESTree.SwitchCase = Nodes.getSwitchCaseNode(
+                    Nodes.getLiteralNode(true),
+                    [
+                        statementNode1,
+                        statementNode2,
+                        statementNode3
+                    ]
+                );
+
+                statementNode1.parentNode = switchCaseNode;
+                statementNode2.parentNode = switchCaseNode;
+                statementNode3.parentNode = switchCaseNode;
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getNextSiblingStatementNode(statementNode1), statementNode2);
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getNextSiblingStatementNode(statementNode2), statementNode3);
+            });
+
+            it('should return `null` if given statement node is last node in the scope', () => {
+                assert.deepEqual(NodeUtils.getNextSiblingStatementNode(statementNode3), null);
+            });
+        });
+    });
+
+    describe('getPreviousSiblingStatementNode (node: ESTree.Statement): TStatement | null', () => {
+        describe('variant #1: block statement node as scope node', () => {
+            let statementNode1: ESTree.Statement,
+                statementNode2: ESTree.Statement,
+                statementNode3: ESTree.Statement;
+
+            before(() => {
+                statementNode1 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('a')
+                );
+                statementNode2 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('b')
+                );
+                statementNode3 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('c')
+                );
+
+                const blockStatementNode: ESTree.BlockStatement = Nodes.getBlockStatementNode([
+                    statementNode1,
+                    statementNode2,
+                    statementNode3
+                ]);
+
+                statementNode1.parentNode = blockStatementNode;
+                statementNode2.parentNode = blockStatementNode;
+                statementNode3.parentNode = blockStatementNode;
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getPreviousSiblingStatementNode(statementNode1), null);
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getPreviousSiblingStatementNode(statementNode2), statementNode1);
+            });
+
+            it('should return `null` if given statement node is last node in the scope', () => {
+                assert.deepEqual(NodeUtils.getPreviousSiblingStatementNode(statementNode3), statementNode2);
+            });
+        });
+
+        describe('variant #2: switch case node as scope node', () => {
+            let statementNode1: ESTree.Statement,
+                statementNode2: ESTree.Statement,
+                statementNode3: ESTree.Statement;
+
+            before(() => {
+                statementNode1 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('a')
+                );
+                statementNode2 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('b')
+                );
+                statementNode3 = Nodes.getExpressionStatementNode(
+                    Nodes.getIdentifierNode('c')
+                );
+
+                const switchCaseNode: ESTree.SwitchCase = Nodes.getSwitchCaseNode(
+                    Nodes.getLiteralNode(true),
+                    [
+                        statementNode1,
+                        statementNode2,
+                        statementNode3
+                    ]
+                );
+
+                statementNode1.parentNode = switchCaseNode;
+                statementNode2.parentNode = switchCaseNode;
+                statementNode3.parentNode = switchCaseNode;
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getPreviousSiblingStatementNode(statementNode1), null);
+            });
+
+            it('should return next sibling statement node', () => {
+                assert.deepEqual(NodeUtils.getPreviousSiblingStatementNode(statementNode2), statementNode1);
+            });
+
+            it('should return `null` if given statement node is last node in the scope', () => {
+                assert.deepEqual(NodeUtils.getPreviousSiblingStatementNode(statementNode3), statementNode2);
+            });
+        });
+    });
+
     describe('getScopeOfNode (node: ESTree.Node): TNodeWithScope | null', () => {
         let functionDeclarationBlockStatementNode: ESTree.BlockStatement,
             ifStatementBlockStatementNode1: ESTree.BlockStatement,

+ 49 - 26
yarn.lock

@@ -2,6 +2,12 @@
 # yarn lockfile v1
 
 
+"@sinonjs/formatio@^2.0.0":
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2"
+  dependencies:
+    samsam "1.3.0"
+
 "@types/[email protected]":
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21"
@@ -66,9 +72,9 @@
   version "8.0.53"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
 
-"@types/[email protected].1":
-  version "9.4.1"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.1.tgz#0f636f7837e15d2d73a7f6f3ea0e322eb2a5ab65"
+"@types/[email protected].5":
+  version "9.4.5"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.5.tgz#d2a90c634208173d1b1a0a6ba9f1df3de62edcf5"
 
 "@types/[email protected]":
   version "2.0.2"
@@ -115,9 +121,9 @@ acorn@^5.0.0:
   version "5.2.1"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7"
 
-ajv-keywords@^2.0.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
+ajv-keywords@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be"
 
 ajv@^4.9.1:
   version "4.11.8"
@@ -126,11 +132,10 @@ ajv@^4.9.1:
     co "^4.6.0"
     json-stable-stringify "^1.0.1"
 
-ajv@^5.1.5:
-  version "5.3.0"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda"
+ajv@^6.1.0:
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.1.1.tgz#978d597fbc2b7d0e5a5c3ddeb149a682f2abfa0e"
   dependencies:
-    co "^4.6.0"
     fast-deep-equal "^1.0.0"
     fast-json-stable-stringify "^2.0.0"
     json-schema-traverse "^0.3.0"
@@ -163,7 +168,7 @@ ansi-styles@^2.2.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
 
-ansi-styles@^3.1.0:
+ansi-styles@^3.1.0, ansi-styles@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
   dependencies:
@@ -964,7 +969,15 @@ [email protected], chalk@^1.0.0, chalk@^1.1.3:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
[email protected], chalk@^2.1.0, chalk@^2.3.0:
[email protected]:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
+  dependencies:
+    ansi-styles "^3.2.0"
+    escape-string-regexp "^1.0.5"
+    supports-color "^5.2.0"
+
+chalk@^2.1.0, chalk@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
   dependencies:
@@ -1087,9 +1100,9 @@ [email protected]:
   version "2.11.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
 
[email protected].0:
-  version "2.14.0"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.0.tgz#7b25325963e6aace20d3a9285b09379b0c2208b5"
[email protected].1:
+  version "2.14.1"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
 
 commander@^2.11.0:
   version "2.12.2"
@@ -1684,7 +1697,7 @@ form-data@~2.1.1:
     combined-stream "^1.0.5"
     mime-types "^2.1.12"
 
-[email protected], formatio@^1.2.0:
+formatio@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb"
   dependencies:
@@ -1834,6 +1847,10 @@ has-flag@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
 
+has-flag@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+
 has-unicode@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -3268,7 +3285,7 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0,
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
 
[email protected]:
+[email protected], [email protected]:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
 
@@ -3333,12 +3350,12 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
 
-sinon@4.2.2:
-  version "4.2.2"
-  resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.2.2.tgz#e039ab27bdb426fc61363c380726e996a2e2c620"
+sinon@4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.3.0.tgz#cec9b27d5f4e2c63c1a79c9dc1c05d34bb088234"
   dependencies:
+    "@sinonjs/formatio" "^2.0.0"
     diff "^3.1.0"
-    formatio "1.2.0"
     lodash.get "^4.4.2"
     lolex "^2.2.0"
     nise "^1.2.0"
@@ -3598,6 +3615,12 @@ supports-color@^5.1.0:
   dependencies:
     has-flag "^2.0.0"
 
+supports-color@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
+  dependencies:
+    has-flag "^3.0.0"
+
 tapable@^0.2.5, tapable@^0.2.7:
   version "0.2.8"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
@@ -3936,14 +3959,14 @@ webpack-sources@^1.0.1:
     source-list-map "^2.0.0"
     source-map "~0.5.3"
 
[email protected]0.0:
-  version "3.10.0"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725"
[email protected]1.0:
+  version "3.11.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.11.0.tgz#77da451b1d7b4b117adaf41a1a93b5742f24d894"
   dependencies:
     acorn "^5.0.0"
     acorn-dynamic-import "^2.0.0"
-    ajv "^5.1.5"
-    ajv-keywords "^2.0.0"
+    ajv "^6.1.0"
+    ajv-keywords "^3.1.0"
     async "^2.1.2"
     enhanced-resolve "^3.4.0"
     escope "^3.6.0"

Някои файлове не бяха показани, защото твърде много файлове са промени