* Fixed identifier names generations for mangled and dictionary identifier names generators

* Fixed combination of `identifierNamesGenerator: dictionary` and `debugProtection` options
* `seed` option now accepts `string` and `number` values
This commit is contained in:
sanex3339
2020-01-01 21:46:51 +03:00
parent f39d16370b
commit 945e885240
26 changed files with 304 additions and 22895 deletions
+6
View File
@@ -1,5 +1,11 @@
Change Log
v0.20.1
---
* Fixed identifier names generations for `mangled` and `dictionary` identifier names generators
* Fixed combination of `identifierNamesGenerator: dictionary` and `debugProtection` options
* `seed` option now accepts `string` and `number` values
v0.20.0
---
* **Breaking:** dropped support of Node 8 because of end of maintenance support
+2 -2
View File
@@ -343,7 +343,7 @@ Following options are available for the JS Obfuscator:
--reserved-names '<list>' (comma separated)
--reserved-strings '<list>' (comma separated)
--rotate-string-array <boolean>
--seed <number>
--seed <string|number>
--self-defending <boolean>
--source-map <boolean>
--source-map-base-url <string>
@@ -673,7 +673,7 @@ Shift the `stringArray` array by a fixed and random (generated at the code obfus
This option is recommended if your original source code isn't small, as the helper function can attract attention.
### `seed`
Type: `number` Default: `0`
Type: `string|number` Default: `0`
This option sets seed for random generator. This is useful for creating repeatable results.
+4 -4
View File
File diff suppressed because one or more lines are too long
+1 -11671
View File
File diff suppressed because one or more lines are too long
+1 -11080
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "0.20.0",
"version": "0.20.1",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
+1 -1
View File
@@ -127,7 +127,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
const timeStart: number = Date.now();
this.logger.info(LoggingMessage.Version, process.env.VERSION);
this.logger.info(LoggingMessage.ObfuscationStarted);
this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getSeed());
this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getInputSeed());
// parse AST tree
const astTree: ESTree.Program = this.parseCode(sourceCode);
+1 -1
View File
@@ -287,7 +287,7 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
BooleanSanitizer
)
.option(
'--seed <number>',
'--seed <string|number>',
'Sets seed for random generator. This is useful for creating repeatable results.',
parseFloat
)
@@ -28,7 +28,7 @@ export const generatorsModule: interfaces.ContainerModule = new ContainerModule(
.whenTargetNamed(IdentifierNamesGenerator.MangledIdentifierNamesGenerator);
// identifier name generator factory
function identifierNameGeneratorFactory () {
function identifierNameGeneratorFactory (): (context: interfaces.Context) => (options: IOptions) => IIdentifierNamesGenerator {
let cachedIdentifierNamesGenerator: IIdentifierNamesGenerator | null = null;
return (context: interfaces.Context): (options: IOptions) => IIdentifierNamesGenerator => (options: IOptions) => {
@@ -66,7 +66,7 @@ export const generatorsModule: interfaces.ContainerModule = new ContainerModule(
cachedIdentifierNamesGenerator = identifierNamesGenerator;
return identifierNamesGenerator;
}
};
}
bind<IIdentifierNamesGenerator>(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
.toFactory<IIdentifierNamesGenerator>(identifierNameGeneratorFactory());
@@ -101,7 +101,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
...NO_ADDITIONAL_NODES_PRESET,
identifierNamesGenerator: this.options.identifierNamesGenerator,
identifiersDictionary: this.options.identifiersDictionary,
seed: this.options.seed
seed: this.randomGenerator.getRawSeed()
}
).getObfuscatedCode();
}
@@ -108,7 +108,7 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
...NO_ADDITIONAL_NODES_PRESET,
identifierNamesGenerator: this.options.identifierNamesGenerator,
identifiersDictionary: this.options.identifiersDictionary,
seed: this.options.seed
seed: this.randomGenerator.getRawSeed()
}
).getObfuscatedCode();
}
+1 -1
View File
@@ -23,7 +23,7 @@ export interface IOptions {
readonly reservedNames: string[];
readonly reservedStrings: string[];
readonly rotateStringArray: boolean;
readonly seed: number;
readonly seed: string | number;
readonly selfDefending: boolean;
readonly sourceMap: boolean;
readonly sourceMapBaseUrl: string;
+7 -2
View File
@@ -26,7 +26,12 @@ export interface IRandomGenerator {
getRandomString (length: number, pool?: string): string;
/**
* @returns {number}
* @returns {string}
*/
getSeed (): number;
getInputSeed (): string;
/**
* @returns {string}
*/
getRawSeed (): string;
}
+2 -3
View File
@@ -176,10 +176,9 @@ export class Options implements IOptions {
public readonly rotateStringArray!: boolean;
/**
* @type {number}
* @type {string | number}
*/
@IsNumber()
public readonly seed!: number;
public readonly seed!: string | number;
/**
* @type {boolean}
+2
View File
@@ -10,6 +10,7 @@ import { DeadCodeInjectionRule } from './normalizer-rules/DeadCodeInjectionRule'
import { DeadCodeInjectionThresholdRule } from './normalizer-rules/DeadCodeInjectionThresholdRule';
import { DomainLockRule } from './normalizer-rules/DomainLockRule';
import { InputFileNameRule } from './normalizer-rules/InputFileNameRule';
import { SeedRule } from './normalizer-rules/SeedRule';
import { SelfDefendingRule } from './normalizer-rules/SelfDefendingRule';
import { SourceMapBaseUrlRule } from './normalizer-rules/SourceMapBaseUrlRule';
import { SourceMapFileNameRule } from './normalizer-rules/SourceMapFileNameRule';
@@ -29,6 +30,7 @@ export class OptionsNormalizer implements IOptionsNormalizer {
DeadCodeInjectionThresholdRule,
DomainLockRule,
InputFileNameRule,
SeedRule,
SelfDefendingRule,
SourceMapBaseUrlRule,
SourceMapFileNameRule,
+25
View File
@@ -0,0 +1,25 @@
import { TOptionsNormalizerRule } from '../../types/options/TOptionsNormalizerRule';
import { IOptions } from '../../interfaces/options/IOptions';
/**
* @param {IOptions} options
* @returns {IOptions}
*/
export const SeedRule: TOptionsNormalizerRule = (options: IOptions): IOptions => {
if (options.seed) {
return {
...options,
seed: options.seed
};
}
const getRandomInteger: (min: number, max: number) => number = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min + 1) + min);
};
return {
...options,
seed: getRandomInteger(0, 999_999_999)
};
};
@@ -50,10 +50,6 @@ export class StringArrayStorage extends ArrayStorage <string> {
public initialize (): void {
super.initialize();
if (!this.options.stringArray) {
return;
}
const baseStringArrayName: string = this.identifierNamesGenerator
.generate(StringArrayStorage.stringArrayNameLength);
const baseStringArrayCallsWrapperName: string = this.identifierNamesGenerator
@@ -6,7 +6,7 @@ export function DebugProtectionFunctionCallTemplate (): string {
(function () {
{singleNodeCallControllerFunctionName}(this, function () {
var regExp1 = new RegExp('function *\\\\( *\\\\)');
var regExp2 = new RegExp('\\\\+\\\\+ *\\(?:_0x(?:[a-f0-9]){4,6}|(?:\\\\b|\\\\d)[a-z0-9]{1,4}(?:\\\\b|\\\\d)\\)', 'i');
var regExp2 = new RegExp('\\\\+\\\\+ *\\(?:[a-zA-Z_$][0-9a-zA-Z_$]*\\)', 'i');
var result = {debugProtectionFunctionName}('init');
+22 -26
View File
@@ -29,12 +29,6 @@ export class RandomGenerator implements IRandomGenerator, IInitializable {
@initializable()
private randomGenerator!: Chance.Chance;
/**
* @type {number}
*/
@initializable()
private seed!: number;
/**
* @type {ISourceCode}
*/
@@ -54,24 +48,7 @@ export class RandomGenerator implements IRandomGenerator, IInitializable {
@postConstruct()
public initialize (): void {
const getRandomInteger: (min: number, max: number) => number = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min + 1) + min);
};
/**
* We need to add numbers from md5 hash of source code to input seed to prevent same String Array name
* for different bundles with same seed
*
* @returns {number}
*/
const getSeed: () => number = (): number => {
const md5Hash: string = md5(this.sourceCode.getSourceCode());
return this.seed + Number(md5Hash.replace(/\D/g, ''));
};
this.seed = this.options.seed !== 0 ? this.options.seed : getRandomInteger(0, 999_999_999);
this.randomGenerator = new Chance(getSeed());
this.randomGenerator = new Chance(this.getRawSeed());
}
/**
@@ -110,9 +87,28 @@ export class RandomGenerator implements IRandomGenerator, IInitializable {
}
/**
* @returns {string}
*/
public getInputSeed (): string {
return this.options.seed.toString();
}
/**
* We need to add numbers from md5 hash of source code to input seed to prevent same String Array name
* for different bundles with same seed
*
* @returns {number}
*/
public getSeed (): number {
return this.seed;
public getRawSeed (): string {
const inputSeed: string = this.getInputSeed();
const inputSeedParts: string[] = `${inputSeed}`.split('|');
if (inputSeedParts.length > 1) {
return inputSeed;
}
const sourceCodeMD5Hash: string = md5(this.sourceCode.getSourceCode());
return `${inputSeed}|${sourceCodeMD5Hash}`;
}
}
+31 -3
View File
@@ -14,10 +14,38 @@ import { IdentifierNamesGenerator } from '../../src/enums/generators/identifier-
`,
{
compact: false,
renameGlobals: true,
identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
selfDefending: false,
disableConsoleOutput: false,
debugProtection: false,
debugProtectionInterval: false,
splitStrings: true,
splitStringsChunkLength: 5,
splitStringsChunkLengthEnabled: true,
stringArray: true,
rotateStringArray: false
rotateStringArray: false,
rotateStringArrayEnabled: true,
stringArrayThreshold: 1,
stringArrayThresholdEnabled: true,
stringArrayEncoding: false,
stringArrayEncodingEnabled: true,
sourceMap: false,
sourceMapBaseUrl: "",
sourceMapFileName: "",
sourceMapSeparate: false,
domainLock: [],
reservedNames: [],
reservedStrings: [],
seed: 0,
controlFlowFlatteningThreshold: 1,
controlFlowFlattening: true,
deadCodeInjectionThreshold: 1,
deadCodeInjection: true,
unicodeEscapeSequence: false,
renameGlobals: true,
identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
identifiersDictionary: ["foo", "bar", "baz", "bark", "hawk", "fooz", "moscow", "chikago"],
identifiersPrefix: "",
transformObjectKeys: true
}
).getObfuscatedCode();
@@ -570,7 +570,7 @@ describe('JavaScriptObfuscator', () => {
});
describe('dictionary identifier names generator', () => {
const regExp: RegExp = /var *[ab] *= *0x1; *var *[ab] *= *0x2; *var *[AB] *= *0x3;/;
const regExp: RegExp = /var *[abc] *= *0x1; *var *[ABC] *= *0x2; *var *[ABC] *= *0x3;/;
let obfuscatedCode: string;
@@ -582,7 +582,7 @@ describe('JavaScriptObfuscator', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
identifiersDictionary: ['a', 'b']
identifiersDictionary: ['a', 'b', 'c']
}
).getObfuscatedCode();
});
@@ -667,7 +667,7 @@ describe('JavaScriptObfuscator', () => {
});
});
describe('Identifier names collision between base code and appended custom nodes', () => {
describe('Identifier names collision between base code and appended string array nodes', () => {
const samplesCount: number = 30;
let areCollisionsExists: boolean = false;
@@ -121,8 +121,8 @@ describe('ClassDeclarationTransformer', () => {
});
describe('Variant #3: already renamed identifiers shouldn\'t be renamed twice', () => {
const classDeclarationRegExp: RegExp = /class *b *{/;
const variableDeclarationsRegExp: RegExp = /let *c, *d, *e, *f;/;
const classDeclarationRegExp: RegExp = /class *d *{/;
const variableDeclarationsRegExp: RegExp = /let *e, *f, *g, *h;/;
let obfuscatedCode: string;
@@ -145,8 +145,8 @@ describe('FunctionDeclarationTransformer', () => {
describe('Variant #5: already renamed identifiers shouldn\'t be renamed twice', () => {
describe('Variant #1', () => {
const functionDeclarationRegExp: RegExp = /function *b\(\) *{/;
const variableDeclarationsRegExp: RegExp = /let *c, *d, *e, *f;/;
const functionDeclarationRegExp: RegExp = /function *d\(\) *{/;
const variableDeclarationsRegExp: RegExp = /let *e, *f, *g, *h;/;
let obfuscatedCode: string;
@@ -426,11 +426,11 @@ describe('VariableDeclarationTransformer', () => {
describe('Variant #13: already renamed identifiers shouldn\'t be renamed twice', () => {
describe('Variant #1', () => {
const variableDeclarationRegExp: RegExp = /var *b *= *0x1;/;
const functionDeclarationRegExp1: RegExp = /function *c *\(\) *{}/;
const functionDeclarationRegExp2: RegExp = /function *d *\(\) *{}/;
const functionDeclarationRegExp3: RegExp = /function *e *\(\) *{}/;
const functionDeclarationRegExp4: RegExp = /function *f *\(\) *{}/;
const variableDeclarationRegExp: RegExp = /var *d *= *0x1;/;
const functionDeclarationRegExp1: RegExp = /function *e *\(\) *{}/;
const functionDeclarationRegExp2: RegExp = /function *f *\(\) *{}/;
const functionDeclarationRegExp3: RegExp = /function *g *\(\) *{}/;
const functionDeclarationRegExp4: RegExp = /function *h *\(\) *{}/;
let obfuscatedCode: string;
@@ -468,10 +468,10 @@ describe('VariableDeclarationTransformer', () => {
});
describe('Variant #2', () => {
const variableDeclarationRegExp1: RegExp = /var *b *= *0x1;/;
const variableDeclarationRegExp2: RegExp = /var *c;/;
const functionDeclarationRegExp: RegExp = /function *d *\(\) *{/;
const variableDeclarationRegExp3: RegExp = /var *d *= *function *\(\) *{}/;
const variableDeclarationRegExp1: RegExp = /var *d *= *0x1;/;
const variableDeclarationRegExp2: RegExp = /var *e;/;
const functionDeclarationRegExp: RegExp = /function *f *\(\) *{/;
const variableDeclarationRegExp3: RegExp = /var *f *= *function *\(\) *{}/;
let obfuscatedCode: string;
@@ -33,6 +33,13 @@ function getNormalizedOptions (optionsPreset: TInputOptions): TInputOptions {
return <TInputOptions>optionsNormalizer.normalize(options);
}
function getDefaultOptions(): TInputOptions {
return {
...DEFAULT_PRESET,
seed: 1 // set `seed` to the fixed value, to prevent a new seed for the each case
};
}
describe('OptionsNormalizer', () => {
describe('normalize', () => {
let optionsPreset: TInputOptions,
@@ -41,13 +48,13 @@ describe('OptionsNormalizer', () => {
describe('controlFlowFlatteningThresholdRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
controlFlowFlattening: false,
controlFlowFlatteningThreshold: 0
};
@@ -61,7 +68,7 @@ describe('OptionsNormalizer', () => {
describe('deadCodeInjectionRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
stringArray: false,
@@ -69,7 +76,7 @@ describe('OptionsNormalizer', () => {
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
stringArray: true,
@@ -86,7 +93,7 @@ describe('OptionsNormalizer', () => {
describe('`stringArrayThreshold` option is empty', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
stringArray: false,
@@ -94,7 +101,7 @@ describe('OptionsNormalizer', () => {
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
stringArray: true,
@@ -110,7 +117,7 @@ describe('OptionsNormalizer', () => {
describe('`stringArrayThreshold` option is not empty', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
stringArray: false,
@@ -118,7 +125,7 @@ describe('OptionsNormalizer', () => {
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
stringArray: true,
@@ -135,13 +142,13 @@ describe('OptionsNormalizer', () => {
describe('deadCodeInjectionThresholdRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: true,
deadCodeInjectionThreshold: 0
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
deadCodeInjection: false,
deadCodeInjectionThreshold: 0
};
@@ -155,7 +162,7 @@ describe('OptionsNormalizer', () => {
describe('domainLockRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
domainLock: [
'//localhost:9000',
'https://google.ru/abc?cde=fgh'
@@ -163,7 +170,7 @@ describe('OptionsNormalizer', () => {
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
domainLock: [
'localhost',
'google.ru'
@@ -180,12 +187,12 @@ describe('OptionsNormalizer', () => {
describe('Variant #1: extension isn\'t set', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: 'foo'
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: 'foo.js'
};
});
@@ -198,12 +205,12 @@ describe('OptionsNormalizer', () => {
describe('Variant #2: extension is set', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: 'foo.js'
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: 'foo.js'
};
});
@@ -216,12 +223,12 @@ describe('OptionsNormalizer', () => {
describe('Variant #3: extension in set with `.map` postfix', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: 'foo.map.js'
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: 'foo.map.js'
};
});
@@ -234,12 +241,12 @@ describe('OptionsNormalizer', () => {
describe('Variant #4: no file name', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: ''
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
inputFileName: ''
};
});
@@ -250,16 +257,72 @@ describe('OptionsNormalizer', () => {
});
});
describe('seedRule', () => {
describe('Variant #1: seed value is string', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...getDefaultOptions(),
seed: 'abc'
});
expectedOptionsPreset = {
...getDefaultOptions(),
seed: 'abc'
};
});
it('should not normalize options preset', () => {
assert.deepEqual(optionsPreset, expectedOptionsPreset);
});
});
describe('Variant #2: seed value is number', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...getDefaultOptions(),
seed: 123
});
expectedOptionsPreset = {
...getDefaultOptions(),
seed: 123
};
});
it('should normalize options preset', () => {
assert.deepEqual(optionsPreset, expectedOptionsPreset);
});
});
describe('Variant #3: seed value is `0``', () => {
let seedValue: number;
before(() => {
optionsPreset = getNormalizedOptions({
...getDefaultOptions(),
seed: 0
});
seedValue = Number(optionsPreset.seed);
});
it('should normalize seed value', () => {
assert.isAtLeast(seedValue, 0);
assert.isBelow(seedValue, 999_999_999);
});
});
});
describe('selfDefendingRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
selfDefending: true,
compact: false
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
selfDefending: true,
compact: true
};
@@ -274,12 +337,12 @@ describe('OptionsNormalizer', () => {
describe('Variant #1: only source map base url', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
sourceMapBaseUrl: 'http://localhost:9000',
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
sourceMapBaseUrl: ''
};
});
@@ -292,13 +355,13 @@ describe('OptionsNormalizer', () => {
describe('Variant #2: source map base url with source map file name', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
sourceMapBaseUrl: 'http://localhost:9000',
sourceMapFileName: '/outputSourceMapName.map'
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
sourceMapBaseUrl: 'http://localhost:9000/',
sourceMapFileName: 'outputSourceMapName.js.map'
};
@@ -313,13 +376,13 @@ describe('OptionsNormalizer', () => {
describe('sourceMapFileNameRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
sourceMapBaseUrl: 'http://localhost:9000',
sourceMapFileName: '//outputSourceMapName'
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
sourceMapBaseUrl: 'http://localhost:9000/',
sourceMapFileName: 'outputSourceMapName.js.map'
};
@@ -334,13 +397,13 @@ describe('OptionsNormalizer', () => {
describe('`splitStringsChunkLengthRule` value is float number', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
splitStrings: true,
splitStringsChunkLength: 5.6
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
splitStrings: true,
splitStringsChunkLength: 5
};
@@ -355,7 +418,7 @@ describe('OptionsNormalizer', () => {
describe('stringArrayRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
stringArray: false,
stringArrayEncoding: StringArrayEncoding.Rc4,
stringArrayThreshold: 0.5,
@@ -363,7 +426,7 @@ describe('OptionsNormalizer', () => {
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
stringArray: false,
stringArrayEncoding: false,
stringArrayThreshold: 0,
@@ -379,12 +442,12 @@ describe('OptionsNormalizer', () => {
describe('stringArrayEncodingRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
stringArrayEncoding: true
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
stringArrayEncoding: StringArrayEncoding.Base64
};
});
@@ -397,14 +460,14 @@ describe('OptionsNormalizer', () => {
describe('stringArrayThresholdRule', () => {
before(() => {
optionsPreset = getNormalizedOptions({
...DEFAULT_PRESET,
...getDefaultOptions(),
rotateStringArray: true,
stringArray: true,
stringArrayThreshold: 0
});
expectedOptionsPreset = {
...DEFAULT_PRESET,
...getDefaultOptions(),
rotateStringArray: false,
stringArray: false,
stringArrayThreshold: 0
@@ -5,6 +5,7 @@ import { readFileAsString } from '../../../helpers/readFileAsString';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../src/options/presets/NoCustomNodes';
import { IdentifierNamesGenerator } from '../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
import { ObfuscationTarget } from '../../../../src/enums/ObfuscationTarget';
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
@@ -29,41 +30,7 @@ function spawnThread(inputCallback: Function, threadCallback: Function, timeoutC
}
describe('DebugProtectionFunctionCallTemplate', () => {
describe('Variant #1: correctly obfuscated code`', () => {
const expectedEvaluationResult: number = 1;
let obfuscatedCode: string,
evaluationResult: number = 0;
beforeEach((done) => {
const code: string = readFileAsString(__dirname + '/fixtures/input.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
debugProtection: true
}
).getObfuscatedCode();
spawnThread(
() => obfuscatedCode,
(response: number) => {
evaluationResult = response;
done();
},
() => {
done();
}
);
});
it('should correctly evaluate code with enabled debug protection', () => {
assert.equal(evaluationResult, expectedEvaluationResult);
});
});
describe('Variant #2: correctly obfuscated code with enabled `mangle` option', () => {
describe('Variant #1: correctly obfuscate code with `HexadecimalIdentifierNamesGenerator``', () => {
const expectedEvaluationResult: number = 1;
let obfuscatedCode: string,
@@ -77,7 +44,7 @@ describe('DebugProtectionFunctionCallTemplate', () => {
{
...NO_ADDITIONAL_NODES_PRESET,
debugProtection: true,
mangle: true
identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
}
).getObfuscatedCode();
@@ -98,7 +65,78 @@ describe('DebugProtectionFunctionCallTemplate', () => {
});
});
describe('Variant #3: correctly obfuscated code with target `extension`', () => {
describe('Variant #2: correctly obfuscate code with `MangledIdentifierNamesGenerator` option', () => {
const expectedEvaluationResult: number = 1;
let obfuscatedCode: string,
evaluationResult: number = 0;
beforeEach((done) => {
const code: string = readFileAsString(__dirname + '/fixtures/input.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
debugProtection: true,
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
}
).getObfuscatedCode();
spawnThread(
() => obfuscatedCode,
(response: number) => {
evaluationResult = response;
done();
},
() => {
done();
}
);
});
it('should correctly evaluate code with enabled debug protection', () => {
assert.equal(evaluationResult, expectedEvaluationResult);
});
});
describe('Variant #3: correctly obfuscate code with `DictionaryIdentifierNamesGenerator` option', () => {
const expectedEvaluationResult: number = 1;
let obfuscatedCode: string,
evaluationResult: number = 0;
beforeEach((done) => {
const code: string = readFileAsString(__dirname + '/fixtures/input.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
debugProtection: true,
identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
identifiersDictionary: ['foo', 'bar', 'baz', 'bark', 'hawk', 'eagle']
}
).getObfuscatedCode();
spawnThread(
() => obfuscatedCode,
(response: number) => {
evaluationResult = response;
done();
},
() => {
done();
}
);
});
it('should correctly evaluate code with enabled debug protection', () => {
assert.equal(evaluationResult, expectedEvaluationResult);
});
});
describe('Variant #4: correctly obfuscated code with target `BrowserNoEval`', () => {
const expectedEvaluationResult: number = 1;
let obfuscatedCode: string,
@@ -133,7 +171,7 @@ describe('DebugProtectionFunctionCallTemplate', () => {
});
});
describe('Variant #4: obfuscated code with removed debug protection code', () => {
describe('Variant #5: obfuscated code with removed debug protection code', () => {
const expectedEvaluationResult: number = 0;
let obfuscatedCode: string,
@@ -168,7 +206,7 @@ describe('DebugProtectionFunctionCallTemplate', () => {
});
});
describe('Variant #5: single call of debug protection code', () => {
describe('Variant #6: single call of debug protection code', () => {
const expectedEvaluationResult: number = 1;
let obfuscatedCode: string,