Skip to content

Commit

Permalink
Added ignoring of all object members previous to SpreadElement when…
Browse files Browse the repository at this point in the history
… `transformObjectKeys` option is enabled

Fixed #797
  • Loading branch information
sanex3339 committed Nov 3, 2020
1 parent 867c125 commit e8517bf
Show file tree
Hide file tree
Showing 14 changed files with 252 additions and 112 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
Change Log

v2.6.4
---
* Added ignoring of all object members previous to `SpreadElement` when `transformObjectKeys` option is enabled. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/797

v2.6.3
---
* Added `ExportSpecifierTransformer`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/791
Expand Down
2 changes: 1 addition & 1 deletion dist/index.browser.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.cli.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "2.6.3",
"version": "2.6.4",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand Down Expand Up @@ -58,36 +58,36 @@
"@types/mkdirp": "1.0.1",
"@types/mocha": "8.0.3",
"@types/multimatch": "4.0.0",
"@types/node": "14.14.5",
"@types/node": "14.14.6",
"@types/rimraf": "3.0.0",
"@types/sinon": "9.0.8",
"@types/string-template": "1.0.2",
"@types/webpack-env": "1.15.3",
"@typescript-eslint/eslint-plugin": "4.6.0",
"@typescript-eslint/parser": "4.6.0",
"@typescript-eslint/eslint-plugin": "4.6.1",
"@typescript-eslint/parser": "4.6.1",
"chai": "4.2.0",
"chai-exclude": "2.0.2",
"coveralls": "3.1.0",
"cross-env": "7.0.2",
"eslint": "7.12.1",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsdoc": "30.7.3",
"eslint-plugin-jsdoc": "30.7.6",
"eslint-plugin-no-null": "1.0.2",
"eslint-plugin-prefer-arrow": "1.2.2",
"eslint-plugin-unicorn": "23.0.0",
"fork-ts-checker-notifier-webpack-plugin": "3.0.0",
"fork-ts-checker-webpack-plugin": "5.2.0",
"mocha": "8.2.0",
"fork-ts-checker-webpack-plugin": "5.2.1",
"mocha": "8.2.1",
"nyc": "15.1.0",
"pjson": "1.0.9",
"pre-commit": "1.2.2",
"rimraf": "3.0.2",
"sinon": "9.2.0",
"sinon": "9.2.1",
"threads": "1.6.3",
"ts-loader": "8.0.7",
"ts-node": "9.0.0",
"typescript": "4.1.0-beta",
"webpack": "5.3.0",
"webpack": "5.3.2",
"webpack-cli": "4.1.0",
"webpack-node-externals": "2.5.2"
},
Expand Down
1 change: 1 addition & 0 deletions src/enums/node/NodeType.ts
Expand Up @@ -41,6 +41,7 @@ export enum NodeType {
RestElement = 'RestElement',
ReturnStatement = 'ReturnStatement',
SequenceExpression = 'SequenceExpression',
SpreadElement = 'SpreadElement',
Super = 'Super',
SwitchCase = 'SwitchCase',
SwitchStatement = 'SwitchStatement',
Expand Down
Expand Up @@ -152,11 +152,16 @@ export class BasePropertiesExtractor implements IObjectExpressionExtractor {
const expressionStatements: ESTree.ExpressionStatement[] = [];
const removablePropertyIds: number[] = [];

for (let i: number = 0; i < propertiesLength; i++) {
// have to iterate in the reversed order to fast check spread elements and break iteration on them
for (let i: number = propertiesLength - 1; i >= 0; i--) {
const property: (ESTree.Property | ESTree.SpreadElement) = properties[i];

// invalid property node
if (!NodeGuards.isPropertyNode(property) || BasePropertiesExtractor.isProhibitedPropertyNode(property)) {
// spread element
if (NodeGuards.isSpreadElementNode(property)) {
break;
}

if (BasePropertiesExtractor.isProhibitedPropertyNode(property)) {
continue;
}

Expand Down Expand Up @@ -199,8 +204,8 @@ export class BasePropertiesExtractor implements IObjectExpressionExtractor {
/**
* Stage 4: filling arrays
*/
expressionStatements.push(expressionStatementNode);
removablePropertyIds.push(i);
expressionStatements.unshift(expressionStatementNode);
removablePropertyIds.unshift(i);
}

return [expressionStatements, removablePropertyIds];
Expand Down
8 changes: 8 additions & 0 deletions src/node/NodeGuards.ts
Expand Up @@ -374,6 +374,14 @@ export class NodeGuards {
return node.type === NodeType.SequenceExpression;
}

/**
* @param {Node} node
* @returns {boolean}
*/
public static isSpreadElementNode (node: ESTree.Node): node is ESTree.SpreadElement {
return node.type === NodeType.SpreadElement;
}

/**
* @param {Node} node
* @returns {boolean}
Expand Down
19 changes: 9 additions & 10 deletions test/dev/dev.ts
Expand Up @@ -7,16 +7,15 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo

let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
function foo () {
const {
qq,
qqq,
} = object;
const foo = {
prop: 1
};
}
const foo = {
baz: 1
};
const bar = {
baz: 2,
bark: 3,
...foo,
};
console.log(bar);
`,
{
...NO_ADDITIONAL_NODES_PRESET,
Expand Down
Expand Up @@ -741,6 +741,72 @@ describe('ObjectExpressionKeysTransformer', () => {
assert.match(obfuscatedCode, regExp);
});
});

describe('Variant #19: object spread as member', () => {
describe('Variant #1: object spread as first member', () => {
const match: string = `` +
`const ${variableMatch} *= *{};` +
`${variableMatch}\\['baz'] *= *0x1;` +
`const foo *= *${variableMatch};` +
`const ${variableMatch} *= *{ *\.\.\.foo *};` +
`${variableMatch}\\['baz'] *= *0x2;` +
`${variableMatch}\\['bark'] *= *0x3;` +
`const bar *= *${variableMatch};` +
``;
const regExp: RegExp = new RegExp(match);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/object-spread-as-first-member.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});

it('shouldn transform object expressions keys', () => {
assert.match(obfuscatedCode, regExp);
});
});

describe('Variant #2: object spread as middle member', () => {
const match: string = `` +
`const ${variableMatch} *= *{};` +
`${variableMatch}\\['baz'] *= *0x1;` +
`const foo *= *${variableMatch};` +
`const ${variableMatch} *= *{ *` +
`'baz': *0x2, *` +
`\.\.\.foo *` +
`};` +
`${variableMatch}\\['bark'] *= *0x3;` +
`const bar *= *${variableMatch};` +
``;
const regExp: RegExp = new RegExp(match);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/object-spread-as-middle-member.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});

it('shouldn transform object expressions keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
});

describe('member expression as host of object expression', () => {
Expand Down Expand Up @@ -1849,5 +1915,38 @@ describe('ObjectExpressionKeysTransformer', () => {
assert.match(obfuscatedCode, regExp);
});
});

describe('Variant #12: object spread as last member', () => {
const match: string = `` +
`const ${variableMatch} *= *{};` +
`${variableMatch}\\['baz'] *= *0x1;` +
`const foo *= *${variableMatch};` +
`const ${variableMatch} *= *{ *` +
`'baz': *0x2 *,` +
`'bark': *0x3 *,` +
`\.\.\.foo *` +
`};` +
`const bar *= *${variableMatch};` +
``;
const regExp: RegExp = new RegExp(match);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/object-spread-as-last-member.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});

it('shouldn ignore object expressions keys transformation', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
});
@@ -0,0 +1,8 @@
const foo = {
baz: 1
};
const bar = {
...foo,
baz: 2,
bark: 3
};
@@ -0,0 +1,8 @@
const foo = {
baz: 1
};
const bar = {
baz: 2,
bark: 3,
...foo
};
@@ -0,0 +1,8 @@
const foo = {
baz: 1
};
const bar = {
baz: 2,
...foo,
bark: 3
};

0 comments on commit e8517bf

Please sign in to comment.