mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Fixed stringArrayWrappersCount behaviour with arrow function scope without statements
This commit is contained in:
@@ -6,6 +6,7 @@ npm-debug.log
|
||||
*.js.map
|
||||
/coverage
|
||||
/node_modules
|
||||
/test/fixtures/compile-performance-obfuscated.js
|
||||
/test-tmp
|
||||
/tmp
|
||||
/test/benchmark/**/**
|
||||
|
||||
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
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -69,7 +69,7 @@
|
||||
"coveralls": "3.1.0",
|
||||
"eslint": "7.8.1",
|
||||
"eslint-plugin-import": "2.22.0",
|
||||
"eslint-plugin-jsdoc": "30.4.0",
|
||||
"eslint-plugin-jsdoc": "30.4.1",
|
||||
"eslint-plugin-no-null": "1.0.2",
|
||||
"eslint-plugin-prefer-arrow": "1.2.2",
|
||||
"eslint-plugin-unicorn": "21.0.0",
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as ESTree from 'estree';
|
||||
|
||||
import { TInitialData } from '../../types/TInitialData';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
import { TNodeWithLexicalScopeAndStatements } from '../../types/node/TNodeWithLexicalScopeAndStatements';
|
||||
import { TStatement } from '../../types/node/TStatement';
|
||||
import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
|
||||
import { TStringArrayScopeCallsWrapperDataByEncoding } from '../../types/node-transformers/string-array-transformers/TStringArrayScopeCallsWrapperDataByEncoding';
|
||||
@@ -122,6 +123,31 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
|
||||
this.stringArrayTransformerCustomNodeFactory = stringArrayTransformerCustomNodeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private static isValidLexicalScopeNode (node: ESTree.Node): node is TNodeWithLexicalScopeAndStatements {
|
||||
if (!NodeGuards.isNodeWithLexicalScope(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const lexicalScopeBodyNode: ESTree.Program | ESTree.BlockStatement | ESTree.Expression =
|
||||
NodeGuards.isProgramNode(node)
|
||||
? node
|
||||
: node.body;
|
||||
|
||||
// invalid lexical scope node
|
||||
if (
|
||||
!lexicalScopeBodyNode.parentNode
|
||||
|| !NodeGuards.isNodeWithLexicalScopeStatements(lexicalScopeBodyNode, lexicalScopeBodyNode.parentNode)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeTransformationStage} nodeTransformationStage
|
||||
* @returns {IVisitor | null}
|
||||
@@ -135,7 +161,7 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
|
||||
this.prepareNode(node);
|
||||
}
|
||||
|
||||
if (NodeGuards.isNodeWithLexicalScope(node)) {
|
||||
if (StringArrayTransformer.isValidLexicalScopeNode(node)) {
|
||||
this.onLexicalScopeNodeEnter(node);
|
||||
}
|
||||
|
||||
@@ -144,7 +170,7 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
},
|
||||
leave: (node: ESTree.Node): ESTree.Node | undefined => {
|
||||
if (NodeGuards.isNodeWithLexicalScope(node)) {
|
||||
if (StringArrayTransformer.isValidLexicalScopeNode(node)) {
|
||||
this.onLexicalScopeNodeLeave();
|
||||
|
||||
return this.transformLexicalScopeNode(node);
|
||||
@@ -297,27 +323,19 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @returns {TNodeWithLexicalScope}
|
||||
* @param {TNodeWithLexicalScopeAndStatements} lexicalScopeNode
|
||||
* @returns {TNodeWithLexicalScopeAndStatements}
|
||||
*/
|
||||
private transformLexicalScopeNode (lexicalScopeNode: TNodeWithLexicalScope): TNodeWithLexicalScope {
|
||||
private transformLexicalScopeNode (lexicalScopeNode: TNodeWithLexicalScopeAndStatements): TNodeWithLexicalScopeAndStatements {
|
||||
if (!this.options.stringArrayWrappersCount) {
|
||||
return lexicalScopeNode;
|
||||
}
|
||||
|
||||
const lexicalScopeBodyNode: ESTree.Program | ESTree.BlockStatement | ESTree.Expression =
|
||||
const lexicalScopeBodyNode: ESTree.Program | ESTree.BlockStatement =
|
||||
NodeGuards.isProgramNode(lexicalScopeNode)
|
||||
? lexicalScopeNode
|
||||
: lexicalScopeNode.body;
|
||||
|
||||
// invalid lexical scope node
|
||||
if (
|
||||
!lexicalScopeBodyNode.parentNode
|
||||
|| !NodeGuards.isNodeWithLexicalScopeStatements(lexicalScopeBodyNode, lexicalScopeBodyNode.parentNode)
|
||||
) {
|
||||
return lexicalScopeNode;
|
||||
}
|
||||
|
||||
const stringArrayScopeCallsWrapperDataByEncoding: TStringArrayScopeCallsWrapperDataByEncoding | null =
|
||||
this.stringArrayScopeCallsWrapperDataByEncodingMap.get(lexicalScopeNode) ?? null;
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithLexicalScope } from './TNodeWithLexicalScope';
|
||||
|
||||
export type TNodeWithLexicalScopeAndStatements = TNodeWithLexicalScope
|
||||
& {
|
||||
body: ESTree.Program | ESTree.BlockStatement;
|
||||
};
|
||||
+4
-29
@@ -8,42 +8,17 @@ import { IdentifierNamesGenerator } from '../../src/enums/generators/identifier-
|
||||
|
||||
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
||||
`
|
||||
const foo = 'aaa';
|
||||
|
||||
function test (a, b) {
|
||||
const bar = 'bbb';
|
||||
|
||||
function test1 (a, b) {
|
||||
const baz = 'ccc';
|
||||
|
||||
function test2 (a, b) {
|
||||
const bark = 'ddd';
|
||||
|
||||
return bark;
|
||||
}
|
||||
|
||||
return baz + test2();
|
||||
}
|
||||
|
||||
return bar + test1();
|
||||
}
|
||||
|
||||
function test3 (a, b) {
|
||||
const hawk = 'eee';
|
||||
|
||||
return hawk;
|
||||
}
|
||||
|
||||
foo + test() + test3();
|
||||
[].map(v => 'vvv');
|
||||
`,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
compact: false,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
||||
renameGlobals: true,
|
||||
stringArray: true,
|
||||
transformObjectKeys: true,
|
||||
stringArrayThreshold: 1,
|
||||
stringArrayWrappersChainedCalls: true,
|
||||
stringArrayWrappersChainedCalls: false,
|
||||
stringArrayWrappersCount: 1
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
+63
-3
@@ -198,7 +198,67 @@ describe('StringArrayTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #3: prevailing kind of variables', () => {
|
||||
describe('Variant #3: prohibited scopes', () => {
|
||||
describe('Variant #1: if statement scope', () => {
|
||||
const stringArrayCallRegExp: RegExp = new RegExp(
|
||||
'var c *= *b;' +
|
||||
'if *\\(!!\\[]\\) *{' +
|
||||
'var foo *= *c\\(\'0x0\'\\);' +
|
||||
'}'
|
||||
);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-prohibited-scope-1.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
||||
stringArray: true,
|
||||
stringArrayThreshold: 1,
|
||||
stringArrayWrappersCount: 1
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should not add scope calls wrappers to a prohibited scope', () => {
|
||||
assert.match(obfuscatedCode, stringArrayCallRegExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #2: arrow function scope without statements', () => {
|
||||
const stringArrayCallRegExp: RegExp = new RegExp(
|
||||
'var c *= *b;' +
|
||||
'\\[]\\[c\\(\'0x0\'\\)]\\(\\(\\) *=> *c\\(\'0x1\'\\)\\);'
|
||||
);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-prohibited-scope-2.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
||||
stringArray: true,
|
||||
stringArrayThreshold: 1,
|
||||
stringArrayWrappersCount: 1
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should not add scope calls wrappers to a prohibited scope', () => {
|
||||
assert.match(obfuscatedCode, stringArrayCallRegExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4: prevailing kind of variables', () => {
|
||||
const stringArrayCallRegExp: RegExp = new RegExp(
|
||||
'return _0x([a-f0-9]){4,6};' +
|
||||
'};' +
|
||||
@@ -230,7 +290,7 @@ describe('StringArrayTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4: correct evaluation of the scope calls wrappers', () => {
|
||||
describe('Variant #5: correct evaluation of the scope calls wrappers', () => {
|
||||
const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
||||
let evaluationResult: string;
|
||||
|
||||
@@ -255,7 +315,7 @@ describe('StringArrayTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #5: `stringArrayWrappersChainedCalls` option is enabled', () => {
|
||||
describe('Variant #6: `stringArrayWrappersChainedCalls` option is enabled', () => {
|
||||
describe('Variant #1: correct chained calls', () => {
|
||||
describe('Variant #1: `Mangled` identifier names generator', () => {
|
||||
const stringArrayCallRegExp: RegExp = new RegExp(
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
if (true) {
|
||||
var foo = 'foo';
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
[].map(() => 'test');
|
||||
@@ -39,6 +39,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
|
||||
StringArrayEncoding.Base64,
|
||||
StringArrayEncoding.Rc4
|
||||
],
|
||||
stringArrayWrappersChainedCalls: true,
|
||||
stringArrayWrappersCount: 5,
|
||||
stringArrayThreshold: 1,
|
||||
transformObjectKeys: true,
|
||||
@@ -71,9 +72,6 @@ describe('JavaScriptObfuscator runtime eval', function () {
|
||||
{
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.MangledShuffledIdentifierNamesGenerator,
|
||||
renameGlobals: true
|
||||
},
|
||||
{
|
||||
stringArrayWrappersChainedCalls: true
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -2035,10 +2035,10 @@ eslint-plugin-import@2.22.0:
|
||||
resolve "^1.17.0"
|
||||
tsconfig-paths "^3.9.0"
|
||||
|
||||
eslint-plugin-jsdoc@30.4.0:
|
||||
version "30.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.4.0.tgz#3c84f59b6a04eaef2b636f75eeee905d16b7f2f9"
|
||||
integrity sha512-eb22QADWcISPQJwFJ+rUAl1NXdyOq3qy0Cp0+MZzpwlqFgJ+eJ7Fd/jYTfwDuN8QyFWumuyzSpwQBnF4PfM9Wg==
|
||||
eslint-plugin-jsdoc@30.4.1:
|
||||
version "30.4.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.4.1.tgz#316b7c1963c7e51d244aeabca0878f3f95749b40"
|
||||
integrity sha512-dVdqenn9uHoXFEUIDnVdaHsel1ZZZMoelYZ1T46XSZvDkdsOl7NpssG0LxqzZ0rG3gpCTHBQdqpL6GlC3TgBAA==
|
||||
dependencies:
|
||||
comment-parser "^0.7.6"
|
||||
debug "^4.1.1"
|
||||
|
||||
Reference in New Issue
Block a user