voluptasvelit
Version:
JavaScript obfuscator
200 lines (156 loc) • 8.4 kB
text/typescript
import { assert } from 'chai';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
import { readFileAsString } from '../../../../helpers/readFileAsString';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
describe('ClassDeclarationTransformer', () => {
describe('transformation of `classDeclaration` node names', () => {
describe('Variant #1: `classDeclaration` parent block scope is not a `ProgramNode`', () => {
const classNameIdentifierRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *\{/;
const classCallIdentifierRegExp: RegExp = /new *(_0x[a-f0-9]{4,6}) *\( *\);/;
let obfuscatedCode: string,
classNameIdentifier: string,
classCallIdentifier: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/input.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
).getObfuscatedCode();
classNameIdentifier = getRegExpMatch(obfuscatedCode, classNameIdentifierRegExp);
classCallIdentifier = getRegExpMatch(obfuscatedCode, classCallIdentifierRegExp);
});
it('should transform class name', () => {
assert.equal(classNameIdentifier, classCallIdentifier);
});
});
describe('Variant #2: `classDeclaration` parent block scope is a `ProgramNode`', () => {
describe('Variant #1: `renameGlobals` option is disabled', () => {
const classNameIdentifierRegExp: RegExp = /class *Foo *\{/;
const classCallIdentifierRegExp: RegExp = /new *Foo *\( *\);/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/parent-block-scope-is-program-node.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
).getObfuscatedCode();
});
it('match #1: shouldn\'t transform class name', () => {
assert.match(obfuscatedCode, classNameIdentifierRegExp);
});
it('match #2: shouldn\'t transform class name', () => {
assert.match(obfuscatedCode, classCallIdentifierRegExp);
});
});
describe('Variant #2: `renameGlobals` option is enabled', () => {
describe('Variant #1: Base', () => {
const classNameIdentifierRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *\{/;
const classCallIdentifierRegExp: RegExp = /new *(_0x[a-f0-9]{4,6}) *\( *\);/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/parent-block-scope-is-program-node.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});
it('match #1: should transform class name', () => {
assert.match(obfuscatedCode, classNameIdentifierRegExp);
});
it('match #2: should transform class name', () => {
assert.match(obfuscatedCode, classCallIdentifierRegExp);
});
});
describe('Variant #2: Two classes. Transformation of identifier inside class method', () => {
const identifierRegExp1: RegExp = /const (?:_0x[a-f0-9]{4,6}) *= *0x1;/;
const identifierRegExp2: RegExp = /const (?:_0x[a-f0-9]{4,6}) *= *0x2;/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/rename-globals-identifier-transformation.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});
it('match #1: should transform identifier name inside class method', () => {
assert.match(obfuscatedCode, identifierRegExp1);
});
it('match #2: should transform identifier name inside class method', () => {
assert.match(obfuscatedCode, identifierRegExp2);
});
});
});
});
describe('Variant #3: already renamed identifiers shouldn\'t be renamed twice', () => {
const classDeclarationRegExp: RegExp = /class *d *{/;
const variableDeclarationsRegExp: RegExp = /let *e, *f, *g, *h;/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/prevent-renaming-of-renamed-identifiers.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
}
).getObfuscatedCode();
});
it('Match #1: shouldn\'t rename twice class declaration name', () => {
assert.match(obfuscatedCode, classDeclarationRegExp);
});
it('Match #2: should correctly rename variable declarations', () => {
assert.match(obfuscatedCode, variableDeclarationsRegExp);
});
});
describe('Variant #5: named export', () => {
const namedExportRegExp: RegExp = /export class Foo *{}/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/named-export.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});
it('shouldn\'t transform identifiers in named export', () => {
assert.match(obfuscatedCode, namedExportRegExp);
});
});
describe('Variant #6: default export', () => {
const classDeclarationRegExp: RegExp = /class _0x[a-f0-9]{4,6} *{}/;
const defaultExportRegExp: RegExp = /export default _0x[a-f0-9]{4,6};/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/default-export.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});
it('Match #1: should transform identifiers in variable declaration', () => {
assert.match(obfuscatedCode, classDeclarationRegExp);
});
it('Match #2: should transform identifiers in default export', () => {
assert.match(obfuscatedCode, defaultExportRegExp);
});
});
});
});