mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
More cases with improved objectExpressionKeys support
Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/387
This commit is contained in:
@@ -3,6 +3,7 @@ Change Log
|
||||
v0.21.0
|
||||
---
|
||||
* Improved `transformObjectKeys` transformation to cover more cases
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/387
|
||||
|
||||
v0.20.4
|
||||
---
|
||||
|
||||
Vendored
+3
-3
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -14,6 +14,9 @@ export enum NodeType {
|
||||
ContinueStatement = 'ContinueStatement',
|
||||
ExportNamedDeclaration = 'ExportNamedDeclaration',
|
||||
ExpressionStatement = 'ExpressionStatement',
|
||||
ForStatement = 'ForStatement',
|
||||
ForInStatement = 'ForInStatement',
|
||||
ForOfStatement = 'ForOfStatement',
|
||||
FunctionDeclaration = 'FunctionDeclaration',
|
||||
FunctionExpression = 'FunctionExpression',
|
||||
Identifier = 'Identifier',
|
||||
|
||||
-8
@@ -70,14 +70,6 @@ export abstract class AbstractPropertiesExtractor implements IPropertiesExtracto
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {propertyValueNode is Pattern}
|
||||
*/
|
||||
protected static isProhibitedHostParent (node: ESTree.Node): node is ESTree.Pattern {
|
||||
return NodeGuards.isMemberExpressionNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {propertyValueNode is Pattern}
|
||||
|
||||
+32
-2
@@ -7,6 +7,7 @@ import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
|
||||
|
||||
import { AbstractPropertiesExtractor } from './AbstractPropertiesExtractor';
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
|
||||
@injectable()
|
||||
export class AssignmentExpressionPropertiesExtractor extends AbstractPropertiesExtractor {
|
||||
@@ -21,6 +22,35 @@ export class AssignmentExpressionPropertiesExtractor extends AbstractPropertiesE
|
||||
super(randomGenerator, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {propertyValueNode is Pattern}
|
||||
*/
|
||||
private static isProhibitedHostParent (node: ESTree.Node): node is ESTree.Pattern {
|
||||
if (NodeGuards.isMemberExpressionNode(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (AssignmentExpressionPropertiesExtractor.isProhibitedStatementNode(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// statements without block statement
|
||||
return NodeGuards.isExpressionStatementNode(node)
|
||||
&& !!node.parentNode
|
||||
&& AssignmentExpressionPropertiesExtractor.isProhibitedStatementNode(node.parentNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private static isProhibitedStatementNode (node: ESTree.Node): boolean {
|
||||
return NodeGuards.isIfStatementNode(node)
|
||||
|| NodeGuards.isForStatementTypeNode(node)
|
||||
|| NodeGuards.isWhileStatementNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ObjectExpression} objectExpressionNode
|
||||
* @param {AssignmentExpression} hostNode
|
||||
@@ -38,8 +68,8 @@ export class AssignmentExpressionPropertiesExtractor extends AbstractPropertiesE
|
||||
return objectExpressionNode;
|
||||
}
|
||||
|
||||
// left node shouldn't be as Pattern node
|
||||
if (hostParentNode && AbstractPropertiesExtractor.isProhibitedHostParent(hostParentNode)) {
|
||||
// left node shouldn't be as prohibited node
|
||||
if (hostParentNode && AssignmentExpressionPropertiesExtractor.isProhibitedHostParent(hostParentNode)) {
|
||||
return objectExpressionNode;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,42 @@ export class NodeGuards {
|
||||
&& !('directive' in node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isForStatementTypeNode (
|
||||
node: ESTree.Node
|
||||
): node is ESTree.ForStatement | ESTree.ForInStatement | ESTree.ForOfStatement {
|
||||
return NodeGuards.isForStatementNode(node)
|
||||
|| NodeGuards.isForInStatementNode(node)
|
||||
|| NodeGuards.isForOfStatementNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isForStatementNode (node: ESTree.Node): node is ESTree.ForStatement {
|
||||
return node.type === NodeType.ForStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isForInStatementNode (node: ESTree.Node): node is ESTree.ForInStatement {
|
||||
return node.type === NodeType.ForInStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isForOfStatementNode (node: ESTree.Node): node is ESTree.ForOfStatement {
|
||||
return node.type === NodeType.ForOfStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
@@ -160,6 +196,14 @@ export class NodeGuards {
|
||||
return node.type === NodeType.Identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isIfStatementNode (node: ESTree.Node): node is ESTree.IfStatement {
|
||||
return node.type === NodeType.IfStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
|
||||
+4
-10
@@ -8,20 +8,14 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
|
||||
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
||||
`
|
||||
function foo () {
|
||||
function foo () {
|
||||
return {
|
||||
bar: {
|
||||
foo: 1
|
||||
}
|
||||
};
|
||||
}
|
||||
var bar;
|
||||
if (false)
|
||||
bar = {baz: 1};
|
||||
}
|
||||
`,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
|
||||
+350
-21
@@ -456,34 +456,363 @@ describe('ObjectExpressionKeysTransformer', () => {
|
||||
|
||||
describe('correct placement of expression statements', () => {
|
||||
describe('Variant #1: if statement', () => {
|
||||
const match: string = `` +
|
||||
`if *\\(!!\\[]\\) *{` +
|
||||
describe('Variant #1: with block statement', () => {
|
||||
const match: string = `` +
|
||||
`if *\\(!!\\[]\\) *{` +
|
||||
`var *${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['foo'] *= *'bar';` +
|
||||
`}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
`}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-if-statement.js');
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-if-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
describe('Variant #2: without block statement', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch};` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['baz'] *= *'baz';` +
|
||||
`if *\\(!!\\[]\\)` +
|
||||
`${variableMatch} *= *${variableMatch};` +
|
||||
`else *` +
|
||||
`${variableMatch} *= *${variableMatch};` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-if-statement-without-block-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: inside condition', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch};` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`if *\\(${variableMatch} *= *${variableMatch}\\) *{}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-if-statement-condition.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: try statement', () => {
|
||||
describe('Variant #2: for statement', () => {
|
||||
describe('Variant #1: with block statement', () => {
|
||||
const match: string = `` +
|
||||
`for *\\(var *${variableMatch} *= *0x0; *${variableMatch} *< *0xa; *${variableMatch}\\+\\+\\) *{` +
|
||||
`var *${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['foo'] *= *'bar';` +
|
||||
`}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-for-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: without block statement', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch};` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`for *\\(var *${variableMatch} *= *0x0; *${variableMatch} *< *0xa; *${variableMatch}\\+\\+\\) *` +
|
||||
`${variableMatch} *= *${variableMatch};` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-for-statement-without-block-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: for in statement', () => {
|
||||
describe('Variant #1: with block statement', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`for *\\(var *${variableMatch} in *${variableMatch}\\) *{` +
|
||||
`${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-for-in-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: without block statement', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`for *\\(var *${variableMatch} in *${variableMatch}\\) *` +
|
||||
`${variableMatch} *= *${variableMatch};` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-for-in-statement-without-block-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4: for of statement', () => {
|
||||
describe('Variant #1: with block statement', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch} *= *\\[];` +
|
||||
`for *\\(var *${variableMatch} of *${variableMatch}\\) *{` +
|
||||
`${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-for-of-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: without block statement', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch} *= *\\[];` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`for *\\(var *${variableMatch} of *${variableMatch}\\) *` +
|
||||
`${variableMatch} *= *${variableMatch};` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-for-of-statement-without-block-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #5: while statement', () => {
|
||||
describe('Variant #1: with block statement', () => {
|
||||
const match: string = `` +
|
||||
`while *\\(!!\\[]\\) *{` +
|
||||
`var *${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['foo'] *= *'bar';` +
|
||||
`}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-while-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: without block statement', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch};` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`while *\\(!!\\[]\\)` +
|
||||
`${variableMatch} *= *${variableMatch};` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-while-statement-without-block-statement.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: inside condition', () => {
|
||||
const match: string = `` +
|
||||
`var ${variableMatch};` +
|
||||
`var ${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['bar'] *= *'bar';` +
|
||||
`while *\\(${variableMatch} *= *${variableMatch}\\) *{}` +
|
||||
``;
|
||||
const regExp: RegExp = new RegExp(match);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-while-statement-condition.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
transformObjectKeys: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly transform object keys', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #6: try statement', () => {
|
||||
const match: string = `` +
|
||||
`try *{` +
|
||||
`var *${variableMatch} *= *{};` +
|
||||
@@ -512,7 +841,7 @@ describe('ObjectExpressionKeysTransformer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: catch clause statement', () => {
|
||||
describe('Variant #7: catch clause statement', () => {
|
||||
const match: string = `` +
|
||||
`try *{` +
|
||||
`} *catch *\\(${variableMatch}\\) *{` +
|
||||
@@ -541,7 +870,7 @@ describe('ObjectExpressionKeysTransformer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4: switch catch statement', () => {
|
||||
describe('Variant #8: switch catch statement', () => {
|
||||
const match: string = `` +
|
||||
`switch *\\(!!\\[]\\) *{` +
|
||||
`case *!!\\[]:` +
|
||||
@@ -570,7 +899,7 @@ describe('ObjectExpressionKeysTransformer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #5: variable declarator with object call', () => {
|
||||
describe('Variant #9: variable declarator with object call', () => {
|
||||
describe('Variant #1', () => {
|
||||
const match: string = `` +
|
||||
`const *${variableMatch} *= *{}; *` +
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
(function(){
|
||||
var foo = {};
|
||||
for (var i in foo)
|
||||
foo = {bar: 'bar'};
|
||||
})();
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
(function(){
|
||||
var object = {};
|
||||
for (var i in object) {
|
||||
object = {bar: 'bar'};
|
||||
}
|
||||
})();
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
(function(){
|
||||
var foo = [];
|
||||
for (var i of foo)
|
||||
foo = {bar: 'bar'};
|
||||
})();
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
(function(){
|
||||
var object = [];
|
||||
for (var i of object) {
|
||||
object = {bar: 'bar'};
|
||||
}
|
||||
})();
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
(function(){
|
||||
var foo;
|
||||
for (var i = 0; i < 10; i++)
|
||||
foo = {bar: 'bar'};
|
||||
})();
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
(function(){
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var object = {
|
||||
foo: 'bar'
|
||||
};
|
||||
}
|
||||
})();
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
(function(){
|
||||
var object;
|
||||
if (object = {bar: 'bar'}) {}
|
||||
})();
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
(function () {
|
||||
var foo;
|
||||
if (true)
|
||||
foo = {bar: 'bar'};
|
||||
else
|
||||
foo = {baz: 'baz'};
|
||||
})();
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
(function(){
|
||||
var object;
|
||||
while (object = {bar: 'bar'}) {}
|
||||
})();
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
(function () {
|
||||
var foo;
|
||||
while (true)
|
||||
foo = {bar: 'bar'};
|
||||
})();
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
(function(){
|
||||
while (true) {
|
||||
var object = {
|
||||
foo: 'bar'
|
||||
};
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user